超级简单的 JQuery 问题让我难住了。代码不会在 <head> 中触发,但会在 <body> 中触发

Edw*_*ter 1 javascript jquery

以前从未见过这个。这么简单的事情我做错了。

我的 JQuery 代码刚刚停止在 head 标签中工作,现在只能在 body 中工作。

这将起作用:

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>

<body>

<div id="foo">
  Click Me
</div>

<script type="application/javascript">
$('#foo').click(function(){
  alert("I got here");
});
</script>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

这不会:

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

<script type="application/javascript">
$('#foo').click(function(){
  alert("I got here");
});
</script>

</head>

<body>

<div id="foo">
  Click Me
</div>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

有点困惑。我没有看到错字。非常感谢建议!

T.J*_*der 5

问题是您的代码在元素存在之前$("#foo")运行,因此找不到它。

除非您使用asyncdefer属性,否则标记中的代码在 HTML 中遇到时script就会运行。所以:

<script>/* your code here */</script>
<div id="foo">..</div>
Run Code Online (Sandbox Code Playgroud)

...将找不到该#foo元素,因为它还不存在。

但如果你有

<div id="foo">..</div>
<script>/* your code here */</script>
Run Code Online (Sandbox Code Playgroud)

...该元素存在并且您的代码可以找到它。

您有三个选择:

  1. 使用事件委托,您可以挂接事件,但仅当事件在冒泡阶段document穿过元素时才响应它。#foo例子:

    $(document).on("click", "#foo", function() {
        // Do something
    });
    
    Run Code Online (Sandbox Code Playgroud)

    这很有效,除非有其他东西可以处理 的后代元素上的事件document并防止其冒泡。

  2. 将脚本放在HTML 中它引用的元素下方。这是非常优选的。标签上方的标记中定义的任何元素script将在脚本运行时存在。因此通常的建议是将 放在script结束</body>标记之前。

  3. 如果您不控制元素的script去向,请使用 jQuery 的readyfunction

    $(document).ready(function() {
        // Your code here
    });
    
    Run Code Online (Sandbox Code Playgroud)

    或快捷方式:

    $(function() {
        // Your code here
    });
    
    Run Code Online (Sandbox Code Playgroud)