Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Portability of nextElementSibling/nextSibling

I'm currently writing an accordion and running into the same problem as described in nextSibling difference between IE and FF? - specifically differences between Microsoft's nextSibling / nextElementSibling and that implemented by everyone else.

For various reasons, using jquery is not an option. Nor is getting all my MS users to upgrade to MSIE9

Currently I'm using the following code to work around the problem:

// 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="";
}

Which seems to do what I expect in MSIE6, FF and Chrome - i.e. the nthRow TR elements below the initial TR are made visible (previously style.display="none").

But is this likely to have unexpected side effects?

(I'm a bit of a newbie with Javascript ;)

like image 985
symcbean Avatar asked Jul 01 '11 13:07

symcbean


People also ask

What is nextSibling?

nextSibling returns the next node (an element node, a text node or a comment node). Whitespace between elements are also text nodes. nextElementSibling returns the next element (not text and comment nodes).

How do I get next element in Dom?

The article Whitespace in the DOM contains more information about this behavior. You can use Element. nextElementSibling to obtain the next element skipping any whitespace nodes, other between-element text, or comments.

Which of the following properties returns the node immediately following the specified node in the same tree level?

Definition and Usage The nextSibling property returns the node immediately following the specified node, in the same tree level.


3 Answers

nextSibling will see HTML code comments, so be sure to keep them out.

Other than that you should be alright since you won't have any text nodes between your tr elements.

The only other issue I could think of would be in Firefox 3 where nextElementSibling hadn't yet been implemented. So if you're supporting that browser, you'll need to manually emulate nextElementSibling. (Pretty sure they had it implemented in FF3.5 though.)

You'll be safer to create a nextElementSibling() function:

tr = tr.nextElementSibling || nextElementSibling(tr);

function nextElementSibling( el ) {
    do { el = el.nextSibling } while ( el && el.nodeType !== 1 );
    return el;
}
like image 57
user113716 Avatar answered Oct 02 '22 08:10

user113716


Considering previous answers, I am currently implementing it this way to grant cross-browser compatibilty:

function nextElementSibling(el) {
    if (el.nextElementSibling) return el.nextElementSibling;
    do { el = el.nextSibling } while (el && el.nodeType !== 1);
    return el;
}

This way, I can avoid the do/while loop for browsers that support nextElementSibling. Maybe I'm too scared of WHILE loops in JS :)

One advantage of this solution is recursability:

//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));
like image 29
LittleSweetSeas Avatar answered Oct 02 '22 10:10

LittleSweetSeas


Firefox nextSibling returns whitespace \n while Internet Explorer does not.

Before nextElementSibling was introduced, we had to do something like this:

var element2 = document.getElementById("xxx").nextSibling;
while (element2.nodeType !=1)
{
          element2 = element2.nextSibling;
} 
like image 36
epascarello Avatar answered Oct 02 '22 10:10

epascarello