函数不在onclick事件中调用

时间:2010-11-22 05:28:22

标签: javascript jquery function scope onclick

我想在每个youtube链接的末尾添加一些HTML,以便在litebox中打开播放器。到目前为止,这是我的代码:

$(document).ready(function() {
  var valid_url = new RegExp('youtube\.com\/.*v=([a-zA-Z0-9_-]+)');
  var image_data = 'base64 encoded image';

  init();

  function init() {
    $('a').each(function() {
      if (valid_url.test($(this).attr('href'))) {
        $(this).after( ' <img src="' + image_data + '" onclick="open_litebox(\'hi\');" />' );
      }
    });
  }

  function open_litebox(param) {
    alert(param);
  }
});

它可以在youtube链接之后注入一些HTML,就像这样:

<img src="base 64 data" onclick="open_litebox('hi')">

但是当我点击这个时,open_litebox()函数不会被调用。查看错误控制台,我可以看到显示open_litebox is not defined的错误,但我已经定义了它。

我对这里出了什么问题一无所知,有人可以帮我一把吗?

感谢。

6 个答案:

答案 0 :(得分:47)

当您第一次开始使用jQuery时,这是一个常见问题。这里的问题是你已经在jQuery范围内定义了这个函数,这意味着它只是像普通函数一样调用它是不可访问的。解决问题的方法是将函数定义移到您编写的匿名就绪函数之外,如下所示:

$(document).ready(function() {

    // do your stuff here

});

// define your functions here 
function my_func() {

}

哦,我建议你为你定义的变量做同样的事情。将它们移到您准备好的功能之外,因为您将遇到与功能相同的问题。

答案 1 :(得分:10)

您的open_litebox函数属于另一个函数的范围,因此它不是全局可见的。而不是你在做什么,尝试使用.click()

这些方面的东西:

$(this).after( ' <img src="' + image_data + '" id='abc' />' );
$('#abc').click(open_litebox);

您必须使用这种方式为每个链接生成单独的ID,因此另一种方法是使每个<img>标记都具有已知的class属性,然后使用{{1 (如果该类为$('.abc'))而不是abc,并且只需一步完成(即作为$('#abc')之后的单独调用)。

答案 2 :(得分:10)

其他答案是正确的,因为将my_func声明移到$(document).ready()之外会解决您的问题,但我想澄清一下推理,因为它与jQuery无关

$(document).ready()是一个事件处理程序,您将匿名函数作为回调传递给该回调函数,该回调函数应在浏览器通知您文档已准备就绪时运行。

因为您已在回调函数中定义了my_func,所以它在全局范围内不可见,因此无法从页面的onclick元素的img属性中调用。

在JavaScript中,范围在功能级别。不在函数内的所有东西都会聚集到全局范围内。

答案 3 :(得分:2)

原因是open_litebox()document.ready函数内声明,因此无法从全局范围访问。

您可以将函数移到document.ready之外,或者修改代码以使用jQuery(直接引用函数)附加onclick处理程序:

var link = $(' <img src="' + image_data + '" />' ).click(function () {
   open_litebox('hi');
});
$(this).after(link);

答案 4 :(得分:0)

有一种更简洁,更简洁的方式来分配点击动作。

function init() {
    $('a').each(function() {
        if(valid_url.test($(this).attr('href'))){
            $(this).click( function() { open_litebox('hi'); });
        }
    });
}

这解决了其他答案中描述的范围问题。如果需要使用参数调用open_litebox(),请将其包含在我所做的匿名函数中,否则将调用该函数,然后将返回值传递给click操作。否则,没有要传递的参数,分配就更简单了:

$(this).click( open_litebox );

答案 5 :(得分:0)

我登陆此页面是因为我遇到了类似的问题,并且在stackoverflow上没有一个帖子实际上解决了这个问题

花费了将近半小时尝试解决此问题后,才能通过html onclick触发您的函数,从而解决了该问题的最佳解决方案,方法是在第一行外部定义一个变量,然后使用该变量以将函数存储在该变量中。

var myAlert;
$(document).ready(function(){
    myAlert = function(msg){
        alert(msg);
    }
}

实际询问的问题的固定版本如下:

var open_litebox;
$(document).ready(function() {
  var valid_url = new RegExp('youtube\.com\/.*v=([a-zA-Z0-9_-]+)');
  var image_data = 'base64 encoded image';

  init();

  function init() {
    $('a').each(function() {
      if (valid_url.test($(this).attr('href'))) {
        $(this).after( ' <img src="' + image_data + '" onclick="open_litebox(\'hi\');" />' );
      }
    });
  }

  open_litebox = function(param) {
    alert(param);
  }
});

现在,当您使用html onclick调用它时,它将起作用

<img src="base 64 data" onclick="open_litebox('hi')">