Переносимость nextElementSibling / nextSibling - PullRequest
22 голосов
/ 01 июля 2011

В настоящее время я пишу аккордеон и сталкиваюсь с той же проблемой, которая описана в Разница 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 - то есть элементы TR nthRow ниже исходного TR становятся видимыми (ранее style.display = "none").

Но может ли это иметь неожиданные побочные эффекты?

(Я немного новичок в Javascript;)

Ответы [ 3 ]

28 голосов
/ 01 июля 2011

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;
}
9 голосов
/ 15 ноября 2012

Учитывая предыдущие ответы, в настоящее время я реализую его таким образом, чтобы обеспечить совместимость с различными браузерами:

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));
4 голосов
/ 01 июля 2011

Firefox nextSibling возвращает пробел \ n, а Internet Explorer - нет.

До того, как был представлен nextElementSibling, мы должны были сделать что-то вроде этого:

var element2 = document.getElementById("xxx").nextSibling;
while (element2.nodeType !=1)
{
          element2 = element2.nextSibling;
} 
...