Hi FE !
Ai
git
前端面试题
前端小tip
  • vite
  • webpack
npm
  • vue2
  • vue3
react
GitHub
Ai
git
前端面试题
前端小tip
  • vite
  • webpack
npm
  • vue2
  • vue3
react
GitHub
  • 事件委托类

事件委托类

题目:

2、使用原生js,ul li中的最后一个p标签。 (1) 删除最后一个p标签
(2) 点击任意li标签,打印所在序号。(用直接绑定 和 事件委托) 2种方式

答案:


<ul id="oBox">
    <li>
        <p>1</p>
        <p>2</p>
    </li>
    <li>
        <p>1</p>
        <p>2</p>
    </li>
    <li>
        <p>1</p>
        <p>2</p>
    </li>
</ul>

<script>



let oUl = document.getElementById('oBox');
let oLi = oUl.getElementsByTagName('li');
// 移除最后一个p节点
for(let i = 0; i < oLi.length; i ++) {
  var lastChild = oLi[i].lastElementChild ? oLi[i].lastElementChild : oLi[i].lastChild;
  oLi[i].removeChild(lastChild)
}


// 直接绑定
for(let i = 0;i < oLi.length; i ++) {
  oLi[i].onclick = function() {
      alert(i)
  }
}


// 事件委托
oUl.addEventListener("click",clickHandler);
function clickHandler(e) {
    if(e.target.nodeName.toLowerCase() !== 'li') return;  // 或者写 if(e.target.constructor!==HTMLLIElement) return;
    let arr = Array.from(oUl.children)
    let index = arr.indexOf(e.target);
    alert(index)
}


</script>

优化

如果用户点击的是 li里面的 span,就没法触发 fn,这显然不对。 那下面我们来看一下正确的事件委托应该怎么写:

function delegate(element, eventType, selector, fn) {
     element.addEventListener(eventType, e => {
       let el = e.target
       while (!el.matches(selector)) {
         if (element === el) {
           el = null
           break
         }
         el = el.parentNode
       }
       el && fn.call(el, e, el)
     })
     return element
   }
Edit this page
最近更新: 2025/6/27 02:24
Contributors: qdleader
qdleader
本站总访问量 129823次 | 本站访客数 12人