Я просто должен был поделиться «моим».
Хотя концептуально тот же ответ, что и у Асафа (благодаря той же кросс-браузерной совместимости, даже с 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
}