Я просто должен был поделиться «моим».
Хотя концептуально тот же ответ, что и у Асафа (благодаря той же кросс-браузерной совместимости, даже с 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 здесь .
Использование:
childOf(child, parent)
возвращает логическое значениеtrue
| false
,
Объяснение:
while
оценивает, пока выполняется условие whiletrue
.
Оператор&&
(AND) возвращает это логическое значение true / false после оценки левой и правой частей, но только если левая часть была истинной ( left-hand && right-hand
) .
Левая сторона (из &&
) имеет вид : (c=c.parentNode)
.
Это первый будет назначить parentNode
из c
к , c
а затем оператор И будет оценивать полученный c
как логическое значение.
Поскольку parentNode
возвращается, null
если родительского элемента не осталось, и null
преобразуется в false
, цикл while будет корректно останавливаться, когда родительских элементов больше нет.
Правая (из &&
) имеет вид : c!==p
.
Оператор !==
сравнения « не совсем равен». Поэтому, если родитель ребенка не является родителем (вы указали), он оценивает его true
, но если родитель ребенка является родителем, то он оценивает его false
.
Таким образом, если значение c!==p
равно false, &&
оператор возвращается false
как условие while, и цикл while останавливается. (Обратите внимание, что в теле while нет необходимости, и ;
требуется точка с запятой.)
Таким образом, когда цикл while завершается, c
это либо узел (не null
), когда он нашел родителя, ИЛИ null
(если цикл прошел до конца, не найдя соответствия).
Таким образом , мы просто return
тот факт (конвертируется в логическое значение, вместо узла) с: return !!c;
: от !
( NOT
оператор) инвертирует логическое значение ( true
становится false
и наоборот).
!c
преобразует c
(узел или ноль) в логическое значение, прежде чем оно сможет инвертировать это значение. Таким образом, добавление second !
( !!c
) преобразует это ложное значение обратно в истинное (именно поэтому двойник !!
часто используется для «преобразования чего-либо в логическое значение»).
Дополнительно:
тело / полезная нагрузка функции настолько малы, что в зависимости от случая (например, когда она используется не часто и появляется в коде только один раз), можно даже опустить функцию (обтекание) и просто использовать цикл 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
}