This question already has answers here:
getElementsByClassName onclick issue [duplicate]
(5 answers)
Closed 9 years ago.
I have the following code:
var abbrs = document.getElementsByClassName("hover");
abbrs.onmouseover=function() {
console.log(this);
};
It should trigger when I hover over an element with the class "hover", but it is not working.
What am i doing wrong?
As its name suggests document.getElementsByClassName returns a list of elements, with the hover as their className, so you can do it like:
var i=0,
len = abbrs.length,
abbrs = document.getElementsByClassName("hover");
for( ; i < len ; i++){
abbrs[i].addEventListener("mouseover", function(event){
//...
});
}
Although it answers the question but in terms of a better coding practice we better avoid from creating functions in loops. So the better practice could be something like this:
var i=0,
len = abbrs.length,
abbrs = document.getElementsByClassName("hover");
fnction addEvent(abbr){
abbr.addEventListener("mouseover", function(event){
//...
});
}
for( ; i < len ; i++){
addEvent(abbrs[i]);
}
document.getElementsByClassName returns either a NodeList or HTMLCollection depending on your current browser and version.
To add event listeners to all of the items in the "abbrs" collection/list you would need to do:
for(i=0; i< abbrs.length; i++) {
abbrs[i].onmouseover=function() {...};
}
Alternately, using jQuery:
$(".hover").on("mouseover", function() {...});
See the code below (I assume you are not using jquery)
var abbrs = document.getElementsByClassName("hover");
var index,l=abbrs.length;
for (index = 0; index < l; ++index) {
console.log(abbrs[index]);
abbrs[index].onmouseover = function() {
console.log(this);
}
}
Related
This question already has answers here:
textContent and innerHTML not changing the DOM
(3 answers)
Closed 1 year ago.
I want to capitalize every single paragraph in a website using the document.querySelectorAll() function.
I don't know what parameter to choose so I can get an array of all the texts.
Here is my Code:
var txtArr = document.querySelectorAll("p");
function capitalize(txtArr){
for (var i = 0; i < txtArr.length; i++){
txtArr[i].textContent.toUpperCase();
}
}
capitalize(txtArr);
Maybe try
var txtArr = Array.from(document.querySelectorAll("p"));
function capitalize(txtArr) {
for (var i = 0; i < txtArr.length; i++){
txtArr[i].textContent = txtArr[i].textContent.toUpperCase();
}
}
capitalize(txtArr);
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
I'm trying to preview image in specific class that has the same index value of another class, from where the user selects an image.
So far I have done this. When I give a specific value to the output class index the image shows up in that specific class
var input = document.getElementsByClassName("input");
var output = document.getElementsByClassName("output");
for (i = 0; i < input.length; i++) {
input[i].onchange = function() {
output[0].src = URL.createObjectURL(event.target.files[0]);
}
}
However when I try to pass the 'i' variable to that class's index the code doesn't work.
var input = document.getElementsByClassName("input");
var output = document.getElementsByClassName("output");
for (i = 0; i < input.length; i++) {
input[i].onchange = function() {
output[i].src = URL.createObjectURL(event.target.files[0]);
}
}
How can I solve this?
In this code you have used a closure function.When the function is invoked, it is created a single context.
Read more about, here.
One method is to use Immediately-invoked function expression, something like this:
for (i = 0; i < input.length; i++) {
(function(index){
input[index].onchange = function() {
output[index].src = URL.createObjectURL(event.target.files[0]);
}
}(i));
}
Here is an example where closures are used in wrong way.
var input=document.getElementsByClassName('abc');
for (i = 0; i < input.length; i++) {
input[i].onclick = function() {
console.log(i);
}
}
<button class="abc">Button1</button>
<button class="abc">Button2</button>
<button class="abc">Button3</button>
As you can see, anything button you clicked, console.log display 3.
Why it is this behavior ?
It is created a single context. When for loop is finished, the value of i remain 3 and whenever you clicked one button, this value is display in console.
How can we resolve this problem ?
One method is to use IIFE, as I mentioned above.
var input=document.getElementsByClassName('abc');
for (i = 0; i < input.length; i++) {
(function(index){
input[index].onclick = function() {
console.log(index);
}
}(i));
}
<button class="abc">Button1</button>
<button class="abc">Button2</button>
<button class="abc">Button3</button>
This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 6 years ago.
This code has no errors in console.log, but it doesn't display class name as it should.
document.getElementsByClassName("abc").onmouseover = function(){mouseOver()};
function mouseOver(){
abc.innerHTML = "Class name " + abc.className;
}
The .getElementsByClassName() routine returns a list of elements. You cannot directly add event handlers to all elements via the list as you're attempting to do. You have to iterate explicitly:
var abc = document.getElementsByClassName("abc");
for (var i = 0; i < abc.length; ++i) {
// ...
}
For your purposes, doing that with the Array.prototype.forEach method makes a little more sense, though it looks odd:
var abc = document.getElementsByClassName("abc");
[].forEach.call(abc, function(element) {
element.onmouseover = function() {
element.innerHTML = "Class name: " + element.className;
};
});
Using .forEach ensures that the event handler works properly using a local variable (element) private to each invocation of the loop callback.
document.getElementsByClassName Returns an array-like object of all child elements which have all of the given class names. So you will have to bind the onmousever event with each child object.
https://developer.mozilla.org/en/docs/Web/API/Document/getElementsByClassName
You can try like this.
var elements = document.getElementsByClassName("abc")
for (var i=0; i < elements.length; i++) {
elements[i].onmouseover = function(){mouseOver(i)};
}
function mouseOver(index){
document.getElementsByClassName("abc")[index -1].innerHTML = "Class name " + document.getElementsByClassName("abc")[index -1].className;
}
<div class="abc">
mouse over me
</div>
Edited Answer based on the provided html in comment
<html> <head> </head> <body> <h1 class="abc">Hello everyone</div>
<script type="text/javascript"> var elements = document.getElementsByClassName("abc"); for (var i=0; i < elements.length; i++) { elements[i].onmouseover = function(){mouseOver(i)}; } function mouseOver(index){ document.getElementsByClassName("abc")[index -1].innerHTML = "Class name " + document.getElementsByClassName("abc")[index -1].className; } </script> </body> </html>
This question already has an answer here:
getElementByID works, getElementsByClassName does not [duplicate]
(1 answer)
Closed 7 years ago.
I'm working on a solution where the javascript changes div1 instead of div2.
This code works with getElementbyId but does not work with getElementbyClassName. Why does this not work?
function refer(Div1, Div2) {
if (document.getElementByClassName('Div1')) {
if (document.getElementByClassName('Div1').style.display == 'block') {
var elems = document.getElementsByClassName('Div2');
for(var i = 0; i < elems.length; i++) {
elems[i].style.display = 'block';
}
var elem = document.getElementsByClassName('Div1');
for(var i = 0; i < elem.length; i++) {
elem[i].style.display = 'none';
}
}
}
}
Here is an example how to use getElementsByClassName: Fiddle
Is this working for you?
array = document.getElementsByClassName('div1');
for (i = 0; i < array.length; i++) {
array[i].style.backgroundColor = "red";
}
In Chrome and Edge works with no issue.
You are using a array as an object, the difference between getElementbyId and
getElementsByClassName is that:
getElementbyId will return you an object.
getElementsByClassName will return you an array.
getElementsByClassName
The getElementsByClassName(classNames) method takes a string that
contains an unordered set of unique space-separated tokens
representing classes. When called, the method must return a live
NodeList object containing all the elements in the document that
have all the classes specified in that argument, having obtained the
classes by splitting a string on spaces. If there are no tokens
specified in the argument, then the method must return an empty
NodeList.
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname
getElementById
The getElementById() method accesses the first element with the specified id.
http://www.w3schools.com/jsref/met_doc_getelementbyid.asp
in your code the lines:
1 if (document.getElementByClassName('Div1')) {
2 if (document.getElementByClassName('Div1').style.display == 'block') {
will NOT work as expected: specially the second(2) line, cos the getElementByClassName will return an array, and the array will NOT have the style property, you gonna access each element by iterating them.
That's why the function getElementById was working for you, this function will return you the direct object , and so you will be able to access the style property.
One working code:
function refer(Div1,Div2) {
var elem = document.getElementsByClassName('Div1');
var elems = document.getElementsByClassName('Div2');
for(var i = 0; i < elem.length; i++) {
if (elem[i]) {
if (elem[i].style.display == 'block') {
elem[i].style.display = 'none';
for(var i = 0; i < elems.length; i++) {
elems[i].style.display = 'block';
}
}
}
}
}
I found this function:
document.getElementsByClassName = function(c){
for(var i=0,a=[],o;o=document.body.getElementsByTagName('*')[i++];){
if(RegExp('\\b'+c+'\\b','gi').test(o.className)){
a.push(o);
}
}
return a;
}
How can I hide all elements by class?
I tried:
var array = document.getElementsByClassName("hide");
for(var i = 0; i < array.length; i++)
{
$(array[i]).hide();
}
But I got error:
Could not convert JavaScript argument arg 0 [nsIDOMWindow.getComputedStyle]
jQuery allows CSS selectors to be used, doing away with the need for hand-built loops and regular expressions. To hide an element with class fooey, just do
$('.fooey').hide();
If you're using vanilla JavaScript, then:
var array = document.getElementsByClassName("hide");
for(var i = 0; i < array.length; i++)
{
array[i].style.display = 'none';
array[i].onclick = function(){
// do stuff
};
/* or:
array[i].addEventListener('click',functionToCall);
*/
}
But, given that you're using jQuery, I don't understand why you're complicating things for yourself, just use:
$('.hide').hide();
Further to the above, given your comment:
Because I must add event "click" for each element.
Simply use:
$(elementSelector).click(
function(){
// do stuff
});
Assuming you want to hide, and bind a click-event to, the same elements:
$('.hide').hide().click(
function(){
// do stuff
});
What you get from getElementsByClassName is NOT an array, but a NodeList, hence the error when trying to loop.
However, you can still loop over a NodeList using the following:
var nodeList = document.getElementsByClassName("hide");
for(var x in nodeList){}