I have a list and I want to get the first item after each heading item. I need to do this all in one line as im using Nightwatch, which hasnt got all the elasticity of using jquery in the browser. What I have is:
// This works
console.log('first item after first header is ');
console.log($('#ul-wrapper li.heading ~ li:first').text());
// This doesnt
console.log('first item after second header is ');
console.log($('#ul-wrapper li.heading:nth-child(2) ~ li:first').text());
So essentially i need to combine the class selector with nth-child() or eq(). Html is:
<ul id="ul-wrapper">
<li class="heading">
Heading 1
</li>
<li>
<label>
<a>
Item 1
</a>
</label>
</li>
<li>
<label>
<a>
Item 2
</a>
</label>
</li>
<li class="heading">
Heading 2
</li>
<li>
<label>
<a>
Item 3
</a>
</label>
</li>
<li>
<label>
<a>
Item 4
</a>
</label>
</li>
</ul>
The fiddle is here
I have a list and I want to get the first item after each heading item
If I understand right you can use Adjacent sibling selectors
$('#ul-wrapper li.heading + li').css("background", "red");
.heading {
background-color: lightgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ul-wrapper" style="">
<li class="heading">
Heading 1
</li>
<li>
<label>
<a>
Item 1
</a>
</label>
</li>
<li>
<label>
<a>
Item 2
</a>
</label>
</li>
<li class="heading">
Heading 2
</li>
<li>
<label>
<a>
Item 3
</a>
</label>
</li>
<li>
<label>
<a>
Item 4
</a>
</label>
</li>
</ul>
The :nth-child() pseudo class only looks at the index of the element relative to the parent element. Similarly, :nth-of-type() will only look at the index of the element based on the type. Neither the :nth-child()/:nth-of-type() pseudo classes will consider the element's class attribute.
With that being said, the :eq() method will select an element by it's index based on the filtered set (which is exactly what you want in this case). However, it's worth pointing out that :eq() has an index that is zero-based (unlike :nth-child()/:nth-of-type()). In this case, you would need to use eq(1) to access the second li element:
Example Here
$('#ul-wrapper li.heading:eq(1) ~ li:first');
You could also use the adjacent sibling combinator, +:
Example Here
$('#ul-wrapper li.heading:eq(1) + li');
Related
I am restyling a list of related articles in a li and I would like to remove the "-" between the a tag and span without messing with the original content on the page (links). I must use jQuery and I'm not sure if there is a simple way of doing this.
<div class="related-articles card">
<h3 class="h2">
<i class="fa fa-book text-brand-primary-dark"></i> Related Articles
</h3>
<ul>
<li>
Title One
-
<span> Some Related Preview Text... </span>
</li>
<li>
Title Two
-
<span> Some Related Preview Text... </span>
</li>
<li>
Title Three
-
<span> Some RelatedPreview Text... </span>
</li>
</ul>
Here is my solution, get the children elements and assign it back, so the plain text present (-) will get removed!
$('.related-articles li').each(function() {
$(this).html($(this).children());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="related-articles card">
<h3 class="h2">
<i class="fa fa-book text-brand-primary-dark"></i> Related Articles
</h3>
<ul>
<li>
Title One -
<span> Some Related Preview Text... </span>
</li>
<li>
Title Two -
<span> Some Related Preview Text... </span>
</li>
<li>
Title Three -
<span> Some RelatedPreview Text... </span>
</li>
</ul>
One way would be to loop through each <li>, extract the <a> and <span> elements and stitch them together manually, like this:
$("ul > li").each( (i, li) => {
const $li = $(li);
const $a = $li.find("a");
const $span = $li.find("span");
//create a temp element with just the <a> and <span>
const $tempItem = $("<li></li>");
$tempItem.append( $a ).append( $span );
//copy new HTML into old element
$li.html( $tempItem.html () );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
Title One
-
<span> Some Related Preview Text... </span>
</li>
<li>
Title Two
-
<span> Some Related Preview Text... </span>
</li>
<li>
Title Three
-
<span> Some RelatedPreview Text... </span>
</li>
</ul>
One option is:
$('.related-articles li a').map(function() {
return this.nextSibling;
}).remove();
I have a html fragment as follows:
<div id="samplediv">
<ul>
<li name="A">
<a id="A">
</li>
<li name="B">
<a id="B">
</li>
</ul>
</div>
I have a text called:
var text = "B";
I have want to check if the text matches with any of the elements of li and add a class name "disable" for the anchor element not matching with text.
I my case I want to add a class called "disable" for
<a id="A">
This is what I have tried:
$("#samplediv li").each(function() {
if($(this).name != text){
$(this).closest("a").addClass("disabled");
}
});
But the thing here is $(this).name is evaluating to "undefined" . What is it that I am missing?
Edit: Due to typo ,had missed the tag
There are multiple issues,
$(this) returns a jQuery object which does not have name property, instead you can use $(this).attr('name')
.closest() is used to find the ancestor element, but the a is a descendant of the li element, so you need to use find()
You can find all the li elements which does not have the given name and then find the a element within it like
var text = 'B';
$("#samplediv li").not('[name="' + text + '"]').find("a").addClass("disabled");
a.disabled {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="samplediv">
<ul>
<li name="A">
<a id="A">a</a>
</li>
<li name="B">
<a id="B">b</a>
</li>
</ul>
</div>
var text = "B";
$("#samplediv li").filter(function() {//use filter
return $(this).attr('name') != text;//use .attr() to get name attribute
}).find('a').addClass("disabled");//use find to get the anchor tag
.disabled{color:red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="samplediv">
<ul>
<li name="A">
<a id="A">a</a>
</li>
<li name="B">
<a id="B">b</a>
</li>
</ul>
</div>
Use .filter()
Description: Reduce the set of matched elements to those that match the selector or pass the function's test.
I need to acces an element that has a certain style.
This is my structure
<ul>
<li> Hi </li>
<li> bye </li>
<li> third one </li>
</ul>
The list items are placed on top of each other (last one first) and I can dislike something or like something. Once I do that, it gets a style display:none like following:
<ul>
<li> Hi </li>
<li> bye </li>
<li style:"display:none;"> third one </li>
</ul>
Now after I did that I want to be able to acces the last element that does not have display:none, (the bye) how can I do this?
I was thinking of something in the form of:
var myId = $("#slider > ul li").last().attr("id");
But obviously I always get the ID of the item that is hidden since its still there.
Can I do something like select last where !display:hidden ?
Can I do something like select last where !display:hidden ?
Yes, with jQuery's :visible pseudo-class:
var myId = $("#slider > ul li:visible").last().attr("id");
(Note: Your li elements don't actually have id values, but that's a tweak.)
Live Example:
var listItem = $("#slider > ul li:visible").last();
$("<p>")
.text("Text of last visible item: " + listItem.text())
.appendTo(document.body);
<div id="slider">
<ul>
<li>Hi</li>
<li>bye</li>
<li style="display:none;">third one</li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Can use ':visible' selector
var myId = $("#slider > ul li:visible").last().attr("id");
It should work using:
$("#slider > ul li:visible").last().attr("id");
https://api.jquery.com/visible-selector/
so your inline styling is a bit off it should be
<ul>
<li> Hi </li>
<li> bye </li>
<li style="display:none;"> third one </li>
</ul>
You could do a few different things, best is probably just iterate through and check for where display = none, then go to the previous element:
$('ul').children().each(function(e) {
if($(this)[0].style.display == 'none') {
console.log($(this).prev());
}
})
Sizzle does not return all the elements which match the selector. Here is JSBin Demo showing the problem.
HTML
<h4> Playing with Sizzle JS </h4>
<ul class="list">
<li> Item 1 </li>
<li class="row"> Item 2 </li>
<li class="row"> <span>Item 3</span> </li>
<li class="divider">List item with unique class name </li>
</ul>
<ul class="list">
<li> Item 1 </li>
<li class="row"> Item 2 </li>
<li class="row"> <span>Item 3</span> </li>
<li class="divider">List item with unique class name </li>
</ul>
JS
var selector = 'UL.list > LI:eq(1)';
var elements = Sizzle(selector);
console.log(elements.length); //Says 1
My Question is:
Why it returns only 1 element while there are 2 elements which match the selector?
How can I make sizzle to return all matching elements ?
UL.list > LI:eq(1) will only ever return one element: the 2nd element that matches UL.list > LI, as indicated by :eq(1).
If you're looking for all li elements, remove the :eq().
If you're looking for every li that is the second child, use :nth-child():
var elements = Sizzle('UL.list > LI:nth-child(2)');
I need to clone strings, unwrap li, and separate them with commas.
$('ul li div ul li').clone().prependTo('.ins');
<div style="display:none;">
<ul id="path">
<li>
<div class="wr_t">
<ul>
<li>
1
</li>
<li>
2
</li>
<li>
3
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="ins"></div>
I try to add .unwrap('<li></li>') before .clone, but it doesn't work.
I need to output 1,2,3
Here is how I did it on jsfiddle:
http://jsfiddle.net/qeQ6L/
$('.wr_t a').clone().prependTo('.ins').after(',');
You were going about it the wrong way, I targeted the links directly and cloned them before inserting them in .ins