如何检测严格相邻的兄弟姐妹

时间:2014-02-13 17:37:21

标签: javascript jquery html dom siblings

考虑以下HTML,其中ID #p1#p2#p3是兄弟姐妹(请参阅fiddle):

<div id="container">
    <span id="p1">Paragraph 1</span>
    <span id="p2">Paragraph 2</span>
    This is just loose text.
    <p id="p3">Paragraph 3</p>
</div>

这些是我对严格和松散的兄弟姐妹的定义:

  • 我认为ID #p1#p2严格的兄弟姐妹(因为没有任何文本没有封装在它们之间的任何类型的html元素中。

  • ID #p2#p3是松散的兄弟姐妹。

鉴于下一个兄弟的任何元素是否可以知道下一个兄弟是严格的还是松散的?

编辑:兄弟姐妹可能属于不同的类型,我更新了小提琴以反映出来。

5 个答案:

答案 0 :(得分:3)

这是你的意思:http://cssdeck.com/labs/0blyuslnzv

var isStrict = function(elem1, elem2) {
    "use strict";

    var e1 = document.querySelectorAll(elem1)[0],
        elemNext = document.querySelectorAll(elem1 +" + "+ elem2)[0];

    if (e1.nextSibling.textContent.trim().length) {
        return e1.nextSibling === elemNext;
    } else {
        return e1.nextElementSibling === elemNext;
    }
};

用法例如。

isStrict("head", "body") => true

isStrict("#p1", "#p2") => true

isStrict("#p2", "#p3") => false

答案 1 :(得分:2)

试试这个。

var $selector = $("#p1");
$selector.siblings().each(function(){
    $(this).addClass('checkSelector');
    if(document.querySelectorAll($selector.selector+' + .checkSelector').length){
        //Do Strict Action
    }else if(document.querySelectorAll($selector.selector+' ~ .checkSelector').length){
        //Do non strict but still sibling action
    }
    $(this).removeClass('checkSelector');
});

http://jsfiddle.net/chsck/5/

答案 2 :(得分:2)

回答你的问题

  

鉴于下一个兄弟的任何元素是否可以知道下一个兄弟是严格的还是松散的?

而不是跟随小提琴的领导,是的,这是可能的。

function isMyNextSiblingStrict(element)
{
    return ("nodeType" in element && element.nodeType === 1 && element.nextSibling !== null && element.nextSibling.nodeType === 1);
}

当元素的下一个兄弟是另一个元素时,这将返回true。但是,请注意您的示例,因为根据您自己的定义它是不正确的,两个跨度在它们之间有一个由空格组成的文本节点,因此#1和#2不是“严格的兄弟”。

<div id="container">
    <span id="p1">Paragraph 1</span><!-- WHITESPACE
 --><span id="p2">Paragraph 2</span>
    This is just loose text.
    <p id="p3">Paragraph 3</p>
</div>

这些将是“严格的兄弟姐妹”。

<div id="container">
    <span id="p1">Paragraph 1</span><span id="p2">Paragraph 2</span>
    This is just loose text.
    <p id="p3">Paragraph 3</p>
</div>

编辑 - 只是为了好玩我已经创建了一个jQuery扩展,它可以做你想要的 - 你可以在更新的jsFiddle中看到它,我没有测试它,但它似乎按你描述的方式工作

$.fn.extend({
    siblingsStrict: function( until, selector ) {
        var ret = jQuery.map( this, function( elem ) {
            var n = ( elem.parentNode || {} ).firstChild,
                r = [],
                contig = false;

        for ( ; n; n = n.nextSibling ) {
                if ( n === elem ) {
                    contig = true;
                }
                else if ( n.nodeType === 1 && n !== elem ) {
                    r.push( n );
                }
                else if ( n.nodeType === 3 && n.textContent.replace(/\s/g, "") === "" ) {
                    continue;
                }
                else if ( n.nodeType === 3 && contig === true ) {
                    break;
                }
                else if ( n.nodeType === 3 && contig === false) {
                    r = [];
                }
        }

        return r;
    }, until );

        if ( name.slice( -5 ) !== "Until" ) {
            selector = until;
        }

        if ( selector && typeof selector === "string" ) {
            ret = jQuery.filter( selector, ret );
        }

        if ( this.length > 1 ) {
            // Remove duplicates
            if ( !guaranteedUnique[ name ] ) {
                ret = jQuery.unique( ret );
            }

            // Reverse order for parents* and prev-derivatives
            if ( rparentsprev.test( name ) ) {
                ret = ret.reverse();
            }
        }

        return this.pushStack( ret );
    }
});

答案 3 :(得分:0)

忽略别人可能写的东西;

function checkAdjacency(element1,element2){
    var result = isLooseOrStrict(element1,element2);
    if(result != 'not'){
        return result;
    }
    else{
        return isLooseOrStrict(element2,element1);    
    }
}

function isLooseOrStrict(elemName1, elemName2){
    var element = document.getElementById(elemName1);
    var element2 =  document.getElementById(elemName2);

    if(element.nextSibling.nodeType != 3){
        if(element.nextSibling == elem2){
            return 'strict';
        }
    }
    else if(element.nextSibling.nextSibling == element2){
        if(element.nextSibling.nodeValue.trim() != '')
            return 'loose';
        else
            return 'strict';
    }
    return 'not';
}

答案 4 :(得分:-1)

你可以使用像bellow

这样的香草来做到这一点

(jsFiddle - &gt; http://jsfiddle.net/Castrolol/chsck/4/

function getSiblings(elem){    
    var siblings = [];
    var actualElem = elem;
    while(actualElem = actualElem.nextSibling ){
        if( !actualElem.textContent.trim() ) continue;
        siblings.push({
            elem: actualElem,
            isStrict: !(actualElem instanceof Text)
        });
    }
    return siblings;
}

//using the function
var element = $("#p1").get(0);
var siblings = getSiblings(element);
siblings.forEach(function(sibling){
    if( sibling.isStrict ) {
        //here is a tag
        sibling.elem.style.color = "red";
    }else{
        //here not is a tag        
    }
});