事件监听
JQ JS 写法比较
JQ选择器 可以一次选择多个元素,一次性套用CSS、挂载事件
原生 querySelectorAll 的结果为 NodeList,需要以迴圈方式套用CSS、挂载事件
原生写法 会造成 大量DOM操作而效能不佳,採取事件代理方式可解决 (下见)
JQ click 与 on 差别
click 对于 后续新增的 DOM 无法侦测到
on 则是能够 动态事件绑定,后续新增的 DOM 仍有挂载事件的效果
动态事件绑定实现
利用事件冒泡,类似于事件代理的方式,
子元素被点时,母元素接受到事件而触发事件
.on('触发方式','被点击的选择器')
// JQ写法 // 储存变数,避免用到又要再次寻找存取,亦可统一管理变数 const myBtn = $('#myBtn') myBtn.click(FuncName) myBtn.on('click', FuncName) // 无动态事件绑定效果 $('li span').click(function(){ /* do stuff*/ ); $('li span').on('click',function(){ /* do stuff*/ ); // on 动态事件绑定实现 $('li').on('click','span',function(){ /* do stuff*/ ); // 原生JS写法 const myBtn = document.querySelector('#myBtn') myBtn.addEventListener('click', funcName) const listItems = document.querySelectorAll('.listItem') listItems.forEach((el) => { el.addEventListener('cick', () => { // do stuff }) })
事件代理 delegate
新人笔记: 若有错误欢迎提出勘误,感谢各路大神
事件代理原理:
利用DOM事件传递机制 "冒泡"
子元素 接收到 点击事件事件冒泡 往上至母元素 接受到 点击事件母元素 透过 match 去判断该子元素应该要做甚么行为事件代理好处:
性能优化思想之一 就是减少 DOM 操作,事件代理可使 DOM 交互次数大幅减少减少监听器的数量,节省不少记忆体资源
Ex:列表下多个Item,利用事件代理只需一个,而非每个Item都挂载监听器
避免迴圈挂载监听器,节省 DOM 操作次数
弃用监听器更为方便
SPA页面切换,仅更换内容不换页,监听器因内容置换而用不到,
但仍会占用资源,因此弃用该监听器可节省资源。
使用事件代理,只需要弃用一个监听器即可。
哪些适合事件代理,哪些则否
适合使用事件代理的事件
click , mousedown , mouseup ,
keydown , keyup , keypress
这些不适合
mouseover , mouseout 需要计算位置较不容易把控
mouseenter , mouseleave, focus , blur 则没有冒泡特性
原生 JS 事件代理实现
JQ delegate() 于 3.0版本被弃用 // 原生JS 事件代理 const myList = document.querySelector('.myList') myList.addEventListener('click', clickListItem) function clickListItem(e){ const className = e.target.classList if (className.contains('')) { /* do stuff */} const tagName = e.target.tagName.toLowerCase() if (tagName === 'a') { /* do stuff */ } }
参考资料
JS中的事件委托或是事件代理详解
JQ click 与 on 差异