【问题标题】:Understanding Event Delegation Handling了解事件委托处理
【发布时间】:2013-05-26 21:04:39
【问题描述】:

我正在尝试对同一页面上的不同表单使用事件委托。但是,我在尝试提交表单时遇到了一个有趣的问题。

我尝试在一个表单(用于提交按钮)上“单击”,完全清楚事件委托固有地在整个表单上设置“单击”。

然而,问题在于“点击”事件实际上是在整个页面上设置的,而不仅仅是表单或按钮元素。所以无论我点击页面,都会触发表单的“点击”事件。所有浏览器都会发生这种情况。

'change' 事件也发生了同样的事情。当我在表单上设置“更改”事件时,表单的子字段和特定表单节点之外的其他字段都会触发它。

所以虽然我知道之前有 questions 询问过事件委托,但他们并没有真正回答这个问题。这甚至是一个问题吗?也许这就是事件委托的工作方式?但是如果是这样的话,那么为整个文档触发事件不是浪费内存吗?解决办法是什么?

另外,有没有一种跨浏览器的方法来阻止纯 Javascript 中的传播?我找到的最好的是Quirksmode.org

function doSomething(e)
{    
    if (!e) var e = window.event;
    e.cancelBubble = true;
    if (e.stopPropagation) e.stopPropagation();
}

我知道我可以在触发时按类型过滤事件,但这是唯一可以做的吗?请帮助我理解这一点!

编辑:

具体问题是,将事件委托给表单以处理其特定字段上的事件是否会/也可以触发文档其余部分的事件?如果是这样,如何处理? 如果这不是事件委托的预期行为,那么可能是什么原因造成的?

【问题讨论】:

  • tl;博士。你应该更准确和简洁 - 你的问题是什么?
  • 刚刚添加了一个具体问题。 :)
  • 嗯...现在我不明白你的问题,但也许其他人会:)

标签: javascript events event-handling dom-events event-delegation


【解决方案1】:

一个事件会通过它的祖先冒泡。如果你有 HTML 结构;

<div>
    <h2>
        <span>
            <input />
        </span>
        <strong>
            Blah
        </strong>

...然后单击输入元素,您会看到单击事件源自input 元素,然后冒泡其祖先(spanh2divbody、@ 987654329@)。它不会strong 上触发,因为它不是祖先。有关示例,请参见 http://jsfiddle.net/2QQFS/(单击其中一个 &lt;input /&gt; 框时查看控制台。

您的&lt;form /&gt;s 不应嵌套。如果您在每个 &lt;form /&gt; 元素上附加事件处理程序,并在 other 表单上查看 other 表单的触发事件,我会验证您的 HTML (@987654322 @) 以确保您没有错过某处的结束标签或其他东西。

要查看事件源自的元素,您可以使用e.targete.srcElement (IE

【讨论】:

    【解决方案2】:

    您没有显示注册事件侦听器的实际代码。

    this fiddle 使用 preventDefault 和 stopPropagation。

    我希望它是不言自明的。如果你愿意,请叉出小提琴。

    请注意 form2.input 没有事件侦听器并且事件如何冒泡到 outerDiv。

    form1 是根据相关的用户控件进行停止和阻止的那个。

    输出区域应该说明发生了什么。

    HTML

    <div id="outerDiv">
    <div>
        <input id="pd" value="1" type="checkbox">Prevent Default in form1 keydown</input>
    </div>
    <div>
        <input id="sp" value="1" type="checkbox">Stop Propagation in form1 keydown</input>
    </div>
    <div>
        <button id="clear">Clear Output</button>
    </div>
    <form id="form1" action="">
        <div>
            <label>input of form1
                <input type="text" />
            </label>
        </div>
    </form>
    <form id="form2" action="">
        <div>
            <label>input of form2
                <input type="text" />
            </label>
        </div>
    </form> <pre id="output">
        watch this spot
    </pre>
    </div>
    

    JS

    window.addEventListener('DOMContentLoaded', function (event) {
    // console.log("DOMContentLoaded event handler ...");
    var form1 = document.getElementById('form1');
    var form2 = document.getElementById('form2');
    var output = document.getElementById('output');
    var div = document.getElementById('outerDiv');
    var clear = document.getElementById('clear');
    clear.addEventListener('click', function (event) {
        output.textContent = ('\n' + clear.id + '\'s ' + event.type + ' event handler for ' + event.srcElement.localName + ' clears output');
    }, false);
    console.dir(output);
    div.addEventListener('keydown', function (event) {
        output.textContent += ('\n' + div.id + '\'s ' + event.type + ' event handler for ' + event.srcElement.localName + ' notices  \'' + event.srcElement.value + '\'');
    }, false);
    form1.addEventListener('keydown', function (event) {
        output.textContent += ('\n' + form1.id + '\'s ' + event.type + ' event handler for ' + event.srcElement.localName + ' notices  \'' + event.srcElement.value + '\'');
        // prevents default of generating an input event
        if (document.getElementById('pd').checked) {
            event.preventDefault();
            output.textContent += ('\n\t' + form1.localName + '\'s ' + event.type + ' event handler does preventDefault');
        }
        // stops propagation up to div
        if (document.getElementById('sp').checked) {
            event.stopPropagation();
            output.textContent += ('\n\t\t' + form1.localName + '\'s ' + event.type + ' event handler does stopPropagation');
        }
    }, false);
    form1.addEventListener('input', function (event) {
        output.textContent += ('\n' + form1.id + '\'s ' + event.type + ' event handler for ' + event.srcElement.localName + ' notices  \'' + event.srcElement.value + '\'');
    }, false);
    }, false);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-16
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多