jQuery counter and adding a class but not to the first two? - javascript

I'm checking list items I have and if there are more than two then I add a class. This works fine but I want the class to start adding after the first two list items. I am not sure how to do that part that excludes adding the class to the first two. Here is my code:
$(document).ready(function() {
//Checking how many time the class appears
var numItems = $('ul.singleMagazine li').length;
if (numItems > 2) {
alert(numItems);
//Want to add this class but not to the first two - exclude first two list items and then add it to the rest. How to do it?
$('ul.singleMagazine li').addClass("newClass");
}
});
How I would do the excluding part?

The li elements should be siblings, so you can use the gt() selector:
$('ul.singleMagazine li:gt(1)').addClass("newClass");
Also note that the length check is redundant as if there's less than two items the above won't do anything anyway.

You can use gt selector. https://api.jquery.com/gt-selector/
$('ul.singleMagazine li:gt(1)').addClass("newClass");
This will add the class only to the li's which are greater than 1. Note here that the indexing starts from 0.

Related

jQuery select all classes except one ID

I need to select all divs of a certain class (jqx-slider) excluding one ID (#str_prg) - something like:
$("div.jqx-slider :not(#str_prg)").each(function () {
.....
});
What is the correct syntax for that?
Also, would it be faster and more effecient code, if I add a "if" condition inside the loop - like
if($(this).attr('id') ! = "str_prg"){
}
Thanks!
You are using an descendant selector between the class selector and the not selector, which is invalid for your requirement
$("div.jqx-slider:not(#str_prg)")
when you say $("div.jqx-slider :not(#str_prg)") it selects all descendants of elements with class jq-slider except the one with id str_prg
Try to remove an unnecessary space char like this:
$("div.jqx-slider:not(#str_prg)")
Remove the space, as it would cause you to select children, instead of the element itself.
$("div.jqx-slider:not(#str_prg)").each(function() {
.....
});
For the second part of your question, it would be better to just use the CSS selector instead of a JS loop.

jquery count the elements by class and set the another class a certain element in the list

How with jQuery/Javascript count the elements by class and set another class a certain element in the list.
It is possible?
An example, i have four elements with the class "qa" and change or add class "qa2" second element in list.
Using jquery
var el = $('.cls');
alert(el.length); // Will alert length
To add a class to the 2nd element
$(el[1]).addClass('classOne'); // first item is 0 and second item is 1 and so on
Inside a loop to add class to 2nd element using condition.
el.each(function(i){
if(i==1) // If 2nd item then add the class
$(el[i]).addClass('newClass');
});​
Or this will add 'newClass' class to all elements that has class 'cls'
$('.cls').addClass('newClass')​;
OR this will add different classes to odd and even items in the list/matched items
​$('.cls').each(function(i){
if(!(i%2))
$(this).addClass('odd');
else
$(this).addClass('even');
});​
Relatively easy:
var numOfElementsOfClassName = $('.classNameToFind').length;
var particularIndexToApplyNewClass = 3;
$('.classNameToFind').eq(particularIndexToApplyNewClass).addClass('newClassName');
References:
addClass().
eq().

Remove all classes except one

Well, I know that with some jQuery actions, we can add a lot of classes to a particular div:
<div class="cleanstate"></div>
Let's say that with some clicks and other things, the div gets a lot of classes
<div class="cleanstate bgred paddingleft allcaptions ..."></div>
So, how I can remove all the classes except one? The only idea I have come up is with this:
$('#container div.cleanstate').removeClass().addClass('cleanstate');
While removeClass() kills all the classes, the div get screwed up, but adding just after that addClass('cleanstate') it goes back to normal. The other solution is to put an ID attribute with the base CSS properties so they don't get deleted, what also improves performance, but i just want to know another solution to get rid of all except ".cleanstate"
I'm asking this because, in the real script, the div suffers various changes of classes.
Instead of doing it in 2 steps, you could just reset the entire value at once with attr by overwriting all of the class values with the class you want:
jQuery('#container div.cleanstate').attr('class', 'cleanstate');
Sample: http://jsfiddle.net/jtmKK/1/
Use attr to directly set the class attribute to the specific value you want:
$('#container div.cleanstate').attr('class','cleanstate');
With plain old JavaScript, not JQuery:
document.getElementById("container").className = "cleanstate";
Sometimes you need to keep some of the classes due to CSS animation, because as soon as you remove all classes, animation may not work. Instead, you can keep some classes and remove the rest like this:
$('#container div.cleanstate').removeClass('removethis removethat').addClass('cleanstate');
regarding to robs answer and for and for the sake of completeness you can also use querySelector with vanilla
document.querySelector('#container div.cleanstate').className = "cleanstate";
What if if you want to keep one or more than one classes and want classes except these. These solution would not work where you don't want to remove all classes add that perticular class again.
Using attr and removeClass() resets all classes in first instance and then attach that perticular class again. If you using some animation on classes which are being reset again, it will fail.
If you want to simply remove all classes except some class then this is for you.
My solution is for: removeAllExceptThese
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;});
};
$.fn.removeClassesExceptThese = function(classList) {
/* pass mutliple class name in array like ["first", "second"] */
var $elem = $(this);
if($elem.length > 0) {
var existingClassList = $elem.attr("class").split(' ');
var classListToRemove = existingClassList.diff(classList);
$elem
.removeClass(classListToRemove.join(" "))
.addClass(classList.join(" "));
}
return $elem;
};
This will not reset all classes, it will remove only necessary.
I needed it in my project where I needed to remove only not matching classes.
You can use it $(".third").removeClassesExceptThese(["first", "second"]);

Select elements whose children don't contain specific elements in jQuery

I want to select all divs on a page whose children don't contain an element with a specific class.
I can select elements whose descendants do contain the class with:
$('div').has('.myClass');
So I just want the inverse of this.
I'd use ".filter()":
var theDivs = $('div').filter(function() {
return $(this).find('.myclass').length === 0;
});
A simple $("div:not(:has(.myClass))") will do the job.
How it works internally in jQuery?
1) $("div") - gets all DIVs from the document.
2) :not(:has(.myClass)) - These are two statements one nested in another. Now jQuery executes :has(.myClass) on resulted DIVs in above step and gets all DIVs with class name 'myClass'
3) :not() - This pseudo-selector method will be applied on All DIVs from Step 1 against the DIVs resulted from second statement to find DIVs without '.myClass'. This is possible by looping through all DIVs from Step 1 and comparing DIVs from second step.
$('div:not(:has(*>.myClass))');
$('div').has(':not(.myClass)');

Jquery - Get xth element

For example, I have a div with an id (lets say "the_div"). This div contains an unordered list, and this list has 5 items in it.
How would I add a class to the third list item, without any of the list items having a class attached to them?
Edit: Even better, how would I change the list item text to equal what number element it was?
Thanks.
Or...
$('#the_div ul li:eq(2)').addClass('className');
You can combine the selectors together - if you prefer :)
For your first problem, you can use eq, which is 0 based:
$('ul li', '#thediv').eq(2).addClass('whatever'); // add class to 3rd item
For your second problem, you can use each to iterate through all the list items. The callback function passes an argument containing the index of the current element in the set:
$('ul li', '#thediv').each(function(i) {
$(this).text(i); // update each list item with its index, 0 based.
});

Categories