我只是不明白。我搜索和搜索但是为此我只是无法弄清楚什么是“正确的”。
有三个例子。
1)Fiddle 1.0
在这里,我们html
onlick="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(点击它总是工作正常。这个函数调用另一个函数,它在docuemnt.ready()之外,也可以正常工作。
所以问题。我何时必须定义函数where AND WHY以便它始终有效?
谢谢!
示例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>
答案 0 :(得分:15)
您所看到的很多内容都是因为jsFiddle的 非常令人惊讶的 默认设置,即将代码包装在{{1}的脚本窗格中处理程序。所以你的代码被包装在一个函数中,而不再是全局范围(如果你使用onload
- 样式属性,那就是函数需要的地方)。您可以使用左侧的下拉框(第二个,在库和脚本列表下)更改此设置。将其更改为“无包装”以获得未包装的代码。
你不是(到目前为止)第一个被这个令人惊讶的默认值所困扰的人。
回答你的主要问题:
当函数在$(document).ready()
时
如果您控制加载脚本的onclick
标记的位置,则基本上不必使用script
;相反,只需确保您的ready
代码位于HTML的结束,就在结束script
之前。
当然,你可以使用</body>
。这样做的原因是确保在代码运行之前创建了所有DOM元素。但是如果你把ready
标签放在最后,那就已经是真的了。您仍然可以在script
处理程序之外定义函数(如果您希望它们是全局变量),但是如果您使用的是ready
,那么您将从<{1}}调用 ready
处理程序,因此元素存在。
FWIW,我会避免使用ready
- 样式属性来挂钩事件处理程序,主要是因为它们需要您创建全局函数。我宁愿避免在我可以避免的情况下创建任何全局符号。
我推荐的一般表格:
onclick
您的脚本如下所示:
<!-- ...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>
以下是一个完整的示例:Live Copy
(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
答案 1 :(得分:3)
在JavaScript中,范围是基于每个函数处理的。函数范围内的任何东西都可以访问该函数范围内的其他事物以及更广泛范围内的事物。
在函数内定义带var
的变量会将该变量的范围限制为该函数。
在另一个函数中使用函数声明定义函数将限定函数的范围限制为容器函数。
使用ready
时,会向其传递函数。当然,该函数中定义的任何内容都是作用于该函数的。由于它是作用于该功能的范围,因此它不是全局的。您的onclick属性未在该函数的范围内定义,它只能访问全局变量。这就是您收到参考错误的原因。
避免使用全局变量。他们使事情难以维持。避免使用onclick
属性,它们通常依赖于全局变量。
如果您希望在完全构建DOM之后运行代码,则需要使用ready
。如果要使用JS将事件处理程序绑定到其中的元素(例如,使用jQuery.on
),这将非常有用。这样做而不是使用onclick
属性。