我正在寻找最绝妙的主意。重点是效率- 让我们尽量避免一堆循环 =)
没有图书馆。这是纯 JS 天才的练习。不过,如果它们实现了这一点,请随意从库中引用函数。无需回退到蹩脚的旧浏览器(即:IE)。
设置
我正在尝试创建事件委托。我将一个事件侦听器绑定到一个容器元素(上下文),用于在该元素中发生的每种事件类型(单击、鼠标输入等)。监听器引用了一个函数,我们称之为“路由”。
有一个单独创建的对象,看起来像这样(示例):
myarr['click']['.myclass'] = functionReference1;
myarr['click']['#myid'] = functionReference2;
myarr['click']['div>a'] = functionReference3;
route
需要(这里event.type
是“点击”)并转到 myarr 并获取所有click
记录。route
然后遍历每个选择器键并将其与event.target
. 如果匹配,则调用函数引用,callback
如果你愿意。
这一切都很好。相当快,直截了当。
问题
event.target
可能是与选择器键匹配的元素的子元素。我正在寻找疯狂平滑的巫术黑魔法来确定该父级是否在我们的上下文元素和event.target
. 最好是一些本机浏览器功能。
理想情况下,例如,我可以按照以下方式做一些事情
context.querySelectorAll(key + " " + event.target);
但显然,据我所知,我不能将对象传递给 querySelectorAll。
尝试了什么
已经尝试了两种方法。两者都有效。两者都不漂亮。
1)
循环遍历 event.target.parentNode 直到找到匹配项。这个手提包做到了,但它在我现有的循环中创建了一个循环。当页面上有多个选择键和大量元素时,开始变得缓慢。
if (event['target'].matchesSelector(key)) {
//do callback
} else {
var et = event['target'];
while (et['parentNode'] !== null and et['parentNode'] !== this) {
et = et['parentNode'];
if (et.matchesSelector(key)) {
//do callback
break;
}
}
}
2)
使用范围。我对此感到相当自豪,但它也有同样的多循环问题。没有过多地测试性能,但是这里发生了很多事情,如果有很多元素匹配选择器键,这可能会影响效率。
if (event['target'].matchesSelector(key)){
//do callback
} else {
var range2 = document.createRange();
range2.selectNode(event.target);
var range = document.createRange();
var allthese = document.querySelectorAll(key)
for (var i = 0; i < allthese.length; i++){
range.selectNode(allthese[i]);
if (range2.compareBoundaryPoints(range2.START_TO_START, range) && range2.compareBoundaryPoints(range2.END_TO_END, range) <= 0){
//do callback
break;
}
}
}
MAGIC VOODOO - 找我一些,当我再次获得代表时,我会创造一个大赏金。