Suppose I have such a structure:
<div id="content">
<div>
<span>
<b>
<i>
<u>
<span>Price</span>
</u>
</i>
</b>
</span>
</div>
</div>
In this case, the number of tags inside the div #content and which ones they don't know me. I only have access to the id content.
How do I get the selector to the latest span which contains the text Price?
p.s. lastChild method returns the last child within the selected selector, but not deeper!
Select all children of #content using * selector and use .filter() to filtering element. In callback filter elements hasn't any child.
$("#content *").filter(function(){
return $("*", this).length == 0;
});
// Or using ES6
$("#content *").filter((i,v) => $("*", v).length == 0);
var ele = $("#content *").filter((i,v) => $("*", v).length == 0);
console.log(ele[0].outerHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
<div>
<span>
<b>
<i>
<u>
<span>Price</span>
</u>
</i>
</b>
</span>
</div>
</div>
You can use .find():
https://api.jquery.com/find/
This will recursively look for your selector, so:
$('#content').find('span') will give you two spans, one for the first nested span and one for the second nested span. The downside is that if you have multiple spans you'll need to find the right one.
If you can put an identifier in the last one, say a class named 'target-class', than you know you'll find the right one:
$('#content').find('span.target-class');
First of all let's fix your syntax. You can't put an <span> directly within a <u>. You need a <li> node. Also you can't/shouldn't put block elements such as ul within inline elements (span, a, b, i...). And even <b> and <i> are not recommended, better use semantic markup such as <strong> or <em> instead.
Now your problem. I think you don't have to care about being the last node. If you know the text contained is "Price" you can look for it in the following way:
var selector = $('#content').find(":contains('Price')");
$(selector).addClass('highlighted');
.highlighted {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
<div>
<u>
<li>
<span>Price</span>
</li>
</u>
</div>
</div>
If this solution does not fits your needs, to get the last node you have to get all of them an check if they have children or not. Once they don't, you've reached your target.
But I have to say that this is a solution you could have found in SO.
Select deepest child in jQuery
Jquery Way -
You could target all spans $() and target the latest span using slice() method.
$('#content span').slice(-1)[0];
Javascript way -
Find all spans using querySelectorAll(), You'd get a NodeArray, you can convert it to Array using Array.from() and slice() last item from it which is latest span.
Array.from(document.querySelectorAll('#content span')).slice(-1)[0]
Related
i am trying to get li tag text value using js but i am not getting the expected output
i.e ("Pens").
I have added a code snippet.
Note - I cannot change html.
console.log(jQuery('#accordionItem li span').html());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="accordionItem" class="filter_middle-stage2-list_wrapper">
<li style="font-weight: bold;">Pens<span>(1200)</span></li>
</div>
Any thoughts on this ?
Use the text method like below:
console.log($('#accordionItem li span').text());
from what I understand you want the text of the li without the text of the span.
So you can use the replace function to do it like so:
console.log($('#accordionItem li').text().replace($('#accordionItem li span').text(), ''));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="accordionItem" class="filter_middle-stage2-list_wrapper">
<li style="font-weight: bold;">Pens<span>(1200)</span></li>
</div>
if you want a more general solution that will get you just the text of the li without any of its children that would be a better solution:
console.log($('#accordionItem li').contents().get(0).nodeValue);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="accordionItem" class="filter_middle-stage2-list_wrapper">
<li style="font-weight: bold;">Pens<span>(1200)</span></li>
</div>
You seem to be selecting the <span> tag on your jQuery selector.
Although I'd suggest using the text method to achieve what you are looking for.
No jQuery needed.
Since you have an element with ID, you can access it directly, and get the node's text and simply remove any non-digit characters, and you'll be left with the numeral value you are after.
The benefit of this method is the irrelevance of the DOM structure - it will always work for that element (with that ID), but can be applied to any <li> element, regardless if it has a <span> child (or any other children)
console.log(
accordionItem.children[0].firstChild.textContent
)
<div id="accordionItem" class="filter_middle-stage2-list_wrapper">
<li style="font-weight: bold;">Pens<span>(1200)</span></li>
</div>
I'm having some problems figuring out how to use the :not selector correctly.
I have a menu which contains menuitems, where one menu-item has an "is-selected"class to show the user what the current page is that he is visiting.
I would like to retrieve the text of this item, without the badge.
Div Structure
<div class="a-TreeView-content is-selected is-current--top">
<a class="a-TreeView-label">
Orderinvoer
<span class="cb-Menu-badge">25</span>
</a>
</div>
And the following code:
var activeMenuItem = $('div.a-TreeView-content.is-selected > a').text();
Which returns something like: "Orderinvoer25"
I've tried the following to retrieve only the text 'Orderinvoer' but I don't really know what I'm doing wrong:
$('div.a-TreeView-content.is-selected > a span:not(".cb-Menu-badge")').text()
$('div.a-TreeView-content.is-selected > a :not(span)').text()
$('div.a-TreeView-content.is-selected > a:not(".cb-Menu-badge")').text()
$('div.a-TreeView-content.is-selected :not(".cb-Menu-badge")').text()
You can use replace() to remove the .cb-Menu-badge text and trim() to remove extra space.
Stack Snippet
var activeMenuItem = $('div.a-TreeView-content.is-selected > a').text().replace($('.cb-Menu-badge').text(), '').trim();
console.log(activeMenuItem);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a-TreeView-content is-selected is-current--top">
<a class="a-TreeView-label">
Orderinvoer
<span class="cb-Menu-badge">25</span>
</a>
</div>
Try this
$('div.a-TreeView-content.is-selected > a')
.clone()
.children()
.remove()
.end()
.text();
FIDDLE HERE
.clone() clones the selected element.
.children() selects the children from the cloned element
.remove() removes the previously selected children
.end() selects the selected element again
.text() gets the text from the element without children
Pick the first text node in .is-selected a.
$(".is-selected a").contents().get(0).nodeValue
var selected = $(".is-selected a").contents().get(0).nodeValue;
console.log(selected);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a-TreeView-content is-selected is-current--top">
<a class="a-TreeView-label">
Orderinvoer
<span class="cb-Menu-badge">25</span>
</a>
</div>
By using :not() selector, you are trying to select an anchor tag which is not a span type or not having cb-Menu-badge class. So, it always select the anchor tag and gives you the text it has inside. You can be leaving the span inside the anchor tag by selecting its first content alone as follows. Read more about contents()
$($('div.a-TreeView-content.is-selected > a').contents()[0]).text();
The above link has lot more examples which will help you if you have your text inside like 'text1<span>text2'
I have a small group of items as shown below.
<div class="item">
<div class="date">2013-08-08</div>
<div class="headline"><a data="normal" href="#">Title</a></div>
</div>
<div class="item">
<div class="date">2013-10-08</div>
<div class="headline"><a data="special" href="#">Title</a></div>
</div>
If the title has a data attribute of special, I want to make the date bold for that item only.
I have the below code to try and do this.
<script>
if ($(".headline a [data='special']")){
$( ".date" ).wrap( "<b></b>" );
}
</script>
However this makes all items bold if the condition is true.
I am familiar with using this in JS but not sure how to relate it to another div above.
What is the best way to do this?
I am happy to change the html structure if required as well.
Try the following:
$(".headline a[data='special']").parent().siblings(".date").wrap("<b></b>");
The parent() function will select the div.headline for a matching <a> tag; then, siblings(".date") will select children of the parent of div.headline (which are called siblings) that have the date class.
It sounds like you'd like to select the .date element in .item elements which contain .headline a[data="special"] elements.
$('.item:has(.headline a[data="special"]) .date')
will select the correct .date elements for my given assumptions, you can then call .wrap('<b></b>').
Also note: [data] is not a valid [data-*] attribute. You must have a hyphen and a name for custom data attributes.
I have a bunch of child elements that are uniquely identified within a parent div. I want to know if there's a way in jQuery (or javascript) to capture all of them? The number of children in the parent div is arbitrary, meaning it could be any number for each div. For example:
<div class="parent1">
<span class="child1">some text here</span>
<span class="child2">some other text</span>
...
<span class="child49">yet more text</span>
<span class="something_else">other text i don't want to select</span>
</div>
<div class="parent2">
<span class="child1">some text</span>
<span class="child2">some text</span>
...
<span class="child120">some text</span>
</div>
So considering the above example, how do I get ALL the children (.child1 through .child49) within the class parent1?
I know that doing the following will work in jQuery (using multiple selector):
$(".child1, .child2, ..., .child49").css("background","red");
But is there a better way? I won't always know how many children are in each parent.
EDIT: also, I might have other children in the parent with a different class name that I DO NOT want to select; I specifically want to select all the "child*" classes.
$('.parent1 span[class^="child"]')
will select all the spans that start with the class child under the class .parent1.
If you want all the span.childX under all parentX then use:
$('div[class^="parent"] span[class^="child"]')
This is using a CSS3 attribute selector which jQuery have implemented (and extended in some cases). From the documentation:
E[foo^="bar"] an E element whose "foo" attribute value begins exactly with the string "bar"
These codes gets all child in div.parent1 and div.parent2
$('[class^="parent"] span').css({ });
$('[class^="parent"]').children().css({ });
Thess codes gets onli the children for parent 1
$('.parent1 span').css...
$('.parent1').children().css...
use .children along with .filter, if number of children are not certain then label all childs which you want to manipulate of parent1 as child1
$(".parent1").children().filter(".child1").css({color:'Red'});
here is the fiddle http://jsfiddle.net/8hUqV/1/
jquery children
I want to know how to get access of this [span class="myclass"] in below html structure..
<ul>
<li class="first">
<span class="myclass"></span>
<div class="xx">
<span></span>
........
</div>
<li >
<span class="myclass"></span>
<div class="xx">
<span></span>
........
</div>
</ul>
Here I need to write one function in [span class="myclass"], but i cant do it using $(".myclass") [I have few issues] I just want to directly access the span itself.How to do this..?
EDIT:the sln by phoenix is working fine..but lets say(just for my knowledge) the structure is
<li >
<span class="myclass"></span>
<div class="xx">
<li>
<span></span>
</li>
........
</div>
</ul>
so why the span inside 2 nd li(which is under div) is not getting the ref, is it bcoz they are not in the same level..if I need to access them do I need to do some thing like
enter code here
$("li").next(".xx").find(li span:first-child )..or something else is there?
Thanks.
$("li span.myclass")
EDIT: Okay then maybe with
$("li span:first") //EDIT: Don't do that. See below.
apparently :first stops after the first hit. So :first-child is the way to go.
which will select the first span in every li-element. But this can be tricky in case you have other li-elements with spans inside...
EDIT: If you can't use the class you already have, maybe assigning an additional class helps?
<span class="myclass newClass"></span>
...
var spans = $("li span.newClass");
EDIT:
As phoenix pointed out
$("li span:first-child")
returns a list with all span elements that are the first child of a li-element. I don't know if jQuery treats textnodes as child nodes. So if you have a space between <li> and <span>, this might be counted as the first-child. So check if you have any whitespace between your elements beside line breaks.
If span is the first child then you can use
first-child
selector
$("li span:first-child");