2014-02-13 4 views
5

Рассмотрим следующий HTML, где идентификаторы #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 быть свободными братьями и сестрами.

Для любого элемента со следующим родным братом можно узнать, является ли следующий брат строгим или свободным?

Редактировать: Братья, сестры могут быть другого типа, и я обновил скрипку, чтобы отразить это.

+0

Вы хотите сделать что-то с CSS2 селекторы '~' и '+' http://www.quirksmode.org/css/selectors/#t11 –

+0

Я бы сказал, что лучше терминология была бы «соседние элементы «или« смежные элементы », поскольку все они являются строго родственными братьями, один - это только текстовый узел, а не узел элемента. – Klors

ответ

2

Отвечая на Ваш вопрос

Given any element with a next sibling is it possible to know if the next sibling is strict or loose?

, а не следуя ваш пример от скрипки, да, это возможно.

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); 
    } 
}); 
+0

_ Однако будьте осторожны с вашим примером, поскольку это неверно по вашему собственному определению. - В то время, когда я ездил на работу сегодня утром, я думал: «Я наскричаю» в моем вопросе ... », но с радостью кто-то проснулся достаточно, чтобы заметить это. . :-) Я рассмотрю и протестирую все ответы и выберет один из них позже. – Fabricio

+0

Я тестировал ваше первое решение и получил консольную ошибку: Firefox говорит 'TypeError: invalid 'в' operand element', Opera говорит' Uncaught exception: TypeError: Operator 'in' применяется к не-объекту' и Chrome также gags: ' Uncaught TypeError: Невозможно использовать оператор 'in' для поиска 'nodeType' в # p1'. См. [Fiddle](). Любая идея о том, что происходит? – Fabricio

+0

Я не уверен, и, к сожалению, я не вижу вашей скрипки, вот скрипка http://jsfiddle.net/chsck/12/ – Klors

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

вы можете сделать это, используя только ваниль, как пыльник

(jsFiddle ->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   
    } 
}); 
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/

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'; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^