Переносимость nextElementSibling/nextSibling
В настоящее время я пишу аккордеон и сталкиваюсь с той же проблемой, как описано в nextSibling разница между IE и FF? - в частности, различия между Microsoft nextSibling/nextElementSibling и реализованный всеми остальными.
По разным причинам использование jquery не является опцией. Также не все мои пользователи MS обновлены до MSIE9
В настоящее время я использую следующий код для решения проблемы:
// tr is a TR doc element at entry....
while (nthRow--) {
// for Chrome, FF tr=tr.nextElementSibling; for MSIE...tr=tr.nextSibling;
tr=tr.nextElementSibling ? tr.nextElementSibling : tr=tr.nextSibling;
if (!tr || tr.nodeName != "TR") {
break;
}
tr.style.display="";
}
Кажется, что я делаю то, что ожидаю в MSIE6, FF и Chrome, т.е. элементы nthRow TR ниже начального TR становятся видимыми (ранее style.display = "none" ).
Но может ли это иметь неожиданные побочные эффекты?
(Я немного новичок с Javascript;)
Ответы
Ответ 1
nextSibling
будет видеть комментарии HTML-кода, поэтому не забудьте оставить их.
Кроме этого вы должны быть в порядке, поскольку у вас не будет текстовых узлов между вашими элементами tr
.
Единственная проблема, о которой я мог думать, была бы в Firefox 3
, где nextElementSibling
еще не была реализована. Поэтому, если вы поддерживаете этот браузер, вам нужно вручную подражать nextElementSibling
. (Понятно, что они реализовали его в FF3.5, хотя.)
Вам будет безопаснее создать функцию nextElementSibling()
:
tr = tr.nextElementSibling || nextElementSibling(tr);
function nextElementSibling( el ) {
do { el = el.nextSibling } while ( el && el.nodeType !== 1 );
return el;
}
Ответ 2
Учитывая предыдущие ответы, я в настоящее время реализую его таким образом, чтобы обеспечить совместимость с несколькими браузерами:
function nextElementSibling(el) {
if (el.nextElementSibling) return el.nextElementSibling;
do { el = el.nextSibling } while (el && el.nodeType !== 1);
return el;
}
Таким образом, я могу избежать цикла do/while для браузеров, поддерживающих nextElementSibling.
Может быть, я слишком боюсь циклов WHILE в JS:)
Одним из преимуществ этого решения является рекурсивность:
//this will always works:
var e = nextElementSibling(nextElementSibling(this));
//this will crash on IE, as looking for a property of an undefined obj:
var e = this.nextElementSibling.nextElementSibling || nextElementSibling(nextElementSibling(this));
Ответ 3
Firefox nextSibling возвращает whitespace\n, в то время как Internet Explorer этого не делает.
Перед тем, как был введен следующий элементElementSibling, нам нужно было сделать что-то вроде этого:
var element2 = document.getElementById("xxx").nextSibling;
while (element2.nodeType !=1)
{
element2 = element2.nextSibling;
}