我想在我的项目中添加两个事件。
一个用于文档的“背景”:$(document).click(function() {do()});
一个用于文档中的div:$("div").click(function() {do2()});
问题在于,当我点击div
时,会调用do
和do2
两个函数。
如果我点击没有元素,我怎么能告诉do()
?
感谢您的帮助,
学家
答案 0 :(得分:7)
您在这里寻找的术语是事件传播或事件冒泡。
“现代”浏览器中的事件处理(大多数库挂钩的模型)通过冒泡文档树来工作。这意味着如果您有像这样的HTML文档结构
<body>
<div>
<ul>
<li>Foo</li>
<li>Bar</li>
<li>Baz</li>
</ul>
</div>
</body>
有人点击Foo,发生以下事件
这就是发生在你身上的事。你可以做两件事来防止这种情况发生。
第一个,正如许多人所建议的那样,如果您的事件处理程序返回false,那么事件传播将停止在已单击的元素上。 (这是jQuery处理它的方式,每个库都有不同的方法)
$(document).ready(function() {
//hookup events for entire body of document
$('body').bind('click', function(e){
//do clicked body stuff
});
//hookup our divs, returning false to prevent bubbling
$('div').bind('click', function(e){
//do clicked div stuff
return false; //stop event propagation
});
});
第二,有些人认为更好,方法是使用事件委托。在Javascript和DOM的上下文中,事件委托是将单个事件处理程序附加到外部元素(在本例中为正文)的位置,然后根据最初单击的元素执行特定操作。
像这样。
$(document).ready(function() {
//event delegate
$('body').bind('click', function(e){
var originalElement = e.srcElement;
if(!originalElement){originalElement=e.originalTarget;}
if ($(originalElement).is('div')) {
console.log("A div!");
}
else if ($(originalElement).is('div#inside')) {
console.log("A Specific Div!");
}
else{
console.log("Something else!");
}
});
});
这样做的好处是双重的。首先,您可以将所有事件处理代码集中到代码中的单个位置。第二个(在我看来更重要)是附加一个事件处理程序会消耗更少的浏览器内存,并为您提供更好的性能。
答案 1 :(得分:3)
诀窍是从事件处理程序返回false。这将阻止事件进一步传播。
这似乎对我有用:
<html><head>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js"></script>
<script type="text/javascript"><!--
$(document).ready(function() {
$(document).click(function() {
alert('document'); return false;
});
$('#my_div').click(function() {
alert('div'); return false;
});
});
--></script>
<body>
<h1>hello!</h1>
<div id="my_div">this div is special</div>
</body></html>
答案 2 :(得分:3)
你必须调用stopPropagation()。在Firefox中,Andyk和Stans的例子都失败了。
这里我在firefox中对此进行了测试,但它确实有效。
$("html").click(function(event){
event.stopPropagation();
alert('document');
});
$("div").click(function(event){
event.stopPropagation();
alert('div');
});
答案 3 :(得分:-2)
您可以尝试从文档选择器中排除div
。
$(document:not(div)).click(function() {do()});
$("div").click(function() {do2()});
未经测试。
编辑:意识到我的答案确实是错的。我会把它放在这里,以显示做这件事的错误方法。对于正确的答案,请寻找赞成的答案。