打印

BX9026: 在 IE 的事件监听处理函数中使用 return false 语句依然可以阻止浏览器默认行为执行

作者:钱宝坤

标准参考

事件处理函数中的 return false 方法最初由 Netscape 制定,当时还没有事件监听注册方法,浏览器只支持为一个标记绑定一个事件处理函数,由此 Netscape 规定如果事件处理函数返回 false ,将就要阻止浏览器的默认事件行为继续执行,这个事实规范在所有浏览器中都被支持,它用于单一事件绑定函数中。

在现行 DOM-Events 规范中已定义了 preventDefault 标准方法来阻止浏览器默认行为,该方法用来在事件监听处理程序中阻止浏览器默认事件触发。

如经常使用的链接标记 A,用户点击他后浏览器将会根据 href 属性加载新的页面,这个默认行为是由点击一个链接事件引起的。但是,当该标签上还定义了一个 onclick 事件处理程序时,这个默认行为还被执行么?又是什么时候被执行的呢?这个问题显而易见,所有浏览器都会先执行 onclick 事件处理程序,而后再处理浏览器默认行为。此时,如果 onclick 事件处理程序返回值为 false,那么浏览器的默认行为将被阻止。这个在现看来是“约定俗成”的事实规范在所有浏览器中都被支持。

关于取消事件的详细描述请参考 DOM-Level-2-Events 规范 1.2.4. Event cancelation

关于 preventDefault 方法的描述请参考 DOM-Level-2-Events 规范 1.4. Event interface

问题描述

古老的 return false 语句根据其历史使命应该仅对事件绑定函授处理方式生效,在事件监听处理程序中将不会阻止浏览器默认事件触发。

但是在 IE 浏览器私有的事件处理模型和新支持的标准事件模型中,这个语句依然可以达到阻止浏览器默认事件触发的效果。

造成的影响

在 IE 浏览器中,事件监听处理程序中的 return false 语句可以阻止浏览器默认行为继续执行,会导致超出作者预期的执行效果。

受影响的浏览器

IE6/7/8

问题分析

1、在事件绑定函数中使用 return false 语句阻止链接默认行为

分析以下代码:

<a href="http://www.google.com/" onclick="return false">点击链接去 google ~~</a>

A 标记的 onclick 内联事件中执行了 return false 语句,他成功的阻止了浏览器加载 google.com 页面的默认行为,并且所有浏览器对此均处理一致。

 

2、在事件监听处理函数内使用 preventDefault 方法阻止链接默认行为

分析以下代码:

<a href="http://www.google.com/">点击链接去 google ~~</a>
<script>
  window.onload = function (){
    function stopDefault(e){
      e = e || window.event;
      (e.preventDefault)
      ?e.preventDefault()
      :e.returnValue = false;1
    }
    function addEvent(el, type, fn){
      (el.addEventListener)
      ? el.addEventListener(type, fn, false)
      : el.attachEvent("on" + type, fn);1

    }
    addEvent(document.getElementsByTagName("a")[0],"click",function (e){stopDefault(e)});
  }
</script>

上例中使用事件监听处理方法监听 A 标记的 click 事件,在具体处理函数内取消浏览器默认事件。

这种方法也成功的阻止了浏览器加载 google.com 页面的默认行为,并且所有浏览器对此均处理一致。

注1:IE 浏览器有其独有的事件处理模型,与 W3C 规范不同,此处优先判断并使用规范中的 preventDefault 方法,否则将使用 IE 事件模型 event. returnValue = false 语句来阻止浏览器默认行为。

注2:IE 浏览器有其独有的事件监听处理模型,与 W3C 规范不同,此处优先判断并使用规范中的 addEventListener 方法,否则将使用 IE 的事件监听处理模型语句 attachEvent ,为元素添加事件处理函数。

 

3、在事件监听处理函数内的 return false 语句阻止链接默认行为

分析以下代码:

<a href="http://www.google.com/">点击链接去 google ~~</a>
<script>
  window.onload = function (){
    function addEvent(el, type, fn){
      (el.addEventListener)
      ? el.addEventListener(type, fn, false)
      : el.attachEvent("on" + type, fn);

    }
    addEvent(document.getElementsByTagName("a")[0],"click",function (){return false});
  }
</script>

本例中代码与例2大致相同,仅在事件处理函数中使用 return false 语句替换原始程序语句。

不幸的是此程序执行后在各浏览器内明显存在差异,见下表:

IE6/7/8 IE9 Firefox Safari Chrome Opera
链接不跳转 链接跳转到 Google

根据上表可以看出,IE6/7/8 浏览器中的 return false 语句在事件监听处理函数中依然可以阻止浏览器默认事件,而其他浏览器在此情况下只有明确的使用 preventDefault 方法才能达到相同效果。

从 return false 语句的历史使命来看,他最初在单一事件绑定处理程序上生效,而 DOM-Events 中规定了标准事件处理模型,取消浏览器默认行为的语句为 preventDefault。 因此 return false 语句不应该会影响新的事件模型。
虽然 IE 使用了一套独立事件处理模型,可他仍有 e.returnValue = false 语句来达到与 return false 相同的功效,这与规范的事件模型定义有异曲同工之意, return false 语句也不应该影响他的事件模型。但是 IE6/7/8 并没有这么处理,由此可见,他对于 return false 这个古老的语句处理很有些守旧的味道。

解决方案

  • 不要在事件监听处理函数内使用 return false 语句,在 IE6/7/8 中他会阻止浏览器默认行为执行;
  • 如果希望在事件绑定函数内取消浏览器默认行为,可以使用 return false 语句;
  • 如果希望在事件监听.处理函数内取消浏览器默认行为,可以使用 preventDefault 方法(IE 中需使用其私有的 event.returnValue = false 属性设置)。

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6.8
Chrome 7.0.503.0 dev
Safari 5.0.1
Opera 10.61
测试页面: prevent_browser_default_behavior.html
本文更新时间: 2010-09-08

关键字

preventDefault returnValue Browser Befault Behavior