According to the book I am reading it is better to change CSS by class when you are using Javascript. But how? Can someone give a sample snippet for this?
Suppose you have:
<div id="mydiv" class="oldclass">text</div>
and the following styles:
.oldclass { color: blue }
.newclass { background-color: yellow }
You can change the class on mydiv in javascript like this:
document.getElementById('mydiv').className = 'newclass';
After the DOM manipulation you will be left with:
<div id="mydiv" class="newclass">text</div>
If you want to add a new css class without removing the old one, you can append to it:
document.getElementById('mydiv').className += ' newClass';
This will result in:
<div id="mydiv" class="oldclass newclass">text</div>
Since classList is supported in all major browsers and jQuery drops support for IE<9 (in 2.x branch as Stormblack points in the comment), considering this HTML
<div id="mydiv" class="oldclass">text</div>
you can comfortably use this syntax:
document.getElementById('mydiv').classList.add("newClass");
This will also result in:
<div id="mydiv" class="oldclass newclass">text</div>
plus you can also use remove, toggle, contains methods.
If you want to manipulate the actual CSS class instead of modifying the DOM elements or using modifier CSS classes, see
https://stackoverflow.com/a/50036923/482916.
I'd highly recommend jQuery. It then becomes as simple as:
$('#mydiv').addClass('newclass');
You don't have to worry about removing the old class then as addClass() will only append to it. You also have removeClass();
The other advantage over the getElementById() method is you can apply it to multiple elements at the same time with a single line of code.
$('div').addClass('newclass');
$('.oldclass').addClass('newclass');
The first example will add the class to all DIV elements on the page. The second example will add the new class to all elements that currently have the old class.
use the className property:
document.getElementById('your_element_s_id').className = 'cssClass';
There are two ways in which this can be accomplished using vanilla javascript. The first is className and the second is classList. className works in all browsers but can be unwieldy to work with when modifying an element's class attribute. classList is an easier way to modify an element's class(es).
To outright set an element's class attribute, className is the way to go, otherwise to modify an element's class(es), it's easier to use classList.
Initial Html
<div id="ID"></div>
Setting the class attribute
var div = document.getElementById('ID');
div.className = "foo bar car";
Result:
<div id="ID" class="foo bar car"></div>
Adding a class
div.classList.add("car");// Class already exists, nothing happens
div.classList.add("tar");
Note: There's no need to test if a class exists before adding it. If a class needs to be added, just add it. If it already exists, a duplicate won't be added.
Result:
<div id="ID" class="foo bar car tar"></div>
Removing a class
div.classList.remove("car");
div.classList.remove("tar");
div.classList.remove("car");// No class of this name exists, nothing happens
Note: Just like add, if a class needs to be removed, remove it. If it's there, it'll be removed, otherwise nothing will happen.
Result:
<div id="ID" class="foo bar"></div>
Checking if a class attribute contains a specific class
if (div.classList.contains("foo")) {
// Do stuff
}
Toggling a class
var classWasAdded = div.classList.toggle("bar"); // "bar" gets removed
// classWasAdded is false since "bar" was removed
classWasAdded = div.classList.toggle("bar"); // "bar" gets added
// classWasAdded is true since "bar" was added
.toggle has a second boolean parameter that, in my opinion, is redundant and isn't worth going over.
For more information on classList, check out MDN. It also covers browser compatibility if that's a concern, which can be addressed by using Modernizr for detection and a polyfill if needed.
document.getElementById("my").className = 'myclass';
You may also be interested in modifying it using jQuery:
http://api.jquery.com/category/css/
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("div").addClass(function(){
return "par" ;
});
});
</script>
<style>
.par {
color: blue;
}
</style>
</head>
<body>
<div class="test">This is a paragraph.</div>
</body>
</html>
Related
In d3, when is it appropriate to use
d3.select("foo").attr('class', 'bar');
as opposed to
d3.select("foo").classed('bar', true);
?
Is one recommended or expected to be deprecated? What is industry standard?
There is no appropriate method, or recommended, or standard. Both are valid methods, and deciding which one to use depends on your specific purpose.
The main difference between classed("foo", true) and attr("class", "foo") is that the former will only modify the classList if it already exists...
If a value is specified, assigns or unassigns the specified CSS class names on the selected elements by setting the class attribute or modifying the classList property and returns this selection. (emphasis mine)
... while the latter will override it.
Let's show the difference in a very simple demo.
There are already paragraphs with assigned classes in the DOM. We select them and use attr("class", "someClass") in the selection. Then, we console.log the class of each one:
var p = d3.selectAll("p");
p.attr("class", "someClass");
p.each(function() {
console.log(d3.select(this).attr("class"))
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<p class="foo">This paragraph has a class foo</p>
<p class="bar">This paragraph has a class bar</p>
<p class="baz">This paragraph has a class baz</p>
You can see that someClass overrides the previously existing classes.
Now the same code using classed("someClass", true):
var p = d3.selectAll("p");
p.classed("someClass", true);
p.each(function() {
console.log(d3.select(this).attr("class"))
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<p class="foo">This paragraph has a class foo</p>
<p class="bar">This paragraph has a class bar</p>
<p class="baz">This paragraph has a class baz</p>
As you can see, someClass is added to the previously existing classes.
I think the classed is a kind of conditional check for example:
To add a class, the second parameter to classed must be true, as in this code:
d3.selectAll(".bar")
.classed("my-selector", true);
To remove a class, the second parameter to classed must be false.
d3.selectAll(".bar")
.classed("my-selector", false);
To flip a class to the opposite state – remove it if it exists already, add it if it does not yet exist – you can do one of the following.
For a single element, the code might look like this:
var oneBar = d3.select(".bar")
oneBar.classed("my-selector", !oneBar.classed("my-selector"));
Both classed and attr have equal importance and attr has other uses which classed can not be used for.
For reference
I am writing a small library where I am in need of selecting a relative element to the targeted element through querySelector method.
For example:
HTML
<div class="target"></div>
<div class="relative"></div>
<!-- querySelector will select only this .target element -->
<div class="target"></div>
<div class="relative"></div>
<div class="target"></div>
<div class="relative"></div>
JavaScript
var target = document.querySelectorAll('.target')[1];
// Something like this which doesn't work actually
var relativeElement = target.querySelector('this + .relative');
In the above example, I am trying to select the .relative class element relative only to the .target element whose value is stored in target variable. No styles should apply to the other .relative class elements.
PS: the selectors can vary. So, I can't use JavaScript's predefined methods like previousElementSibling or nextElementSibling.
I don't need solution in jQuery or other JavaScript libraries.
Well it should be ideally:
var relativeElement = target.querySelector('.relative');
But this will actually try to select something inside the target element.
therefore this would only work if your html structure is something like:
<div class="target">
<div class="relative"></div>
</div>
Your best bet would probably in this case be to use nextElementSibling which I understand is difficult for you to use.
You cannot.
If you insist on using the querySelector of the subject element, the answers is there is no way.
The spec and MDN both says clearly that Element.querySelector must return "a descendant of the element on which it is invoked", and the object element you want does not meet this limitation.
You must go up and use other elements, e.g. document.querySelector, if you want to break out.
You can always override Element.prototype.querySelector to do your biddings, including implementing your own CSS engine that select whatever element you want in whatever syntax you want.
I didn't mention this because you will be breaking the assumption of a very important function, easily breaking other libraries and even normal code, or at best slowing them down.
target.querySelector('.relative');
By using querySelector on the target instead of document, you scope the DOM traversal to the target element.
It is not entirely clear from your explanation, but by related i assume you mean descendant?
To get all target elements you can use
document.querySelectorAll('.target')
And then iterate the result
I found a way which will work for my library.
I will replace "this " in the querySelector with a unique custom attribute value. Something like this:
Element.prototype.customQuerySelector = function(selector){
// Adding a custom attribute to refer for selector
this.setAttribute('data-unique-id', '1');
// Replace "this " string with custom attribute's value
// You can also add a unique class name instead of adding custom attribute
selector = selector.replace("this ", '[data-unique-id="1"] ');
// Get the relative element
var relativeElement = document.querySelector(selector);
// After getting the relative element, the added custom attribute is useless
// So, remove it
this.removeAttribute('data-unique-id');
// return the fetched element
return relativeElement;
}
var element = document.querySelectorAll('.target')[1];
var targetElement = element.customQuerySelector('this + .relative');
// Now, do anything with the fetched relative element
targetElement.style.color = "red";
Working Fiddle
I'm working with the German book (mediated title) "jQuery the practice book".
In one of the first tutorials the given JS code is like this:
$(document).ready(function()
{
$("#box p").click
(
function()
{
$("#box p").removeClass("green");
$(this)
.addClass("green")
.parent()
.removeClass()
.addClass("boxColor-" + $("#box p").index(this));
}
);
});
the CSS is like this:
<style type ="text/css">
p {
cursor:pointer;
}
.green{
color:#009933;
background-color:#E2FFEC;
cursor:default;
}
</style>
and the HTML is this:
<body>
<div id="box">
<p>Erster Absatz</p>
<p>Zweiter Absatz</p>
<p>Dritter Absatz</p>
</div>
</body>
What makes me stuck is this line of the jQuery script:
.addClass("boxColor-" + $("#box p").index(this));
The Tutorial of the book explains this with a reason like "On which way else we could get the p box related Class?"
But I don't get the point what is happening in that line?
And even if I remove this line, the result I'm seeing keeps being the same.
so, what does happen here? and is it really necessary in any way?
That line is adding a boxColor-N class to the #box element, where N is the index of the <p> you just clicked.
Since there is nothing in the CSS that targets such a class and also no script code that works with it, there are no observable effects.
This line adds a class name. The value that is added is a concatenation of the string boxColor- and the index of the relevant paragraph element.
The index of the element is extracted by using the jQuery index() function.
Regarding your question if it is needed at all really depends on what that class name does. All it's really doing here is adding a class name. If that class name has any other uses such as changing CSS properties then yes, it is needed. In your example, there is no CSS rule for that value - so nothing really changes or happens.
To see this actual doing something, you can add a CSS rule like this:
boxColor-0 {
background:red;
}
boxColor-1 {
background:green;
}
boxColor-2 {
background:blue;
}
With these rules, when you click on a <p> element, it's background color will change.
I don't know if it was an error but as the other explained this will add a class something like "boxColor-" + the index of the element.
But the code
$("#box p").removeClass("green");
$(this)
.addClass("green")
.parent()
.removeClass();
has a closing ; on .removeClass();
In jQuery the Chaining is used to call multiple functions on an element selected but because you are ending the chaining with this line. Otherwise you will add the class to the parent of the <p> tag
.removeClass();
You're not applying the addClass to any object try removing the ; and then use something like
$("#box p").removeClass("green");
$(this)
.addClass("green")
.parent()
.removeClass()
.addClass("boxColor-" + $("#box p").index(this));
Here is an example of how it should work.
JSFiddle
I would like to know the best way to accomplish the following task:
Using jquery or pure javascript code for copy the style of one dom element to another.
example:
// css file
div.myClass {
color: red;
}
// html file
<div class="otherClass">
no style
</div>
// js script
var propertyName = color;
$("div.otherClass").css( propertyName , function () {
return $("div.otherClass").css(propertyName);
} )
The js script works but I would like to take the propertyName automatically. Any idea?
Here is jsFiddle for your question from another one.
why not append the same class from one to the other?
$("div.otherClass").addClass('myClass');
if you want to replace the style properties of that element then you could also do something like this
$("div.otherClass").removeClass("otherClass").addClass("myClass");
this will first remove the class otherClass and then ad myclass to the element
otherwise Joseph's answer would work best
I'm working with jQuery and looking to see if there is an easy way to determine if the element has a specific CSS class associated with it.
I have the id of the element, and the CSS class that I'm looking for. I just need to be able to, in an if statement, do a comparison based on the existence of that class on the element.
Use the hasClass method:
jQueryCollection.hasClass(className);
or
$(selector).hasClass(className);
The argument is (obviously) a string representing the class you are checking, and it returns a boolean (so it doesn't support chaining like most jQuery methods).
Note: If you pass a className argument that contains whitespace, it will be matched literally against the collection's elements' className string. So if, for instance, you have an element,
<span class="foo bar" />
then this will return true:
$('span').hasClass('foo bar')
and these will return false:
$('span').hasClass('bar foo')
$('span').hasClass('foo bar')
from the FAQ
elem = $("#elemid");
if (elem.is (".class")) {
// whatever
}
or:
elem = $("#elemid");
if (elem.hasClass ("class")) {
// whatever
}
As for the negation, if you want to know if an element hasn't a class you can simply do as Mark said.
if (!currentPage.parent().hasClass('home')) { do what you want }
Without jQuery:
var hasclass=!!(' '+elem.className+' ').indexOf(' check_class ')+1;
Or:
function hasClass(e,c){
return e&&(e instanceof HTMLElement)&&!!((' '+e.className+' ').indexOf(' '+c+' ')+1);
}
/*example of usage*/
var has_class_medium=hasClass(document.getElementsByTagName('input')[0],'medium');
This is WAY faster than jQuery!
In the interests of helping anyone who lands here but was actually looking for a jQuery free way of doing this:
element.classList.contains('your-class-name')
Check the official jQuery FAQ page :
How do I test whether an element has perticular class or not
$('.segment-name').click(function () {
if($(this).hasClass('segment-a')){
//class exist
}
});
In my case , I used the 'is' a jQuery function, I had a HTML element with different css classes added , I was looking for a specific class in the middle of these , so I used the "is" a good alternative to check a class dynamically added to an html element , which already has other css classes, it is another good alternative.
simple example :
<!--element html-->
<nav class="cbp-spmenu cbp-spmenu-horizontal cbp-spmenu-bottom cbp-spmenu-open" id="menu">somethings here... </nav>
<!--jQuery "is"-->
$('#menu').is('.cbp-spmenu-open');
advanced example :
<!--element html-->
<nav class="cbp-spmenu cbp-spmenu-horizontal cbp-spmenu-bottom cbp-spmenu-open" id="menu">somethings here... </nav>
<!--jQuery "is"-->
if($('#menu').is('.cbp-spmenu-bottom.cbp-spmenu-open')){
$("#menu").show();
}