8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

原生 JavaScript 事件委托

Mikkel 2月前

128 0

在 vanilla js 中进行事件委托的最佳方式(最快/正确)是什么?例如,如果我在 jQuery 中有这个:$('#main').on('click', '.focused', function(){ settingsPanel();})...

在 vanilla js 中进行事件委托的最佳方式(最快/最合适)是什么?

例如如果我在 jQuery 中有这个:

$('#main').on('click', '.focused', function(){
    settingsPanel();
});

我该如何将其转换为原生 js?或许可以用 .addEventListener()

我能想到的方法是:

document.getElementById('main').addEventListener('click', dothis);
function dothis(){
    // now in jQuery
    $(this).children().each(function(){
         if($(this).is('.focused') settingsPanel();
    }); 
 }

但这似乎效率低下,特别是在 #main 有很多孩子的情况下。

那么这是正确的做法吗?

document.getElementById('main').addEventListener('click', doThis);
function doThis(event){
    if($(event.target).is('.focused') || $(event.target).parents().is('.focused') settingsPanel();
}
帖子版权声明 1、本帖标题:原生 JavaScript 事件委托
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Mikkel在本站《loops》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我想出了一个简单的解决方案 ,它似乎效果很好(尽管支持旧版 IE)。在这里,我们扩展了 EventTarget 的原型,以提供一种 delegateEventListener 使用以下语法的方法:

    EventTarget.delegateEventListener(string event, string toFind, function fn)
    

    我创建了一个相当复杂的 fiddle 来演示它的实际操作,其中我们委托绿色元素的所有事件。停止传播继续起作用,您可以访问应该 event.currentTarget 通过的 this (与 jQuery 一样)。

    以下是完整的解决方案:

    (function(document, EventTarget) {
      var elementProto = window.Element.prototype,
          matchesFn = elementProto.matches;
    
      /* Check various vendor-prefixed versions of Element.matches */
      if(!matchesFn) {
        ['webkit', 'ms', 'moz'].some(function(prefix) {
          var prefixedFn = prefix + 'MatchesSelector';
          if(elementProto.hasOwnProperty(prefixedFn)) {
            matchesFn = elementProto[prefixedFn];
            return true;
          }
        });
      }
    
      /* Traverse DOM from event target up to parent, searching for selector */
      function passedThrough(event, selector, stopAt) {
        var currentNode = event.target;
    
        while(true) {
          if(matchesFn.call(currentNode, selector)) {
            return currentNode;
          }
          else if(currentNode != stopAt && currentNode != document.body) {
            currentNode = currentNode.parentNode;
          }
          else {
            return false;
          }
        }
      }
    
      /* Extend the EventTarget prototype to add a delegateEventListener() event */
      EventTarget.prototype.delegateEventListener = function(eName, toFind, fn) {
        this.addEventListener(eName, function(event) {
          var found = passedThrough(event, toFind, event.currentTarget);
    
          if(found) {
            // Execute the callback with the context set to the found element
            // jQuery goes way further, it even has it's own event object
            fn.call(found, event);
          }
        });
      };
    
    }(window.document, window.EventTarget || window.Element));
    
返回
作者最近主题: