2011-04-18 120 views
2

我在使用stopPropagation,修改MDC doc中的代码。stopPropagation:element.addEventListener vs onclick属性

下面是一个问题:如果我按照他们所做的操作并使用element.addEVentListener("click", fname),一切正常。
但是,当我试图附加功能元素的onclick属性(<div onclick="fname();">),传播不停止。
如果我使用<div onclick="function(ev) {fname();}">,fname()根本不被调用(我也尝试通过fname(ev)得到相同的结果)。

想法任何人?让我知道你是否需要看代码。

回答

8

当你这样做:

<div onclick="fname();"> 

你不作为事件处理程序分配fname,你调用fname事件处理程序(这是为您创建一个匿名函数)。所以你的第一个参数是你传入的任何东西fname,并且在你引用的代码中,你不会传递任何东西。

你会想:

<div onclick="fname(event);"> 

但即使这样,将不可靠的,因为它假定自动生成的匿名函数使用的名称event接受event参数或您使用IE或浏览器,做类似IE的事情,你正在看IE的全球window.event属性。

更可靠的事情是这样的:

<div onclick="return fname();"> 

...并有fname返回false如果它想阻止都传播,并防止浏览器的默认行为。

这一切

为什么我极力主张始终使用DOM2方法(addEventListener,这是attachEvent   —略有不同的参数上之前IE9 IE   —),如果你想要做什么有趣的事件挂钩处理程序(或者10次中的9次,即使你没有)。


题外话:这整个地区是我推荐使用库像jQueryPrototypeYUIClosure,或any of several others平滑过度浏览器的差异给你,让你可以集中精力的原因之一你自己的工作。

+1

我真的会反驳,并建议不要使用通用框架。虽然他们有它们的优点,但可以非常容易地创建跨浏览器框架实现。我建议至少先编写自己的自定义框架,以便您可以完全理解所有正在发生的事情。这有助于你在将来不会遇到像这样的问题! 把事情放在心上,离开网站,(并在框架中)是不好的做法!更简单并不意味着更快,或更好! – GAgnew 2011-04-18 15:01:28

+0

J.很高兴知道,谢谢!我现在坚持使用addEventListener。否则,我确实使用jQuery来处理这类事情。这只是一个快速测试页面,所以我还没有链接到jQ。 – Nathan 2011-04-18 15:16:03

+1

@Greg:*“......跨浏览器框架实现可以很容易地创建......”*哦,很多人都认为这些年来。 :-)只要看看任何主要的图书馆的源代码,如果你像我一样,你会明白利用其他人所做的所有调试的能力。就像处理Safari在某些情况下会在“select”框中错误地报告所选项目一样,或者在IE6中插入'script'元素以避免遇到奇怪的'base'元素时必须小心的事实错误。等* *(续)* – 2011-04-18 15:31:19

6

其实,你的事件的行为在以下几个方面:

事件触发,捕获阶段,冒泡阶段,事件已申请默认操作。

因此,为了阻止传播,你可以做到以下几点:

element1.addEventListener('click',fname,true) // Capturing phase 
element1.addEventListener('click',fname,false) // Bubbling phase 

fname(event){ 
    event.stopPropagation(); 
//event.preventDefault(); is also available here (in both phases I believe) 
} 

请注意,传播只能在冒泡阶段被停止,只有使用事件处理程序以这种方式可以让你打断事件。

据我知道的

<div onclick="return fname();"> 

的tradidtional方法不允许此功能。