Skip to content Skip to sidebar Skip to footer

Selecting Adjacent Sibling Without Intervening Text Nodes

Due to a sad situation I receive HTML like this:

Perform the following commands: > cd /foo> adb shell<

Solution 1:

This works:

$('code').each(function() {
    var prev = this.previousSibling;
    var next = this.nextSibling;
    if ((prev && prev.tagName === 'CODE') ||
        (next && next.tagName === 'CODE')) {
        $(this).addClass('block');
    }
});​

Then in your CSS use the .block selector to add display: block and any other desired styles to the matched elements.

demo at http://jsfiddle.net/alnitak/JYzGg/

It would be pretty easy to code this as pure Javascript if you don't already have jQuery loaded - jQuery just happens to make adding the class easier than pure JS if you should have other class names already on those elements.

Solution 2:

While I see that you've already accepted an answer, I thought I'd offer this as an alternative:

$('code').each(
    function(){
        if (this.previousSibling == this.previousElementSibling){
            $(this).addClass('block');
        }
        else {
            $(this).addClass('inline');
        }
    });​

JS Fiddle demo.

This will, of course, only run on those browsers that implement previousElementSibling (but I think the majority of browsers that implement the CSS pseudo-elements do implement this feature).

And, in pure vanilla JavaScript:

var codes = document.getElementsByTagName('code');

for (var i=0, len=codes.length; i<len; i++){
    var cur = codes[i];
    codes[i].className = cur.previousSibling == cur.previousElementSibling ? 'block' : 'inline';
}​

JS Fiddle demo.

And because I prefer a slightly tidier approach to adding classes (as opposed to explicitly adding a space-character before the new class I'm adding) there's this approach as well:

functionaddClass(elem,newClass){
    if (!elem) {
        returnfalse;
    }
    else {
        var curClass = elem.className;
        if (curClass.length){
            return curClass + ' ' + newClass;
        }
        else {
            return newClass;
        }
    }
}

var codes = document.getElementsByTagName('code');

for (var i=0, len=codes.length; i<len; i++){
    var cur = codes[i];
    codes[i].className = cur.previousSibling == cur.previousElementSibling ? addClass(cur,'block') : addClass(cur,'inline');
}​

JS Fiddle demo.


Edited in response to the comments raised by Alnitak (the second of which I'd realised as I went to make myself a cup of tea, the first I hadn't considered at all):

var codes = document.getElementsByTagName('code');

for (var i=0, len=codes.length; i<len; i++){
    var cur = codes[i];
    codes[i].className = cur.previousSibling == codes[i-1] || cur.nextSibling == codes[i+1]? addClass(cur,'block') : addClass(cur,'inline');
}​

JS Fiddle demo

References:

Post a Comment for "Selecting Adjacent Sibling Without Intervening Text Nodes"