This question already has answers here:
How to Get Element By Class in JavaScript?
(12 answers)
Closed 9 years ago.
Using JavaScript, we can get element by id using following syntax:
var x=document.getElementById("by_id");
I tried following to get element by class:
var y=document.getElementByClass("by_class");
But it resulted into error:
getElementByClass is not function
How can I get an element by its class?
The name of the DOM function is actually getElementsByClassName, not getElementByClassName, simply because more than one element on the page can have the same class, hence: Elements.
The return value of this will be a NodeList instance, or a superset of the NodeList (FF, for instance returns an instance of HTMLCollection). At any rate: the return value is an array-like object:
var y = document.getElementsByClassName('foo');
var aNode = y[0];
If, for some reason you need the return object as an array, you can do that easily, because of its magic length property:
var arrFromList = Array.prototype.slice.call(y);
//or as per AntonB's comment:
var arrFromList = [].slice.call(y);
As yckart suggested querySelector('.foo') and querySelectorAll('.foo') would be preferable, though, as they are, indeed, better supported (93.99% vs 87.24%), according to caniuse.com:
querySelector(all)
getElementsByClassName
Don't use w3schools to learn something
Refer to MDN for accurate information
Another option is to use querySelector('.foo') or querySelectorAll('.foo') which have broader browser support than getElementsByClassName.
http://caniuse.com/#feat=queryselector
http://caniuse.com/#feat=getelementsbyclassname
You need to use the document.getElementsByClassName('class_name');
and dont forget that the returned value is an array of elements so if you want the first one use:
document.getElementsByClassName('class_name')[0]
UPDATE
Now you can use:
document.querySelector(".class_name") to get the first element with the class_name CSS class (null will be returned if non of the elements on the page has this class name)
or document.querySelectorAll(".class_name") to get a NodeList of elements with the class_name css class (empty NodeList will be returned if non of. the elements on the the page has this class name).
you can use
getElementsByClassName
suppose you have some elements and applied a class name 'test', so, you can get elements like as following
var tests = document.getElementsByClassName('test');
its returns an instance NodeList, or its superset: HTMLCollection (FF).
Read more
Related
How do I get only one DOM element by class name? I am guessing that the syntax of getting elements by class name is getElementsByClassName, but I am not sure how many elements it's going to return.
document.getElementsByClassName('className') would always return multiple elements because conceptually Classes are meant to be applied to multiple elements. If you want only the first element in the DOM with that class, you can select the first element out of the array-like HTMLCollection returned.
var elements = document.getElementsByClassName('className');
var requiredElement = elements[0];
Else, if you really want to select only one element. Then you need to use 'id' as conceptually it is used as an identifier for unique elements in a Web Page.
// HTML
<div id="myElement"></div>
// JS
var requiredElement = document.getElementById('myElement');
Clarifications :
getElementsByClassName returns a Node List and not an array
You do not need jQuery
What you were looking for was probably document.querySelector :
How do I get only one DOM element by class name?
var firstElementWithClass = document.querySelector('.myclass');
Also see: https://developer.mozilla.org/en/docs/Web/API/Document/querySelector
You can use jQuery:
$('.className').eq(index)
Or you can use the javascript built-in method:
var elements = document.getElementsByClassName('className');
This returns a nodeList of elements that you can iterate and make what you want.
If you want only one, you can access the elements in the javascript version like this:
elements[index]
To anyone looking for a one liner
var first = document.getElementsByClassName('test')[0];
Use NodeList.item().
For example:
var first = getElementsByClassName('test').item(0);
You can try with this:
document.getElementsByClassName("className")[index]
I tried using let modal = document.getElementsByClassName('modal') to select an element with the class modal. It only worked after using node selection to select the first result: let modal = document.getElementsByClassName('modal')[0]. I know the method Document.getElementsByClassName() returns child elements which have all of the given class names, but there's only one element in my HTML with that class. I confirmed this in my browser's dev tools by using var x = document.getElementsByClassName('modal').length and logging the value of x to the console (it returned 1 as expected).
Could someone explain why node selection is needed in this case?
Edit: My question is different than the one marked as a duplicate. In that question, they are asking the difference between methods than return a single element and those that return an array-like collection of elements. I'm already aware getElementsByClassName returns an array-like collection of elements, whereas the other methods return one element. My question is why do you need to specify the index in a case where all elements of a class are returned but there's only one element with a class (so one item, the correct item, is returned).
document.getElementsByClassName will return a list of elements with the given class name. Even if there is only one element with that class name it will be in a Node List which is why you have to use the [0]
It is needed because getElementsByClassName Returns an HTMLCollection and not a single element.
To get the item without using [0], use a query selector instead, this will give you the item instead of a collection of items.
let modal = document.querySelector('.modal')
console.log(modal)
document.getElementsByClassName
will return array of element who has this class
In order to find children objects of a certain class name, I had to create my own helper function
findChildrenByTagName = function(obj, name){
var ret = [];
for (var k in obj.children){
if (obj.children[k].className === name){
ret.push(obj.children[k]);
}
}
return ret;
}
An example of how it works is
var li = document.createElement('li');
var input = document.createElement('input');
input.setAttribute('class','answer_input');
li.appendChild(input);
console.log(findChildrenByTagName(li,"answer_input"));
However when I replace className above by class in the function above, the code doesn't work. So I am naturally wondering what the difference is between class and className. A quick search on google doesn't reveal anything.
Also what's the best way to return a list of children of a particular class name for a generic object? If such doesn't exist, is there a way to add a method to all objects so that I can call
li.findChildrenByTagName("answer_input");
instead of the global function above?
Let's break this into answerable parts:
Question 1:
What is the difference between class and classname in javascript?
Your title question.
Answer 1:
Class is an attribute in an html element <span class='classy'></span>
While, on the other hand, .className is a property that can by called on an element to get/set its class.
var element = document.createElement('span');
element.className = 'classy'
// element is <span class='classy'></span>
Setting the class can also be accomplished with .getAttribute('class') and .setAttribute('class', 'classy'). We change manipulate classes so often, however, that it merited its own .className method.
Question 2:
However when I replace className above by class in the function above, the code doesn't work. So I am naturally wondering what the difference is between class and className.
Answer 2: element.class is not a property.
Class may be an attribute of an element, but you can't call it like el.class. The way you do it is by el.className, like you already figured out. If you look at the MDN for Element, you'll see that elements have many properties and methods, but .class isn't one.
Question 3:
Also what's the best way to return a list of children of a particular class name for a generic object?
Answer 3: Use .getElementsByClassName
Rather than using a purpose-made function, people frequently "chain" methods one-after-another to achieve your desired effect.
Based on your needs, I think you're asking for the .getElementsByClassName method. Here are the full docs and an excerpt:
The Element.getElementsByClassName() method returns returns a live HTMLCollection [array] containing all child elements which have all of the given class names.
To reuse the example from your answer:
var li = document.createElement('li');
var input = document.createElement('input');
input.setAttribute('class','answer_input');
li.appendChild(input);
console.log(li.getElementsByClassName("answer_input")[0]);
// would return the <input class='answer_input'> as the first element of the HTML array
Don't get confused between the reserved word 'class' and 'className' attribute of DOM element.
According to MDN:
The name className is used for this property instead of class because of conflicts with the "class" keyword in many languages which are used to manipulate the DOM.
EDIT:
The 'class' word used on js 1.0 but in js 2.0 was merged with ECMAScript 4 which was rather unpopular and depreciated. but it is still a reserved word.
The general concept is that class is an object and className is "one" of its properties.Refer the links on how to use the class attribute for manipulation.Kindly correct me if my perception/understanding is wrong.
https://www.w3schools.com/jsref/prop_html_classname.asp
https://www.w3schools.com/jsref/prop_element_classlist.asp
I want to get the control id so that I can attach event to this id,code for this is:
var t=document.getElementsByName('test');
alert(t);
this 't' here returns the Object HTMLCollection but when I run this code on jsfiddle i got Object NodeList and by using t[0].id I got the required id.
I have some requirement so I don't want to use document.getElementById();
Can any one tell me why this is happening and how can I get the id of control through Object HTMLCollection?
So it looks like you have two questions:
1) Can any one tell me why this is happening
and
2) how can I get the id of control through Object HTMLCollection?
First I think you need to understand WHAT an HTMLCollection is. Please read the answer to this stackoverflow question and pay careful attention to what is written, specifically
getElementsByTagName is method of the DOM interface. It accepts a tag
name as input and returns a NodeList (some browsers chose to return
HTMLCollection instead, which is OK, since it is a superset of
NodeList).
So the two share most properties, especially basic properties like id. I recommend reading up on HTMLCollection and NodeList on MDN.
This also contains the answer to your question as to WHY this happens
getElementsByTagName is method of the DOM interface. It accepts a tag
name as input and returns a NodeList (some browsers chose to return
HTMLCollection instead, which is OK, since it is a superset of
NodeList).
Essentially, the answer is simply that different browsers behave differently (when it comes to web development, you will find this is true in MANY ways).
So onto a more deailed answer to the second part of your question. ASSUMING that you have HTML elements with the name 'test' and ASSUMING you want the first one, all you have to do is reference the first element of the returned array, whether it is a NodeList or an HTMLCollection
var element = document.getElementsByName('test')[0];
If you want to make sure you got elements back, just get the array and check that it has > 0 elements
var element;
var elements = document.getElementsByName('test');
if (elements.length > 0)
{
element = elements[0];
}
The method you are using will return an array, so to answer your question you will need to do:
var element = document.getElementsByName('test')[0];
I'm encountering some very strange behaviour with JavaScripts new classList API, say we have the following HTML code:
<p class="testing">Lorem Ipsum</p>
<p class="testing">Lorem Ipsum</p>
And the following JavaScript code:
var elements = document.getElementsByClassName("testing");
alert(elements.length);
elements[0].classList.remove("testing");
alert(elements.length);
The first alert will give you a value of 2, whilst the second alert returns 1.
It appears that removing the class from the element is also removing it from the elements HTMLCollection, which makes absolutely no sense to me.
You can see an example of this code HERE.
I encountered this problem when trying to remove a certain class from some elements using code like below:
var elements = document.getElementsByClassName('testing');
var elementsLength = elements.length - 1;
for(var i = 0; i <= elementsLength ; i++)
{
elements[i].classList.remove('testing');
}
Say we have two elements like in the example above, the loop runs successfully the first time, but the second time it's looking for an element in the HTMLCollection that no longer exists, so I get something like "TypeError: elements[i] is undefined".
You can see an example of the above code HERE
This is frustrating to say the least, I can't understand why/how classList.remove could effect what is effectively an array set only once before the classList.remove function is called. I can't even seem to find anything about this behaviour online.
Am I doing something crazy? Or has I unearthed some strange hidden feature of the classList api that no one knows about?
The collection returned by document.getElementsByClassName is live so if an element doesn't have that class anymore it will be removed from the collection.
You can either create a non-live copy of the collection:
var elements = [].slice.call(document.getElementsByClassName('testing'));
Or take in account that it's live:
while (elements.length) elements[0].classList.remove('element-focus');
Using document.getElementsByClassName returns a live HTMLCollection:
An HTMLCollection in the HTML DOM is live; it is automatically updated when the underlying document is changed.
Thus (as described in plalx's answer) if you remove an element's class, the element is removed from an HTMLCollection based on that class.
Instead you could use document.querySelectorAll which returns a static NodeList collection:
The Document method querySelectorAll() returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.
So your code would change from
var elements = document.getElementsByClassName("testing");
with the class name "testing" as an argument, to
var elements = document.querySelectorAll(".testing");
with the class selector ".testing" as an argument.
And then you could iterate over elements which would be a static NodeList.