【问题标题】:Programmatically fired events not working with event delegation以编程方式触发的事件不适用于事件委托
【发布时间】:2010-04-22 07:41:51
【问题描述】:

如果有人能帮我弄清楚为什么我在 MooTools 中使用事件委托(来自 Element.Delegation 类)时无法以编程方式触发事件,我将不胜感激。

有一个父 <div> 在某些子 <input> 元素上有一个 change 侦听器。当用户操作触发更改事件时,父 div 上的处理程序会被触发,但是当我在任何子输入上使用 fireEvent 以编程方式触发它时,什么也没有发生。基本设置是:

html

<div id="listener">
    <input type="text" id="color" class="color" />
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​</div>​​​​​​​​​​​

js

$("listener").addEvent("change:relay(.color)", function() {
    alert("changed!!");
});

$("color").fireEvent("change"); // nothing happens

没有调用父 div 上的事件处理程序。任何帮助表示赞赏。


相关问题:使用fireEvent 触发的事件是否会在 DOM 树中冒泡?我目前的 hack 是在本地调度正在运行的事件(但仍然是 hack)-http://jsfiddle.net/SZZ3Z/1/

var event = document.createEvent("HTMLEvents")
event.initEvent("change", true);
document.getElementById("color").dispatchEvent(event); // instead of fireEvent

【问题讨论】:

    标签: javascript mootools event-delegation mootools-events


    【解决方案1】:

    “按原样”这样做不会很好。事件冒泡(以及事件的程序触发)的问题是它可能需要事件对象是“真实的”,以便它包含与中继字符串匹配的event.target。此外,document.id("color").fireEvent() 将不起作用,因为颜色本身没有附加任何事件。

    为了解决这个问题,您可以通过传递一个包含目标元素的事件对象来伪造父侦听器上的事件,如下所示:

    document.id("listener").fireEvent("change", {
        target: document.id("color")
    });
    

    查看实际操作:http://www.jsfiddle.net/xZFqp/1/

    如果您在回调函数中执行 event.stop 之类的操作,那么您需要为您可能引用的任何事件方法传递 {target: document.id("color"), stop: Function.from} 等等,但事件委托代码目前只对 target 感兴趣。

    【讨论】:

    • 感谢这种方法 Dimitar。但是,我对直接在父级上触发事件感到不舒服,因为这对内部工作过于友好。另外,如果说 MooTools 不使用 DOM 事件调度机制,并且在元素存储中为每个元素存储事件处理程序,我会不会错?
    • 我没有看到通过父侦听器触发事件​​的问题。老实说,mootools 核心团队是第一个承认,目前事件委托的实现并不出色。我无法评论即将发布的 1.3 或几乎准备好的 mootools 2.0 中即将发生的事情,但您是正确的,因为事件基本上是在事件下的元素存储中(因此您可以执行 var myEvents = this.retrieve("events"); 并获取事件的对象命名为键,如myEvents.click 并可以在 click.keys 下进一步探索以找到存储的函数。
    • 我还要说,您用于调度事件的本机方法不是跨浏览器兼容的(FF 失败),当您需要满足需求时,这种事情违背了使用框架的目的对于所有浏览器引擎实现这一点的所有可能方式......话虽如此,如果你得到这个,可能值得在 github 上将它作为 Event 类的新方法提交,例如fireNativeEvent: function(eventType)。祝你好运
    • 感谢您的好评。我真的很期待尽快在我的网站上使用 1.3。调用父级似乎不是什么大问题,最好将其记录下来或将其放入我们的功能测试中,以便在确实发生 MooTools 版本升级时,我们会小心地测试这些更改。也就是说,我正在考虑在Element.Event 上实现一个名称完全相同的方法fireNativeEvent :),以隔离对单个函数的更改。现在它不是跨浏览器,也不能在 IE/FF 上运行。但如果我写这个,我会在github上分享。
    【解决方案2】:

    我是这样解决的:

    document.addEvents({
        'click:relay(.remove_curso)': function(){
            document.fireEvent('_remove_curso', this);
        },
        '_remove_curso':function( me ){
            console.log( me );
        }.bind( this )
    }
    

    【讨论】:

      猜你喜欢
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多