find next elements but not in order having same class - javascript

I want to find elements which have .item class but they are not in order. Below is sample code.
<ul>
<li class="item">list item 1</li>
<li>list item 2</li>
<li>list item 3</li>
<li class="item">list item 4</li>
<li>list item 5</li>
<li class="item">list item 6</li>
</ul>
I want to traverse each li element having only .item class on key-press event. I have tried .nextAll() getting all elements but it takes much time to produce resultsets as I have huge li elements.
var siblingsElements = $('.item').nextAll(); // Takes much time
How can i achieve the result ? Thanks in advance.

Try to rewrite code with Native JS, it works much faster
var items = $('ul')[0].getElementsByClassName('item');
items = $(items);

You can try
$('li.item').each(function(){
--your code here--
})
Because this will find only li having class "item" instead of all dom elements having class "item" which may speed up your process.

Related

How to use jquery to get to previous li

I have the following html:
<li>
Presentation Name
</li>
<li>
Survey Length
</li>
and here is the jquery:
var yolo = $('.not-allowed').first();
yolo.removeClass("not-allowed");
yolo.prev("li").addClass("active");
The first two lines of javascript are working. For some reason, i can't get the last line to work. I'm trying to have the second li tag have the class active, but the class is just not being added anywhere.
There is no previous element for that link. You want to get the parent of the link:
yolo.parent().addClass("active");
Ref: .parent()
jsFiddle example
Note that you could also use .closest('li') instead of .parent().
You want parent() not prev().
.prev() queries only the siblings of the element, and .not-allowed has none. In order to use .prev() you'd need to call .parent() to get the list item element the anchor is within:
yolo.parent().prev("li").addClass("active");
Edit: I'm an idiot
Have a look at this with the example. I think this answers your question: https://api.jquery.com/prev/
Markup
<ul>
<li>list item 1</li>
<li>list item 2</li>
<li class="third-item">list item 3</li>
<li>list item 4</li>
<li>list item 5</li>
</ul>
JQuery
$( "li.third-item" ).prev().css( "background-color", "red" );
I made a JSFiddle here: https://jsfiddle.net/ToreanJoel/nq6efza9/

jquery select li element in hierarchical menu

I need to be able to get the text from the certain li when it is clicked on, code is below:
<div>
<ul>
<li>list item 1</li>
<li>list item 2</li>
<li>
<ul>
<li>list item 3</li>
<li>list item 4</li>
<li>list item 5</li>
</ul>
</li>
<li>list item 6</li>
<li>
<ul>
<li>list item 7</li>
<li>list item 8</li>
<li>list item 9t</li>
</ul>
</li>
</ul>
</div>
In this case, I need to get the "list item 5" by its index.
Edited:
Basically, when the <li>list item 5</li> is clicked i want to get this particallar text or value, when something else is clicked - do nothing. Note that although the menu is hierarchical, 5th element means flat 5th element. Carefully check the texts of the li items to understand.
$('li').on('click',function(){
alert($(this).text());
});
Working Example
Well, it appears that eq selector is sufficient for your purpose.
$("li:eq(5)").click(function(){
var text = $(this).text();
})
Your best solution is to give that item an id or, at least, a class then you can do:
$("#myID").click(function() {
var text=$(this).text();
});
If you can't do this, then you can try using the various navigation selectors, maybe something like (untested):
$("div>ul>li:nth-child(3)>ul>li:nth-child(3)").click(...
But this is a really awkward way to do it and may break the second you add any more items to your list(s). (here's a fiddle - it'll alert only when your list item 5 is clicked)
Or if the text is static, you could select by that:
$("li:contains('list item 5')").click(...
Which, again, will break if that text changes, or if there are other nodes that contain the same text.
$('ul').on('click', 'li', function() {
console.log($(this).text());
});

jQuery .click() .show() function issues

Could anyone please let me know what i'm doing wrong.
I have:
//My HTML
<div>
<ul>
<li id="test">Main Item 1</li>
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<li>Main Item 2</li>
<li>Main Item 3</li>
</ul>
</div>
//My CSS
.list-in-list {
display:none;
}
//My jQuery
$(document).ready(function() {
$('#test').click(function() {
alert("hello");
});
});
My final goal is to show that none displayed content if you press a list item, so that it expands neatly. However, i can't seem to get that alert() appearing in any way. Should i use an id for all list items in the main list, or is it enough with a class?
/W
you can add .next function to show next ul for any li curreny click by user. you have to change id test to one class name to make effect in all click of main li
HTML would be like
<div>
<ul>
<li class="main">Main Item 1</li>
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<li class="main" >Main Item 2</li>
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<li class="main">Main Item 3</li>
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</ul>
</div>
and JQuery function is below
$(document).ready(function() {
$('.main').click(function() {
$(this).next(".list-in-list").slideToggle();
});
});
for detail you can check link
Should i use an id for all list items in the main list, or is it enough with a class?
IDs are unique. Your JavaScript code will not work properly if you have multiple identical IDs. If you're planning on adding a similar attribute to all of your list items you'd use a class in this case (and reference it with . instead of #). In this case you'd call the click function using:
$('li.myClass').click(...);
If you only have one list, however, you can simply add the ID to the ul and use the click function as:
$('ul#myId > li').click(...);
Note that it would be marginally quicker with the classes in this case.
You'd then reference your inner ul using:
$('li.myClass > ul.list-in-list');
Or, depending on which of the above you went with:
$('ul#myId > li > ul.list-in-list');
(You'd use > here to select only the direct child. If you used ul#myId li you'd also be selecting the li elements which belong to any inner ul)
Your code works fine I do believe you have not included Jquery on your page - or maybe the path to it is not valid. Check your network tab to see if you get an http error retrieving jquery.
You can show the hidden li by doing the following:
$(document).ready(function() {
$('#test').click(function(e) {
$(this).find('.list-in-list').show();
});
});
Your code works fine:
Demo
In this case classes would be better than ids because Id's have to be unique on your page. You can use classes like in the demo below by adding a class to your outer li elements. Just change the binding from #test to whatever class you give your li elements.
$('.clickAbleLi').click(function(e) {
$(this).find('.list-in-list').show();
});
Demo
You close your </li> tag before your "list-in-list". You should close your </li> tag after your inside list ;) Like this :
<div>
<ul>
<li id="test">Main Item 1
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>Main Item 2</li>
<li>Main Item 3</li>
</ul>
</div>
It sholud work but Try moving the ID attribute to the A instead of LI if you experience problems

Find the last child or grandchild in a UL

I have a CMS generating a basic navigation using a UL. Each first-level LI is styled to be a group. I need to apply a style to the last element within each of the first level LI "groups". Meaning; if a first-level LI has no children, I want to apply a style to it (as the "bottom" of the group); if it does have children, I want to find the last child OR grandchild element that appears (again, the "bottom" of the group). I have used both CSS and Javascript "last" classes, and have successfully applied styles to the last child of a certain depth within the first-level LI, but that isn't helpful since the bottom button of the list is of an unknown depth.
My line of thinking involves a IF statement that finds the last child of the first level, checks if it has children, and if it does, go another level deep and find that last child and checks for children, repeating this process until it finds the last LI that does not have children within the first-level LI groups. However, I am a JS noob and am not sure how to go about that.
I am open to CSS or JavaScript/jQuery solutions. I have been banging my head on this one for a while and appreciate any input or better ideas. Thanks for your help!!
--
Update: here's a code sample of what I am hoping for:
<ul id="navigation>
<li>Item one</li> <!--Style this one-->
<li>Item Two
<ul>
<li>Item Two-One</li>
<li>Item Two-Two</li> <!--Style this one-->
</ul>
<li>
<li>Item Three
<ul>
<li>Item Three-One</li>
<li>Item Three-Two
<ul>
<li>Item Three-Two-One</li>
<li>Item Three-Two-One</li> <!--Style this one-->
</ul>
</li>
</ul>
<li>
<li>Item Four
<ul>
<li>Item Four-One</li>
<li>Item Four-Two
<ul>
<li>Item Four-Two-One</li>
<li>Item Four-Two-One</li>
</ul>
</li>
<li>Item Four-Three</li> <!--Style this one-->
</ul>
<li>
</ul>
The reason the .last selector doesn't work is because, in the above example, it would style item Four-Two-One since it is the last element of its UL.
To clean up my answer, incase this is read at a later date.
here is my solution to your problem:
var checkChildren = function($this) {
if (!$this.children().length) {
$this.css({
color: '#f00',
fontWeight: '700',
textDecoration: 'underline'
});
return false;
}
return true;
};
$("#navigation").children("li").each(function() {
$these = $(this);
while (checkChildren($these)) {
$these = $these.children().last() || $these.next();
}
});
I think this is what you want. It's part of the jQuery API.
http://api.jquery.com/last/
HTML
<ul>
<li>list item 1</li>
<li>list item 2</li>
<li>list item 3</li>
<li>list item 4</li>
<li>list item 5</li>
</ul>
jQuery
$('li').last().css('background-color', 'red');
EDIT:
Okay I figured out a way for you to do it.. the only caveat is that you need to be able to set a class for the first level of <li>'s. I've posted my findings here:
http://jsfiddle.net/TTXch/54/
It selects the last of the <li>'s for each main navigation element. Your posted structure was a little off... the end tags didn't all match up. Anyway, check out the jQuery in the javascript window in the jsFiddle.
You should be able to use the jQuery last selector for this (http://api.jquery.com/last-selector/).

Matching classes with jquery

I have two unordered lists, a bit like:
<ul class="list1">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="current">Item 4</li>
<li>Item 5</li>
</ul>
<ul class="list2">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
And the goal is, with jquery, to identify which li is marked with the 'current' class and then add a class to the second list to the corresponding li. I just can't think of how to do this.
Thanks.
$('ul.list2 li:nth-child(' + $('ul.list1 li.current').index() + ')').addClass('current');
Or you could make it a little less icky:
$('ul.list2 li').eq($('ul.list1 li.current').index()).addClass('current');
The second one, I like better, now that I get to see them both :-) The tricks here are:
the "eq" filter lets you pick an element from a jQuery list based on an index;
the "index" function lets you find the index of an element relative to its siblings in the DOM
Just simply use this:
var initialIndex = $('.list1 .current').index();
$('.list2 li').eq(initialIndex).addClass('current');
// Find the current item in the first list, remember its text
var textToMatch = $('ul.list1 li.current').text();
// Loop through each li in the second list
$('ul.list2 li').each(function(index, domElement){
var curr = $(domElement);
// if the text matchs the first then add our class
if(textToMatch == curr.text()){
curr.addClass('NEWCLASS');
}
});
EDIT1:This is answering the wrong question, the question has since been clarified I will leave this here as it still seems nice :)
EDIT2: as Per Flex, this is a nicer way to achive the same thing, again not what the question was after.
$('.list2 li:contains("' + // Find an li in list2 which contains
$('.list1 li.current').text() + '")') // the same text as the as the current li in list1
.addClass("NEWCLASS"); // and add our new class to it
$('li.current + li').addClass('yourClass')
edit: misunderstanding of the question
var index = $.inArray($('li.current')[0],$('li.current').parent().children());
$('ul:eq(1) li:eq('+index+')').addClass('selected');

Categories