我在jsPerf 测试中添加了两个测试。两者都使用previousElementSibling
,但第二个包含 IE8 及更低版本的兼容性代码。
它们在现代浏览器(这是当今使用的大多数浏览器)中都表现得非常好,但在旧浏览器中会受到一点影响。
这是第一个不包含兼容性修复程序的。它适用于 IE9 及更高版本,以及几乎所有的 Firefox、Chrome 和 Safari。
function findRow6(node) {
var i = 1;
while (node = node.previousElementSibling)
++i;
return i;
}
这是具有兼容性修复的版本。
function findRow7(node) {
var i = 1,
prev;
while (true)
if (prev = node.previousElementSibling) {
node = prev;
++i;
} else if (node = node.previousSibling) {
if (node.nodeType === 1) {
++i;
}
} else break;
return i;
}
因为它会自动抓取元素兄弟姐妹,所以不需要对 进行测试nodeType
,并且整个循环更短。这解释了性能的大幅提升。
我还添加了一个循环的最后一个版本,.children
并将 与node
每个版本进行比较。
这不如previousElementSibling
版本快,但仍然比其他版本快(至少在 Firefox 中)。
function findRow8(node) {
var children = node.parentNode.children,
i = 0,
len = children.length;
for( ; i < len && children[i] !== node; i++)
; // <-- empty statement
return i === len ? -1 : i;
}
回到previousElementSibling
版本,这里有一个可能会稍微提高性能的调整。
function findRow9(node) {
var i = 1,
prev = node.previousElementSibling;
if (prev) {
do ++i;
while (prev = prev.previousElementSibling);
} else {
while (node = node.previousSibling) {
if (node.nodeType === 1) {
++i;
}
}
}
return i;
}
我还没有在 jsPerf 中对其进行测试,但是previouselementSibling
我认为根据 a 的存在将它分成两个不同的循环只会有帮助。
也许我会稍微补充一下。
我继续并将其添加到此答案顶部链接的测试中。它确实有一点帮助,所以我认为这可能是值得的。