【问题标题】:stopPropagation: element.addEventListener vs onclick attributestopPropagation:element.addEventListener vs onclick 属性
【发布时间】:2011-08-07 22:47:31
【问题描述】:

我正在使用stopPropagation,从MDC doc 改编代码。

问题是:如果我按照他们的做法使用element.addEVentListener("click", fname),一切都会正常工作。
但是,当我尝试使用元素的 onclick 属性 ( <div onclick="fname();"> ) 附加函数时,传播不会停止。
如果我使用<div onclick="function(ev) {fname();}">,则根本不会调用 fname()(我也尝试通过 fname(ev) 得到相同的结果)。

有什么想法吗?如果您需要查看代码,请告诉我。

【问题讨论】:

    标签: javascript html dom propagation


    【解决方案1】:

    当你这样做时:

    <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 次,即使你不这样做)。


    离题:这整个领域是我推荐使用 jQueryPrototypeYUIClosureany of several others 之类的库的原因之一为您消除浏览器差异,以便您可以专注于自己的工作。

    【讨论】:

    • 我实际上驳斥了这一点,并建议不要使用通用框架。尽管它们各有优势,但可以相当容易地创建跨浏览器框架实现。我建议至少先编写自己的自定义框架,这样您就可以完全理解引擎盖下发生的所有事情。这可以帮助您将来不会遇到类似的问题!把事情放在心上,不在现场,(并且在框架中)是不好的做法!更简单并不意味着更快或更好!
    • J.很高兴知道,谢谢!我现在会坚持使用 addEventListener。否则,我会使用 jQuery 来处理这类事情。这只是一个快速测试页面,所以我还没有链接到 jQ。
    • @Greg: "...可以很容易地创建跨浏览器框架实现..." 哦,这么多年来,很多人都这么认为。 :-) 看看任何主要库的源代码,如果你和我一样,你会欣赏利用其他人所做的所有调试的能力。就像处理在某些情况下 Safari 会在 select 框中错误报告所选项目的事实,或者您必须小心在 IE6 上插入 script 元素的位置以避免遇到奇怪的 base 元素错误。等等(续)
    • @Greg: (继续) 完全同意你必须知道引擎盖下发生了什么,但我仍然不会独自飞行,我是 在我的同事中很有名,因为我倾向于说“哦,不可能那么复杂,让我们自己做吧……”;-)
    【解决方案2】:

    实际上,您的事件通过以下方式起作用:

    事件触发、捕获阶段、冒泡阶段、事件已应用默认操作。

    因此,为了停止传播,您可以执行以下操作:

    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();">
    

    不允许此功能。

    【讨论】:

      猜你喜欢
      • 2015-01-31
      • 2020-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2021-03-07
      相关资源
      最近更新 更多