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"]);
Related
I'm trying to select the class p100 and replace it with a number that will be inputted by the user, does anyone know how to keep the "p" and replace the number in the class using jQuery?
<div class="c100 p100 small green storyline">
something like this can be done: $('.p100').removeClass('p100').addClass('p'+uservalue);
edit:
if you have more that one div with class p100:
$('.p100').each(function(){
$(this).removeClass('p100').addClass('p'+uservalue);
})
var item = $('.p100');
$('#button').click(() => {
item.removeClass('p100');
item.addClass('p200')
})
Working JSFiddle with visuals
You can set the class by using .attr(), like this:
$("#td_id").attr('class', 'newClass');
If you want to add a class, use .addclass() instead, like this:
$("#td_id").addClass('newClass');
Or a short way to swap classes using .toggleClass():
$("#td_id").toggleClass('change_me newClass');
Read more about Class attributes
While the other answers mention good ways with jquery, I'd like to add a vanilla javascript solution :) :
for(let elem of document.getElementsByClassName('p100'){
elem.classList.remove('p100');
elem.classList.add('p'+uservalue);
}
If you want to restrict it to divs (the above code will match every element with class p100) just replace document.getElementsByClassName('p100') with document.querySelectorAll('div .p100') :).
We could replace the two calls of .remove and .add with one call of .replace like this : elem.classList.replace('p100','p'+uservalue), Currently this function isn't implemented in all browsers.
Pay attention that classList is supported in IE10+, if you need IE9 support you need a polyfill, MDN already gives one and the polyfill provides replace function above too, see here : https://developer.mozilla.org/en-US/docs/Web/API/Element/classList (scroll down to see the polyfill)
for document.querySelectorAll support, it's supported in IE8(CSS2 selectors only) and IE9+(all CSS selectors including CSS3 ones).
Using String.match & RegExp.test
var pattern = new RegExp("/p[0-9]*/");
var className = $('div').attr('class')
if (pattern.test(className)) {
var class = className.match(pattern)[0];
$('div').removeClass(class).addClass('p' + integer);
}
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.
I have 2 text area's that are generated automatically, and I need to use JavaScript to disable both when the page has loaded. The catch is because they are generated automatically I can't give them an ID because they would both have the ID - a big no.
Attempted Javascript:
document.getElementByClassName('option_window-size').disabled=true;
I know this works because if I change getElementbyClassName to ID then it will work if I give the text areas the ID as well. But as I say it needs to work off class. Also it can't work of the Name attribute because that is automatically generated per product and per page...
I have tried this but it just doesn't work and I can't figure out why not because it should as the only thing I have changed is from ID to CLASS
Text Areas
<textarea name="willbeautogenerated" class="option_window-size" cols="40" rows="5">willbeautogenerated</textarea>
Additional note: I have tried to count and assign them different IDs using PHP but it gets far to complex. Also it is only these two that need disabling, thus I can't just disable all text area's on the page.
I know this works because if I change getElementByClassName to ID then it will work if I give the text areas the ID as well. But as I say it needs to work off class.
getElementsByClassName returns a NodeList rather than a Node itself. You'll have to loop over the list, or if you expect just 1 item, choose index 0.
var nodes = document.getElementsByClassName("option_window-size"),
i = 0, e;
while (e = nodes[i++]) e.disabled = true;
jQuery makes this pretty simple:
$(".selector").prop("disabled", true);
ALTHOUGH! It should be noted that this note appears on the man pages for $.prop() and $.attr():
Note: Attempting to change the type property (or attribute) of an input element created via HTML or already in an HTML document will result in an error being thrown by Internet Explorer 6, 7, or 8.
This doesn't apply directly to your question, but you are changing prop/attrs on an input element, so be aware.
But it's still possible with plain old JS:
var els = document.getElementsByClassName("selector"); // note: Elements, not Element
for(var e = 0; e < els.length; e++)
{
els[e].disabled = true;
}
getElementsByClassName returns an NodeList, you just have to iterate over each element within.
You can use class selector,
$('.option_window').attr('disabled', true);
OR
$('.option_window')[0].disabled = true;
With Jquery you can do:
//make sure to use .prop() and not .attr() when setting properties of an element
$('.option_window').prop('disabled', true);
Disable textarea using jQuery:
$('.option_window-size').attr('disabled', true);
your missing a s in elements and the index where the element is like [0], for the first element.
document.getElementsByClassName('option_window-size')[0].disabled=true;
or
document.getElementsByName('willbeautogenerated')[0].disabled=true;
Disabel texarea using .prop() methode in jquery...
$('.option_window-size').prop('disabled', true);
You can use CSS:
.option_window-size{display:none;}
I have a navigation menu with about 10 items, and I put together this code to update the links for which is selected and which is not. It manually updates classes. The problem is, as you can probably tell, its inefficient and its a pain to update. Is there a better way of doing it?
$('#Button1').click(function(){
$('#Button1').addClass("selectedItem");
$('#Button2').removeClass("selectedItem");
$('#Button3').removeClass("selectedItem");
$('#Button4').removeClass("selectedItem");
$('#Button5').removeClass("selectedItem");
$('#Button6').removeClass("selectedItem");
$('#Button7').removeClass("selectedItem");
$('#Button8').removeClass("selectedItem");
$('#Button9').removeClass("selectedItem");
$('#Button10').removeClass("selectedItem");
});
You could try something like this -
$("[id^='Button']").removeClass("selectedItem");
$('#Button1').addClass("selectedItem");
This will first remove all the selectedItem classes from any element which has an id attribute starting with "button". The second command then adds the class to Button1
You could also simply bind all the elements with the same handler like this -
var $buttons = $("[id^='Button']");
$buttons.on('click', function ()
{
$buttons.removeClass("selectedItem");
$(this).addClass("selectedItem");
});
For each element, when clicked, the class will be removed - the element that was clicked with then have the class added.
Checkout the Attribute Starts With Selector [name^="value"] selector.
I would suggest using classes because this is exactly what they are for - to denote groups of elements. While you can easily select your buttons using the method proposed by Lix (and you should use this method if you can't modify HTML), using class is a more unobtrusive:
var $buttons = $('.button').on('click', function() {
$buttons.removeClass('selectedItem');
$(this).addClass('selectedItem');
});
Meta example: http://jsfiddle.net/88JR2/
You could have a class .button and apply it to all your buttons then
$('#Button1').click(function(){
$('.button').removeClass("selectedItem");
$('#Button1').addClass("selectedItem");
});
I feel like this is a stupid simple question, but I've been doing so much CSS work lately that I feel a little rusty. So, I have several buttons with classname: and class: attributes. Basically, all I want to do is take the value of the classname attribute and append it to class. Only the buttons with className need their content appended.
classname="blah_btn blah_btnGrey" class="blah blah blah foo foo"
Would I write something like:
if ($('#ui-button').has("className")) {
$(("className").val()).appendTo("class");
or something more along the lines of:
$("button").each(function() {
//do stuff
});
Or am I in the completely wrong ballpark? Once again, any help is greatly appreciated.
First off, please don't use an attribute call className. That is reserved as the way to address the class attribute because class is a reserved word in javascript. So, if you use attributes with names of class and className, you could end up having a hard time reaching them individually in javascript. It could be a mess. Pick a more unique name for the one that isn't actually class.
To add the class attribute, you would just use .addClass():
$('#ui-button').addClass("blah_btn")
jQuery's `addClass() is smart enough to not add it if it's already present.
If you want to get an attribute and add it to the actual class, you can do this:
$('#ui-button').addClass($(elem).attr("myAttribute"));
If you just want to add one attribute onto another, you can do this:
var target = $('#ui-button');
target.attr(target.attr("myAttribute") + $(elem).attr("myAttribute"));
That's what you need ?
$.each($('#ui-button.className'), function() {
var $element = $(this);
$element.addClass($element.val());
});
How about this?
$('button[className]').each(function(){
var classNameValue = $(this).attr('className');
var classValue = $(this).attr('class');
$(this).attr('class', classValue + classNameValue);
});