DOM事件系列[4]

[4]阻止浏览器默认事件行为

  1. 首先我们来说说什么是浏览器的默认行为,比如对于一个html的a标签,浏览器的处理都是链接跳转。如果我们不想点击a标签的时候,浏览器进行页面跳转,这时候就需要阻止浏览器的跳转行为,而这个跳转行为就是浏览器默认的处理方式,也就是默认事件行为。
  2. 前面说到阻止浏览器的默认行为我们可以使用event.preventDefault()。但是很多时候,我们会看到代码中也有使用return false来阻止浏览器的默认行为。这小节主要就是来探讨使用event.preventDefault()和使用return false之间的区别。

    1
    2
    <a class='toggle'>Click Me!</a>
    <div id='mydiv'>MyDiv</div>
    1
    2
    3
    4
    $('a.toggle').click(function(){
    $('#mydiv').toggle();
    return false;
    });

    案例查看

    1. 通过上面的例子,我们可以看到在点击a标签的时候并没有发生浏览器页面跳转行为。当我们把JavaScript代码中的return false注释掉之后,再次点击a标签会发现浏览器进行了页面跳转。所以可以看到return false确实是可以用来阻止浏览器的默认行为。
    2. 我们将上面的return false换成event.preventDefault(),可以看到同样能阻止浏览器页面的跳转。案例查看
      3.既然return false 和 event.preventDefault() 都能阻止浏览器的默认行为,那是不是随便用哪个都OK呢?显然不是的,下面就来说说两者之间的差别。

Return false VS. event.preventDefault()

  1. 使用return false来取消浏览器默认行为的时候,其背后做了两件事情。分别是:

event.preventDefault()
event.stopPropagation()
什么鬼!?不要惊讶,就是酱紫。return false不禁阻止了浏览器的默认行为,而且还阻止了事件冒泡。具体Show by code!

1
2
3
4
5
6
7
8
9
10
11
12
<div class="post">
<h2><a href="http://www.scholat.com/zengweiquan">My Page</a></h2>
<div class="content">
Teaser text...
</div>
</div>
<div class="post">
<h2><a href="https://github.com/ScholatLouis">My Other Page</a></h2>
<div class="content">
Teaser text...
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(function(){
$("div.post h2 a").click(function (event) {
var event = event || window.event;
var a = $(this),
href = a.attr('href'),
content = a.parent().next();
content.html(href + " #content");
return false;
});

var posts = $("div.post");
posts.click(function () {
alert("posts click!");
});
});

从代码中可以看出,使用return false之后,点击a标签并不会有弹框:posts click!出现。如果我们把return false换成event.preventDefault()之后,就可以看到posts click!的出现。案例查看
原因分析:

  1. 首先posts click!弹框是绑定在a标签的父元素div上。正常情况下,当a标签发生点击事件的时候,事件会向上冒泡,div绑定的click事件监测到点击事件的发生,则执行代码:alert(“posts click!”),于是出现了弹框。
  2. 使用return false之后,因为其背后执行了event.preventDefault(); event.stopPrapagation();这句代码,第一句首先是阻止了页面的跳转,所以我们可以看到点击a标签之后并没有发生页面跳转;第二句则是阻止点击事件向上冒泡,从而使得a标签的父元素div没能检测到click事件的发生,因此没有弹框posts click!的发生。

结论:

  1. 如果我们只是单纯需要阻止浏览器的默认行为,则应该使用event.preventDefault()而不要使用return false。

stopProgapation() VS. stopImmediatePropagation()

  1. 在阻止事件冒泡JavaScript也提供了两个事件函数,分别是stopProgapation()和stopImmediatePropagation()。这一部分,我们来说下这两个时间函数的区别。

stopProgapation()函数:

  1. 阻止当前事件向上传播,但是不影响当前元素所绑定的其他事件的执行。
    stopImmediatePropagation()函数:
  2. 阻止当前事件向上传播,同时当前元素绑定的相同事件都将不再执行,不会影响不同事件的执行。案例查看
1
2
3
4
5
6
7
8
9
10
11
12
<div class="post">
<h2><a href="http://www.scholat.com/zengweiquan">My Page</a></h2>
<div class="content">
Teaser text...
</div>
</div>
<div class="post">
<h2><a href="https://github.com/ScholatLouis">My Other Page</a></h2>
<div class="content">
Teaser text...
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(function(){
$("div.post h2 a").click(function (event) {
var event = event || window.event;
var a = $(this),
href = a.attr('href'),
content = a.parent().next();
content.html(href + " #content");
event.preventDefault();
event.stopPropagation();
});
$("div.post h2 a").click(function(event){
var event = event || window.event;
alert("stopPropagation()");
});
var posts = $("div.post");
posts.click(function () {
alert("posts click!");
});
});
  1. 从上面的代码可以看到a标签绑定了两个click事件,第二个是一个弹框,内容为:stopPropagation() 。执行代码可以看到确实是会有弹框,且弹框内容为:stopPropagation()。案例查看
  2. 我们将上面的代码做出如下修改,将event.stopPropagation()改成event.stopImmediatePropagation()。案例查看。修改之后的代码执行,不再有弹框出现。