2013-06-20 10 views
1
<p id='1'></p> 
<p id='1a'><br /></p> 
<p id='3success'><b>Match this</b></p> 
<p id='3fail'><b>Match this</b> but not now because of this test</p> 

У меня есть какая-то логика, которая должна пропускать элементы, которые удовлетворяют следующим условиямПроверьте пункт имеет только дочерние элементы не текст

  1. Нет HTML
  2. только уш или NBSP
  3. только имеет ребенка элементы определенного типа (b, i, img)

Я могу легко справиться с 1/2, но с третьим я столкнулся с проблемой. Я знаю, как утверждать часть детей, $('#3fail').children().length, но я не знаю, как определить, есть ли дополнительный текст.

Любые предложения о том, как проверить 3? Я обработки элемента в простом .each функции

$('p').each(function(){ 
    var element = $(this) 
    if(matchesCondition(element)){ 
     doLogic(element) 
    } 
}); 

Примечание

Кто-то отправил ответ и получил много upvotes, но он не работает. Вот скрипка для проверки ответов.

http://jsfiddle.net/ncapito/k87rc/

я смог исправить @Kolink сек ответ

http://jsfiddle.net/ncapito/9D3tg/

var getNontextNodes; 
//coffeescript generated 
getNontextNodes = function (nodes) { 
    var cnt, n, _i, _len; 
    cnt = 0; 
    for (_i = 0, _len = nodes.length; _i < _len; _i++) { 
    n = nodes[_i]; 
    if (n.textContent.trim()) { 
     cnt++; 
    } 
    } 
    return cnt; 
}; 

$("p").each(function() { 
    if (
    (this.children.length === this.childNodes.length) 
    || 
    (getNontextNodes(this.childNodes) === this.children.length)) 
     $(this).append("<b style='color:green'>Success</b>"); 
    else 
    $(this).append("<b style='color:red'>Failed</b>"); 
}); 

ответ

6

Вы можете проверить, если элемент имеет только элемент детей, проверяя
if(this.children.length == this.childNodes.length), потому что children[] только подсчетов , а childNodes[] также содержит текстовые узлы.

После того как вы очистили этот шаг, вы можете выполнить итерацию через массив children[] и проверить их tagName, чтобы узнать, находятся ли они в вашем списке.

EDIT: Я только что заметил, это не позволит пропускать пробелы, такие как новые строки, между элементами. Если вы хотите, чтобы пробелы, но не сам текст, попробуйте этот чек вместо:
if(!(this.textContent || this.innerText).match(/\S/))

Нет, это не будет работать. Это, хотя:

var filter = [].filter ? [].filter : function(cb) {for(var i=0, l=this.length, ret=[]; i<l; i++) {if(cb(this[i])) ret.push(this[i]);} return ret;}; 
$("p").each(function(){ 
    if(this.children.length == this.childNodes.length || filter.call(this.childNodes,function(n) {return n.nodeType == 3 && n.nodeValue.match(/\S/);}).length == 0) 
     $(this).append("<b style='color:green'>Success</b>") 
    else 
     $(this).append("<b style='color:red'>Failed</b>") 
}); 

Demo

+0

другой способ будет непосредственно использовать свойство childElementCount – gaspyr

+0

Много вещей, и все же люди всегда удивляются ... Рад, что смог помочь! –

+1

@gaspyr Это [устарело] (https://developer.mozilla.org/en-US/docs/Web/API/Element.childElementCount). –