选择相邻兄弟节点而不插入文本节点

时间:2012-06-25 22:01:20

标签: javascript jquery html css

由于悲惨的情况,我收到这样的HTML:

<p>Perform the following commands:
   <code>&gt; cd /foo</code><code>&gt; adb shell</code><code># ps</code>
</p>

我需要使代码看起来像:

Perform the following commands:
> cd /foo
> adb shell
# ps

我认为我会很棘手并使用CSS Adjacent Sibling Selector

code + code:before { content:'\A'; white-space:pre }

...但后来我发现这甚至适用于:

<p>If you go to your <code>C:\</code> directory and run <code>dir</code> …</p>

是否有仅使用CSS的解决方案来选择相邻元素而不介入非元素节点

当且仅当没有时,建议使用JavaScript(包括jQuery)解决方案。

2 个答案:

答案 0 :(得分:4)

这有效:

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

然后在您的CSS中使用.block选择器将display: block和任何其他所需的样式添加到匹配的元素。

演示http://jsfiddle.net/alnitak/JYzGg/

如果你还没有加载jQuery,那么将它编码为纯Javascript将非常容易 - 如果你应该在这些元素上已经有其他类名,jQuery恰好比纯JS更容易添加类。

答案 1 :(得分:1)

虽然我看到你已经接受了答案,但我认为我会提供这个替代方案:

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

JS Fiddle demo

当然,这只会在那些实现previousElementSibling的浏览器上运行(但我认为大多数实现CSS伪元素的浏览器都会实现此功能)。

而且,在纯粹的香草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

因为我更喜欢稍微整理类的方法(而不是在我正在添加的新类之前显式添加空格字符),所以也有这种方法:

function addClass(elem,newClass){
    if (!elem) {
        return false;
    }
    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


编辑以回应Alnitak提出的意见(当我去做一杯茶时,我意识到第二个,我没有考虑过的第一个):

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

参考文献: