Javascript 函数不在 onclick 事件中调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4242541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:33:02  来源:igfitidea点击:

Function not calling within an onclick event

javascriptjqueryfunctionscopeonclick

提问by Wen

I want to add some HTML to the end of every youtube link to open up the player in a litebox. This is my code so far:

我想在每个 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);
  }
});

It works to the point where it injects some HTML after the youtube link, like so:

它可以在 youtube 链接后注入一些 HTML,如下所示:

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

But when I click this the open_litebox()function doesn't get called. Looking in the error console I can see an error that says open_litebox is not defined, but I have defined it.

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

I'm pretty clueless as to what's going wrong here, could someone lend me a hand?

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

Thanks.

谢谢。

回答by Simon H

This is a common problem when you first start working with jQuery. The problem here is that you have defined the function within the jQuery scope, which means that it is not accessible by just calling it like a normal function. A solution to your problem is to move your function definition outside the anonymous ready function that you written, like so:

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

$(document).ready(function() {

    // do your stuff here

});

// define your functions here 
function my_func() {

}

Oh and I would suggest doing the same for your variables that you have defined. Move them outside your ready function as well, because you will have the same problems as you did with your functions.

哦,我建议对您定义的变量做同样的事情。也将它们移到您的就绪函数之外,因为您将遇到与您的函数相同的问题。

回答by Rob Sobers

The other answers are correct in that moving your my_funcdeclaration outside of $(document).ready()will solve your problem, but I'd like to clarify the reasoning, because it has nothing to do with jQuery in particular.

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

$(document).ready()is an event handler to which you're passing an anonymous function as a callback that should run when the browser notifies you that the document is ready.

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

Because you've defined my_funcwithin the callback function, it's not visible from the global scope and thus cannot be called from the onclickproperty of your page's imgelement.

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

In JavaScript, scope is at the function level. Everything that isn't within a function gets clumped into the global scope.

在 JavaScript 中,作用域位于函数级别。不在函数内的所有东西都会聚集到全局作用域中。

回答by icyrock.com

Your open_liteboxfunction is in the scope of another function, so it is not globally visible. Instead of what you are doing, try using .click():

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

Something along these lines:

沿着这些路线的东西:

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

You would have to generate separate IDs for each of the links using this way, so another way is to make each of <img>tags have a known classattribute and then select it using $('.abc')(if the class is abc) instead of $('#abc')and do it in one step (i.e. as a separate call after your $('a').each).

您必须使用这种方式为每个链接生成单独的 ID,因此另一种方法是使每个<img>标签都有一个已知class属性,然后使用$('.abc')(如果类是abc)而不是选择它,而不是$('#abc')一步完成(即作为您的$('a').each)之后的单独调用。

回答by David Tang

The reason is that open_litebox()is declared inside the document.readyfunction, and therefore not accessible from a global scope.

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

You can move the function outside of document.ready, or, modify the code to attach the onclick handler using jQuery (which references the function directly):

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

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

回答by Surreal Dreams

There's a much neater and more jQuery way to assign the click action.

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

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

This solves the scope problem as described in the other answers. If you need to call open_litebox() with parameters, wrap it inside an anonymous function like I did, or else the function will be called and then the return value is passed to the click action. Otherwise, with no parameters to pass, the assignment is simpler:

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

$(this).click( open_litebox );

回答by Taha Khan

I landed on this page because I faced similar issue and there is not a single post on stackoverflow that actually fixes this issue.

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

After spending almost half an hour trying to fix this The best solution to this problemto have your function available to be fired from html onclick is by defining a variable at the first line outside and then use that variable to store the function inside that variable.

在花了将近半个小时试图解决这个问题之后,让您的函数可以从 html onclick 触发的最佳解决方案是在外部的第一行定义一个变量,然后使用该变量将函数存储在该变量中。

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

Fixed version of the actual asked question is below:

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

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);
  }
});

Now when you call it using html onclick it will work

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

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