javascript 跨浏览器的事件系统4
上次说到我们在无菌环境中设计了一个事件代理函数,但性能是个问题,解决它我们需要缓存节点集合,发现节点集合不足以应对新情况时,再替换这个节点集合,重新开始匹配。下面是新的方案:
var delegate = function(selector,type,callback){ var els = $(selector); addEvent(document,type,function(e){ var flag = true; var node = e.srcElement || e.target; for(var i=0,el;el = els[i++];){ if(node === el){ flag = false; return callback.call(node,e); } } if(flag){ els = $(selector); for(var i=0,el;el = els[i++];){ if(node === el){ return callback.call(node,e); } } } },true); } |
好了,我们现在来考虑另一种情况。之前我们的判定都是用全等于来比较,但如果事件源是来自更底层的元素呢?换言之,是下面的情况。
< div onclick="alert('outer')" id="outer"> < div onclick="alert('middle')" id="middle"> < div onclick="alert('inner')" id="inner"></ div > </ div > </ div > |
当我们点击inner元素时,它上面的middle与outer的onclick也触发,因此我们必须引入包含判定了。这里我直接给出答案,具体可见我的这一篇博文。
var contains = function (el, root) { if (el.compareDocumentPosition) return (el.compareDocumentPosition(root) & 8) === 8; if (root.contains && el.nodeType === 1){ return root.contains(el) && root !== el; } while ((el = el.parentNode)) if (el === root) return true ; return false ; } var delegate = function (selector,type,callback){ var els = $(selector); addEvent(document,type, function (e){ var flag = true ; var src = e.srcElement || e.target; for ( var i=0,el;el = els[i++];){ if (el === src || contains(src,el) ){ flag = false ; return callback.call(el,e); } } if (flag){ els = $(selector); for ( var i=0,el;el = els[i++];){ if (el === src || contains(src,el) ){ return callback.call(el,e); } } } }, true ); } |
我们再把筛选事件源的逻辑独立出来,就变成下面这个样子。是时候考虑如第一部分设计的事件系统衔接起来了!
var handle = function (e,obj){ var flag = true , src = e.srcElement || e.target, els = obj.nodes; for ( var i=0,el;el = els[i++];){ if (el === src || contains(src,el) ){ flag = false ; return obj.callback.call(el,e); } } if (flag){ els = obj.nodes = $(obj.selector); for ( var i=0,el;el = els[i++];){ if (el === src || contains(src,el) ){ return obj.callback.call(el,e); } } } } var delegate = function (selector,type,callback){ var handleObj = {}; handleObj.callback = callback; handleObj.selector = selector; handleObj.nodes = $(selector); addEvent(document,type, function (e){ handle(e,handleObj) }, true ); } |
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?