Choosing <p> elements that don't have text nodes in jQuery
I have this HTML structure:
<div class="article-body"> <p> <a href="http://www.example.com">My Link</a> Lorem Ipsum Dolor Sit amet. </p> <p><a href="http://www.example.com">Link that I must select.</a></p> </div> and I have to apply the class to the second link, without text nodes. I tried "p: empty a" and "p> a: only-child", but they do not work ... Is there a way to select it using jQuery?
Cannot be done with a selector, but you can use filter() to make a custom selection:
$('p').filter(function(){ var $clone = $(this).clone(); $clone.children().remove(); return !$clone.text(); }).addClass("red"); There is a fiddle here: http://jsfiddle.net/adrianonantua/5daYT/
:)
Update
According to @dfsq's suggestion, we can use end() and do the same logic in one line:
$('p').filter(function(){ return !$(this).clone().children().remove().end().text(); }).addClass("red"); It will be a very quick decision. No cloning needed:
$("p > a").filter(function(i, el) { return !el.previousSibling && !el.nextSibling; }).parent(); Or that:
$("p").filter(function(i, el) { return el.firstChild && el.firstChild === el.lastChild && el.firstChild.nodeName.toUpperCase() === "A"; }); This should work http://jsfiddle.net/nvass/ :
$("p").filter(function(){ return $.grep(this.childNodes,function(node){ return node.nodeType === 3 && node.nodeValue.replace(/(\s|\n|\r|\t)/g,"") !== ""; }).length === 0; }).css("background-color","green"); Or you can use a single line: $("p").filter(function(){ return $(this).clone().children().remove().end().text() == ""; });
Demo: http://jsfiddle.net/bJnEJ/1/
Source (adapted): http://viralpatel.net/blogs/jquery-get-text-element-without-child-element/