我只需要分享“我的”。
虽然在概念上与 Asaph's answer 相同(受益于相同的跨浏览器兼容性,甚至 IE6),但它要小很多,并且在大小非常宝贵和/或当它不需要那么频繁时。
function childOf(/*child node*/c, /*parent node*/p){ //returns boolean
while((c=c.parentNode)&&c!==p);
return !!c;
}
..或单行(只有 64 个字符!):
function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
和jsfiddle here。
用法:
childOf(child, parent) 返回布尔值true|false。
解释:
while 的计算结果只要 while 条件计算为 true。
&& (AND) 运算符返回此布尔值 true/false 评估左侧和右侧,但仅 if 评估左侧是真的(left-hand && right-hand)。
(&&)的左侧是:(c=c.parentNode)。
这将首先将c 的parentNode 分配给c,然后AND 运算符将结果c 评估为布尔值。
由于如果没有父级,parentNode 返回null,并且null 转换为false,因此当没有父级时,while 循环将正确停止。
右侧(&&)是:c!==p。
!== 比较运算符是 'not 完全等于'。因此,如果孩子的父母不是父母(您指定),则评估为true,但如果孩子的父母是父母,则评估为false。
所以 if c!==p 的计算结果为 false,然后 && 运算符返回 false 作为 while 条件并且 while 循环停止。 (注意,不需要 while 正文,需要结束 ; 分号。)
所以当 while 循环结束时,c 在找到父节点时要么是一个节点(不是 null),要么是 null(当循环运行到最后但没有找到匹配项时)。
因此,我们只需将 return 这个事实(转换为布尔值,而不是节点)与:return !!c;:!(NOT 运算符)反转一个布尔值(true 变为 false反之亦然)。
!c 将 c(节点或 null)转换为布尔值,然后才能反转该值。因此,添加第二个 ! (!!c) 会将这个 false back 转换为 true(这就是为什么双精度 !! 通常用于“将任何内容转换为布尔值”)。
额外:
函数的主体/有效负载是如此之小,以至于根据情况(例如它不经常使用并且在代码中只出现一次的情况),一个可以甚至省略该函数(包装)而只使用while循环:
var a=document.getElementById('child'),
b=document.getElementById('parent'),
c;
c=a; while((c=c.parentNode)&&c!==b); //c=!!c;
if(!!c){ //`if(c)` if `c=!!c;` was used after while-loop above
//do stuff
}
代替:
var a=document.getElementById('child'),
b=document.getElementById('parent'),
c;
function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
c=childOf(a, b);
if(c){
//do stuff
}