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

原生 JavaScript 事件委托

Mikkel 2月前

131 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)
  • 委托事件

    当现有或动态元素(将来添加到 DOM 中)收到事件时需要执行某个函数时使用 事件委托
    该策略是将事件监听器分配给已知的 静态父级 并遵循以下 规则

    • 使用 evt.target.closest(\'.dynamic\') 获取所需的动态子项
    • 用于 evt.currentTarget 获取 #staticParent 委托人
    • 用于 evt.target 获取 exact clicked Element (警告!这也可能是后代元素,不一定是那个 .dynamic

    片段示例:

    document.querySelector("#staticParent").addEventListener("click", (evt) => {
    
      const elChild = evt.target.closest(".dynamic");
    
      if ( !elChild ) return; // do nothing.
    
      console.log("Do something with elChild Element here");
    
    });
    

    具有动态元素的完整示例:

    // DOM utility functions:
    
    const el = (sel, par) => (par || document).querySelector(sel);
    const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);
    
    
    // Delegated events
    el("#staticParent").addEventListener("click", (evt) => {
    
      const elDelegator = evt.currentTarget;
      const elChild = evt.target.closest(".dynamicChild");
      const elTarget = evt.target;
    
      console.clear();
      console.log(`Clicked:
        currentTarget: ${elDelegator.tagName}
        target.closest: ${elChild?.tagName}
        target: ${elTarget.tagName}`)
    
      if (!elChild) return; // Do nothing.
    
      // Else, .dynamicChild is clicked! Do something:
      console.log("Yey! .dynamicChild is clicked!")
    });
    
    // Insert child element dynamically
    setTimeout(() => {
      el("#staticParent").append(elNew("article", {
        className: "dynamicChild",
        innerHTML: `Click here!!! I'm added dynamically! <span>Some child icon</span>`
      }))
    }, 1500);
    #staticParent {
      border: 1px solid #aaa;
      padding: 1rem;
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
    }
    
    .dynamicChild {
      background: #eee;
      padding: 1rem;
    }
    
    .dynamicChild span {
      background: gold;
      padding: 0.5rem;
    }
    <section id="staticParent">Click here or...</section>

    直接事件

    或者,你可以在创建时直接在子项上附加一个点击处理程序:

    // DOM utility functions:
    
    const el = (sel, par) => (par || document).querySelector(sel);
    const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);
    
    // Create new comment with Direct events:
    const newComment = (text) => elNew("article", {
      className: "dynamicChild",
      title: "Click me!",
      textContent: text,
      onclick() {
        console.log(`Clicked: ${this.textContent}`);
      },
    });
    
    // 
    el("#add").addEventListener("click", () => {
      el("#staticParent").append(newComment(Date.now()))
    });
    #staticParent {
      border: 1px solid #aaa;
      padding: 1rem;
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
    }
    
    .dynamicChild {
      background: #eee;
      padding: 0.5rem;
    }
    <section id="staticParent"></section>
    <button type="button" id="add">Add new</button>

    资源:

    • 事件.target
    • 元素.closest()
    • 委托事件 jQuery 与 JavaScript
返回
作者最近主题: