Javascript 单击事件的jQuery开/关方法从外部脚本失败
这在嵌入脚本时起作用。为什么当代码在外部脚本中时,它只对两次单击有效 嵌入式机箱:Javascript 单击事件的jQuery开/关方法从外部脚本失败,javascript,jquery,Javascript,Jquery,这在嵌入脚本时起作用。为什么当代码在外部脚本中时,它只对两次单击有效 嵌入式机箱: <html> <head> <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script> </head> <body> <h1 id="title" onclick="sayGoodbye();"> Hello </h1>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<h1 id="title" onclick="sayGoodbye();"> Hello </h1>
</body>
<script type="text/javascript">
function sayGoodbye() {
console.log("goodbye");
$("#title").html("Goodbye");
$("#title").click(function() {
$("#title").html("Hello");
$("#title").off("click");
});
};
</script>
</html>
传递函数引用的语法不正确
$('#title').on('click',sayGoodbye());
由于()
,将立即调用该函数
改为:
$('#title').on('click',sayGoodbye);
问题与文件是外部的或嵌入的无关 您更改了代码,这就是它停止工作的原因。您可以保持HTML代码与原始代码相同
Hello
既然你变了,这就是它不再工作的原因
通过Javascript的addEventListener
或jQuery的on
添加事件监听器时,必须始终传递函数引用,而不能传递函数执行。如果使用()
,将立即调用该函数,并将其返回值传递给正在调用的另一个函数
例如,如果我这样做:
function num() {
return 5;
}
console.log(num); // it will log 'function num()'
console.log(num()); // it will log 5
由于您的saybye
函数不返回任何内容,因此传递给jQuery的on
的值将是未定义的
function num() {
var y = 5;
y = y + 10;
}
console.log(num); // it will log 'function num() '
console.log(num()); // it will log 'undefined'
当你输入HTMLonclick=“saybye();”
时,你实际上是在说:
Element.onclick = function() {
sayGoodbye();
}
它会自动将代码包装到匿名函数中,并将其作为事件的引用传递
Tl;dr
您的代码不起作用,因为您正在使用:
$('#title').on('click', sayGoodbye());
它立即计算/调用函数,因为括号存在
相反,您应该按名称提供回调函数:
$('#title').on('click', sayGoodbye);
或者作为匿名函数:
$('#title').on('click', function() {
sayGoodbye();
});
更新
在你改变问题之后,这似乎是另一个简单的问题
您在哪里定义您的
您应该将其放置在嵌入的位置。如果您已将其放入head
标记中,则即使在加载h1#test
之前也会对其进行评估,然后,它将找不到元素,也不会向其添加事件侦听器
但是,如果您确实想/需要将其放入head
标记中,则必须将代码包装到load
事件侦听器中。如果使用香草Javascript,它将是:
document.addEventListener('DOMContentLoaded', function() {
// your code
});
但是因为您使用的是jQuery,所以可以使用$(document)。ready
:
$(document).ready(function() {
// your code
});
这里有一个缩写,就是用$()来表示代码>:
注意:我刚刚意识到,这里最大的问题是您不理解执行Hello
和通过jQuery添加事件处理程序之间的区别
您的第一个示例按照您预期的方式工作,因为当您这样做时:
$("#title").html("Goodbye");
$("#title").click(function() {
$("#title").html("Hello");
$("#title").off("click");
});
你是说:
将id为title
的元素的innerHTML
属性更改为“再见”
添加一个单击事件处理程序:
2.1将id为title
的元素的innerHTML
属性更改为“Hello”
2.2删除事件的所有jQuery事件处理程序单击
那么,接下来会发生什么:
当您第一次单击时
1.1您的h1
将更改为“再见”
1.2将有一个新的点击事件处理程序
当您第二次单击时
2.1它将首先再次触发同一事件,因此您的h1
将更改为“再见”
2.2它将有一个新的点击事件处理程序
2.3将触发先前在1.2
上添加的事件处理程序
2.4然后,您的h1
将变回Hello
2.5,然后删除它的所有jQueryclick
事件处理程序
因此,当您第三次单击时,与加载页面时一样,因为放入HTML代码中的事件处理程序仍将保留,但附加到h1
的所有jQuery事件处理程序都已删除
也就是说,第三个将与第一个相同,第四个将与第二个相同,依此类推
当您停止将事件处理程序附加到HTML代码中,并开始通过jQuery附加它时,您的代码将停止工作,因为:
当您第一次单击时
1.1您的h1
将更改为“再见”
1.2将有一个新的点击事件处理程序
当您第二次单击时
2.1它将首先再次触发同一事件,因此您的h1
将更改为“再见”
2.2它将有一个新的点击事件处理程序
2.3将触发先前在1.2
上添加的事件处理程序
2.4然后,您的h1
将变回Hello
2.5并删除它的所有单击事件处理程序
如您所见,与上面的示例非常相似。但是有一个很大的区别:当发生2.5
时,您不再有任何click
事件处理程序附加到h1
,因为您已经将它们全部删除
这种情况会发生,因为当您只将一个参数传递给jQuery的off
方法时,您说的是“删除该类型事件的所有jQuery事件处理程序”(在这种情况下,单击
)。因此,它将同时删除附加到saybye
的事件处理程序和您使用匿名函数创建的事件处理程序
在第一个示例中,它没有发生,因为jQuery不知道您通过HTML代码附加的事件,所以它永远不会删除它,并且您的代码按照您期望的方式工作
因此,如果您只想使用jQuery,那么您的代码应该是:
$(function(){
function sayGoodbye() {
$('#title')
.html('Goodbye')
.off('click', sayGoodbye)
.on('click', sayHello);
}
function sayHello() {
$('#title')
.html('Hello')
.off('click', sayHello)
.on('click', sayGoodbye);
}
$('#title').on('click', sayGoodbye);
});
JavaScript中没有引用(除非讨论引用规范类型,但是..)。将其称为函数对象要整洁得多。那就没有了
$(function() {
// your code
});
$("#title").html("Goodbye");
$("#title").click(function() {
$("#title").html("Hello");
$("#title").off("click");
});
$(function(){
function sayGoodbye() {
$('#title')
.html('Goodbye')
.off('click', sayGoodbye)
.on('click', sayHello);
}
function sayHello() {
$('#title')
.html('Hello')
.off('click', sayHello)
.on('click', sayGoodbye);
}
$('#title').on('click', sayGoodbye);
});