9

我只是不明白。我搜索和搜索,但为此我无法弄清楚什么是“正确的”。

有三个例子。

1) Fiddle 1.0 这里我们有htmlwithonlick="function"和那里的javascript功能也很好用

 <span class="classic one"   onclick="someFunction(this,'one')">CLICK HERE</span>

 <script type="text/javascript">
    function someFunction(obj,nr) {
        var string = $(obj).attr('class');
        $('.result').text( string );
    }
</script>

2) Fiddle 2.0 然后,当我将函数移动到脚本部分(将其移动到 .js 文件)时,我收到一个错误“ReferenceError: someFunction is not defined”

这是问题的开始

3) Fiddle 3 所以现在我在文档准备调用中有一个函数 .on(click 总是工作正常。这个函数正在调用另一个函数,它在 docuemnt.ready() 之外并且工作正常。

所以这个问题。我什么时候必须定义函数在哪里以及为什么它总是有效的?

谢谢!

示例 3) 中的所有代码如下所示:

<div class="result">result</div>

    <span class="classic one"   onclick="someFunction(this,'one')">CLICK HERE</span>
    <span class="classic two"   onclick="someFunction(this,'two')">CLICK HERE</span>
    <span class="classic three" onclick="someFunction(this,'three')">CLICK HERE</span>
    <span class="classic four"  onclick="someFunction(this,'four')">CLICK HERE</span>

<div class="ready">ready</div>


<span class="callOtherFunction">Call other function</span>


<script type="text/javascript">
    $(document).ready(function(){
        $('.ready').text( 'dom is ready' );

        function someFunction(obj,nr) {
                var string = $(obj).attr('class');
                $('.result').text( string );
            }

         $( "span.callOtherFunction" ).on({
            click: function() {
                $(this).css("color","red");
                $(this).addClass("xyz");
                otherFunctionCallingFunction($(this));
            }
        });

    });

    function otherFunctionCallingFunction($me) {
        $('.callOtherFunction').append( ' --> ' + $me.attr('class') );
    }
</script>
4

2 回答 2

16

您所看到的很多内容是因为 jsFiddle非常令人惊讶的默认设置,即将脚本窗格中的代码包装在onload处理程序中。onclick因此,您的代码被包装在一个函数中,不再处于全局范围内(如果您使用-style 属性,这是函数需要所在的位置)。您可以使用左侧的下拉框(第二个,在库和脚本列表下)更改此设置。将其更改为“无包装”以具有未包装的代码。

您不是(到目前为止!)第一个被这种令人惊讶的默认设置所困扰的人。


回答你的主要问题:

什么时候有一个函数在 $(document).ready()

如果您控制script加载脚本的标签的位置,则基本上不必使用ready; 相反,只需确保您的script标签位于 HTML 的末尾,就在</body>.

当然,您可以使用ready。这样做的原因是确保在您的代码运行之前已经创建了所有 DOM 元素。但如果你把你的script标签放在最后,那已经是真的了。您仍然可以在ready处理程序之外定义您的函数(如果您希望它们是全局的),但如果您正在使用ready,您将从处理程序调用它们ready以便元素存在。


FWIW,我会避免使用onclick-style 属性来连接事件处理程序,主要是因为它们需要您创建全局函数。当我可以避免时,我更愿意避免创建任何全局符号。

我推荐的一般形式:

<!-- ...your page markup here... -->
<script src="any_libraries_you_need_if_you_are_not_combining.js"></script>
<script src="your_script.js"></script>
</body>
</html>

您的脚本如下所示:

(function($) { // A scoping function that wraps everything
    // Hook up event handlers here. You can use `$` for jQuery, even if
    // you've used noConflict, because we have a private `$` symbol (see
    // the `$` argument above)

    // The body of your code goes here

})(jQuery); // <== Note how we're passing the jQuery reference in
            // and immediately executing the scoping function

这是一个完整的示例:Live Copy

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Script Placement Example</title>
</head>
<body>
  <input type="button" class="hello-button" value="Click me">
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
  <script>
    // This would be in a file, rather than inline
    (function($) {
      // Hook up handlers
      $(".hello-button").click(sayHello);

      // Body of the code
      function sayHello() {
        $("<p>Hello!</p>").appendTo(document.body);
      }
    })(jQuery);
  </script>
</body>
</html>
于 2013-09-25T08:19:19.867 回答
3

在 JavaScript 中,作用域是基于每个函数处理的。函数范围内的任何东西都可以访问该函数范围内的其他事物以及更广泛范围内的事物。

在函数内部定义变量var会将该变量的范围限制为函数。

在另一个函数中定义一个函数声明的函数会将定义函数的范围限制为容器函数。

当你使用 时ready,你将一个函数传递给它。当然,该函数中定义的任何内容都局限于该函数。由于它的范围仅限于该功能,因此它不是全局的。您的 onclick 属性未在该函数的范围内定义,它只能访问全局变量。这就是您收到参考错误的原因。

避免全局变量。它们使事情难以维护。避免onclick使用属性,它们通常依赖于全局变量。

ready如果您希望代码在 DOM 完全构建后运行,则需要使用。如果您想使用 JS(例如使用 )将事件处理程序绑定到其中的元素,这很有用jQuery.on。这样做而不是使用onclick属性。

于 2013-09-25T08:22:03.423 回答