如何将“更改”事件委托给正文的输入元素?

Posted

技术标签:

【中文标题】如何将“更改”事件委托给正文的输入元素?【英文标题】:How can I delegate 'change' event on input element from body? 【发布时间】:2018-12-27 09:02:59 【问题描述】:

我已经知道 jQuery 的事件委托。 但是,我如何在没有 jQuery 的情况下使用纯 javascript 做同样的事情。

虽然我在 body 或顶部元素 (div) 上附加了 change 事件,但当 body 或顶部元素中的输入元素的值发生更改时,change 事件不会触发...

我该怎么做?

【问题讨论】:

这意味着,我是否在正文中的每个输入元素上附加事件?..所以,我认为可能会发生性能问题......嗯 啊,对不起,我真的错过了倒数第二行关于输入的部分 所以,是的,如果您有输入、选择或文本区域,它确实有效 【参考方案1】:

您可以只监听一个元素(在本例中为 elSelector)上的事件,然后仅当实际目标适合该元素中的 selector 时才执行该事件。

function on(elSelector, eventName, selector, fn) 
    var element = document.querySelector(elSelector);

    element.addEventListener(eventName, function(event) 
        var possibleTargets = element.querySelectorAll(selector);
        var target = event.target;

        for (var i = 0, l = possibleTargets.length; i < l; i++) 
            var el = target;
            var p = possibleTargets[i];

            while(el && el !== element) 
                if (el === p) 
                    return fn.call(p, event);
                

                el = el.parentNode;
            
        
    );

在下面的示例中,您可以看到它也适用于动态元素!

on("#inputs", "change", ".event", (target, evt) => console.log(target.target));




function on(elSelector, eventName, selector, fn) 
  var element = document.querySelector(elSelector);

  element.addEventListener(eventName, function(event) 
    var possibleTargets = element.querySelectorAll(selector);
    var target = event.target;

    for (var i = 0, l = possibleTargets.length; i < l; i++) 
      var el = target;
      var p = possibleTargets[i];

      while (el && el !== element) 
        if (el === p) 
          return fn.call(p, event);
        

        el = el.parentNode;
      
    
  );


/** random code for the button to add more inputs **/

let i = 7;

document.querySelector("#b").addEventListener("click", () => 
  document.querySelector("#inputs").innerhtml += i + ` <input type="text" class="event"> <br>`;
  i++;
);
<div id="inputs">
  1 <input type="text" class="event"> <br>
  2 <input type="text" class=""> <br>
  3 <input type="text" class="event"> <br>
  4 <input type="text" class=""> <br>
  5 <input type="text" class="event"> <br>
  6 <input type="text" class=""> <br>
</div>

<br><br>
<button id="b">Add another input</button>

【讨论】:

【参考方案2】:

让我们定义您的活动function

function(event) doSomething
    //Your code

让我们在body 中获取所有input 标签:

var inputs = document.getElementsByTagName('input');

现在,让我们迭代它们并附加事件:

for (var inputIndex = 0; inputIndex < inputs.length; inputIndex++) 
    inputs.addEventListener('change', doSomething);

【讨论】:

但是,如果某些输入元素是动态创建的,这些输入元素将无法监听'change'事件。 @YounghunJung 您可以通过监听 DOMSubtreeModified 事件并相应地处理更改来实现这一点,请参见此处:developer.mozilla.org/en-US/docs/Web/Events/DOMSubtreeModified @YounghunJung 或者您可以为此目的使用 MutationObserver API,请参见此处:davidwalsh.name/detect-node-insertion

以上是关于如何将“更改”事件委托给正文的输入元素?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript中的事件委托机制

JavaScript事件委托

js中的事件委托

css/js 将固定元素上的滚动事件委托给它们下面的元素

JavaScript中冒泡与事件委托

JavaScript事件委托原理及Jquery中的事件委托