从零开始学_JavaScript_系列(31)——事件代理/事件委托
来源:互联网 发布:手机变脸软件 编辑:程序博客网 时间:2024/06/04 19:52
(49)事件代理/事件委托
github:
https://github.com/qq20004604/some_demo/tree/master/%E4%BA%8B%E4%BB%B6%E4%BB%A3%E7%90%86
①简单来说,利用事件的捕获-触发-冒泡三阶段的机制,在冒泡阶段,父级(或更高级)结点处理触发事件,而非子节点(事件触发结点)触发事件。
从而避免给每个子节点绑定事件所带来的大量事件问题,(委托往往只需要一个即可)
完全不懂的可以参照链接:
http://www.cnblogs.com/owenChen/archive/2013/02/18/2915521.html
②如代码:
<!DOCTYPE HTML><html><head> <meta charset="UTF-8"> <title>事件代理</title></head><body><ul id="test"> <li>a</li> <li>b</li> <li>c</li> <li>d</li> <li> eeee <span>ffff</span> gg </li></ul><script> function setEvent() { document.querySelector("#test").addEventListener("click", function (evt) { console.log(evt); //这个获取点击事件 console.log(evt.target); //这个是获取触发点击事件的dom,是最底层的DOM(即事件目标) console.log(evt.target.nodeName); //显示HTML标签名 if (evt && evt.target.nodeName === 'LI') { alert("文本内容为:" + evt.target.innerHTML + "的li结点被触发了"); } }) } setEvent();</script></body></html>
③优点:
【1】当dom结构单一时,可以省去大量的绑定事件的问题;
【2】当动态添加、删除子节点时(如上面的li),可以省去绑定、移除子节点的功夫,减少业务复杂度;
④缺点:
【1】DOM结构复杂时,很难满足需求,如上面最后一个li标签,点击span标签范围是不能触发事件的;(我觉得有办法处理,即跟踪其冒泡阶段,但是暂时不知道怎么写)
【2】如果父级DOM下,某些DOM有响应事件,某些DOM没有响应事件,那么需要进行额外的逻辑判断进行处理。
⑤在IE情形下,特别是兼容低版本IE时,不能简单的这么写。
参考链接:
http://www.w3cmark.com/2016/439.html
代码如下:
<!DOCTYPE HTML><html><head> <meta charset="UTF-8"> <title>事件代理</title></head><body><ul id="test"> <li>a</li> <li>b</li> <li>c</li> <li>d</li> <li> eeee <span>ffff</span> gg </li></ul><script> //参数依次为:委托元素,选择器(支持类、id和元素),事件类型,回调函数 function delegateEvent(parentElement, selector, eventType, fn) { if (parentElement.addEventListener) { //普通的,然后触发回调函数 parentElement.addEventListener(eventType, eventfn); } else { //兼容的处理,然后触发回调函数 parentElement.attachEvent("on" + eventType, eventfn); } function eventfn(e) { //事件或者是兼容性处理的window的事件 console.log(e); var e = e || window.event; var target = e.target || e.srcElement; if (matchSelector(target, selector)) { if (fn) { //用call将目标dom作为this指向的对象 fn.call(target, e); } } } } /** * 选择器匹配 * 不支持组合,只支持id、类、html标签名 */ function matchSelector(element, selector) { // 匹配id if (selector.charAt(0) === "#") { return element.id === selector.slice(1); } // 匹配类名 if (selector.charAt(0) === ".") { return (" " + element.className + " ").indexOf(" " + selector.slice(1) + " ") != -1; } // 匹配HTML标签名 return element.tagName.toLowerCase() === selector.toLowerCase(); } //获取父节点 var parentNode = document.getElementById("test"); //调用事件委托函数,父节点作为代理结点,第二个参数是选择器,支持类名、标签名和id(但不能组合),第三个是事件,第四个参数是回调函数 delegateEvent(parentNode, "li", "click", function (e) { console.log(e); console.log(this); alert("1"); })</script></body></html>
0 0
- 从零开始学_JavaScript_系列(31)——事件代理/事件委托
- 从零开始学_JavaScript_系列(32)——事件广播
- 从零开始学_JavaScript_系列(46)——Proxy代理(给对象加壳)
- 从零开始学_JavaScript_系列(九)——dojo(2)(AJAX、时间控件、鼠标事件、样式修改、事件移除、消息发布订阅)
- 从零开始学_JavaScript_系列(30)——NodeList
- 从零开始学_JavaScript_系列(43)——Symbol简述
- 从零开始学_JavaScript_系列(47)——Reflect
- 从零开始学_JavaScript_系列(58)——Thunk函数
- 从零开始学_JavaScript_系列(59)——async函数
- 从零开始学_JavaScript_系列(八)——js系列<2>(事件触发顺序、文本读取、js编写ajax、输入验证、下拉菜单)
- 从零开始学_JavaScript_系列(十一)——dojo(4)(GRID表格进阶:格式化、style、数据获取、多重排序、点击事件)
- 从零开始学_JavaScript_系列(二)——弹框及读取、条件判断、事件处理、注释、图片、超链和div
- 从零开始学_JavaScript_系列(15)——js系列<3>(转为字符串,截取字符串)
- 从零开始学_JavaScript_系列(16)——js系列<5>(正则表达式)
- 从零开始学_JavaScript_系列(19)——js系列<6>闭包
- 从零开始学_JavaScript_系列(三)——CSS相关(基础、选择器、position、div)
- 从零开始学_JavaScript_系列(14)——dojo(7)(饼图,BorderContainer,hashchange,弹窗)
- 从零开始学_JavaScript_系列(17)——dojo(6)(声明一个类declare)
- Android中的调色板功能的实现
- 71. Simplify Path
- emacs注释快捷键
- 四种C#实现播放声音的方法,如DirectX ,SoundPlayer, Windows Media Player
- pandas处理excel数据经验
- 从零开始学_JavaScript_系列(31)——事件代理/事件委托
- 哈夫曼树的实现
- MySQL 字符集与校对规则
- HDU 1269 迷宫城堡 (Tarjan 算法)
- 从此起飞~博客
- (一)开发环境搭建,基本语法,字符串,数组
- Acticle 6:javascript事件:事件的绑定
- 改良版进程管理
- deploy myeclipse j2ee project to server 按了没反应 怎么办