Adding class to div with onclick function [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I tried to find some way to solve my problem, which is to add class to the divs when I click on them, but I can't make it work.
var el = document.getElementsByClassName('applications');
var i;
for (i = 0; i < el.length; i++) {
el[i].addEventListener("click", function() {
if (el[i]) {
el[i].className += el[i].className ? ' openDiv' : 'openDiv';
}
});
}
I have the 'for loop' because I used getElementsByClassName which gives a node list. I also created a codepen example:
http://codepen.io/anon/pen/dGqmMy

Instead of using complex string manipulation, use classList:
el[i].classList.add('openDiv');
I believe you might need to add a closure for the eventListeners to work.
So this would be considered as a solution:
var el = document.getElementsByClassName('applications');
var i;
for (i = 0; i < el.length; i++) {
(function (i) {
el[i].addEventListener("click", function() {
if (el[i]) {
el[i].classList.add('openDiv');
}
});
})(i);
}

Related

Why does this javascript for loop cause an early exit? [duplicate]

This question already has an answer here:
(infinite?) loop in javascript code
(1 answer)
Closed 5 years ago.
Right now I am really stumped. I have a short function, called "validate", and for some reason the for loop I have prevents an outer for loop from running.
Here it is breaking by only printing out the first entry:
function validate(str) {
for(i=0; i<str.length; i++) {
// do nothing
}
return str;
}
And here's the version that works:
function validate(str) {
/*for(i=0; i<str.length; i++) {
// do nothing
}*/
return str;
}
Here is my fiddle.
Here is the sample text file.
Try encapsulating your variable i. var i = 0;
function validate(str) {
for(var i = 0; i < str.length; i++) {
// do nothing
}
return str;
}
Without the var you are adding it to the global scope or the window object

Javascript onclick attachment indexer issue [duplicate]

This question already has answers here:
Javascript infamous Loop issue? [duplicate]
(5 answers)
Closed 6 years ago.
I have problem with the following 'registerHandlers' javascript function. When I am trying to attach the onclick even, it always displaying '3'. Here how it should work;
An alert should display anchor's zero-based index within a document instead of following the link.
For example, in the document below, the alert should display "2" when Google anchor is clicked since it is the third anchor element in the document and its zero-based index is 2.
Here the script and test page in JSFiddle
function registerHandlers() {
var as = document.getElementsByTagName('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
alert(i);
return false;
}
}
}
This should work :)
function registerHandlers() {
var as = document.getElementsByTagName('a');
var j = 1;
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
alert(j);
j++;
}
}
}

Javascript JSLint create n elements [duplicate]

This question already has answers here:
JSlint: unexpected 'for' [duplicate]
(2 answers)
Closed 7 years ago.
I'm new to JSLint and I'm trying to create function that outputs amount of elements specified in first argument. Normally I would use the for loop but JSLint doesn't like loops and complains about it.
I've searched the web looking for satisfying answer, but the only ones that I've found are with use of new Array or other way of outsmarting JSLint.
So, how to change this code to JSLint-friendly?
function createElements(amount) {
var i;
var elements = [];
for (i = 0; i < amount; i += 1) {
elements.push(document.createElement('div'));
}
return elements;
}
Try this code,
function createElements(amount, document) {
'use strict';
var i = 0;
var elements = [];
while (i < amount) {
i = i + 1;
elements.push(document.createElement('div'));
}
return elements;
}

Javascript get dynamically set data-* attribute [duplicate]

This question already has answers here:
Javascript infamous Loop issue? [duplicate]
(5 answers)
Closed 8 years ago.
Let's say I have multiple elements with the class game_join_a, with their respective data-tbl attributes set dynamically from a database. I want to retrieve those atrributes to further use them in my code.
The code I'm using below returns tells me that a[i] is undefined.
a = document.getElementsByClassName("game_join_a");
for(i = 0; i < a.length; i++){
a[i].addEventListener("click", function(){
console.log(a[i].getAttribute("data-tbl"));
});
}
a = document.getElementsByClassName("game_join_a");
for(i = 0; i < a.length; i++){
a[i].addEventListener("click", function(){
console.log(this.getAttribute("data-tbl"));
});
}
this refers to the element that the click event is binded to. If you're dynamically adding the elements rather than just the data- attributes, you could also try this:
var a = document.getElementById('game_join_container'); // just something that contains all the elements that will be dynamically added
a.addEventListener('click', function (event) {
// check to see if original element clicked is a "game_join_a" element first
if(event.target.classList.contains('game_join_a')) {
console.log(event.target.getAttribute('data-tbl'));
}
});
Try this
var a = document.getElementsByClassName("game_join_a");
for(i = 0; i < a.length; i++) {
a[i].addEventListener("click", function (e) {
console.log(e.currentTarget.getAttribute("data-tbl"));
}, false);
}
Example

How to alert numbers in a for loop [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Looping setTimeout
(3 answers)
Closed 8 years ago.
Please help me fix this code
HTML
<p class="imgclass">Test1</p>
<p class="imgclass">Test2</p>
<p class="imgclass">Test3</p>
JavaScript
imgclassElements = document.getElementsByClassName('imgclass');
for (var i = 0; i < imgclassElements.length; i++){
imgclassElements[i].onmouseover=function(){alert(i);};
}
In browser onmouseover elements with class .imgclass appear alertbox only with text "3". How fix this? I want to pop-up alert window with values appropriate .imgclass elements order.
This is the simplest way to do it, you can use a closure but I'll keep it simple. Also you can access the element and apply styles, or get info from it in the click handler
FIDDLE
http://jsfiddle.net/bz7a2vf5/1/
HTML
<p id="item1" class="imgclass">Test1</p>
<p id="item2" class="imgclass">Test2</p>
<p id="item3" class="imgclass">Test3</p>
JS
imgclassElements = document.getElementsByClassName('imgclass');
for (var i = 0; i < imgclassElements.length; i++) {
click(i);
}
function click(i){
imgclassElements[i].onmouseover = function (e) {
// you can also get the element from e.target
alert(i);
alert(e.target.id);
};
}
This may not be the most elegant way, but
imgclassElements[i].addEventListener('mouseover',function(j){return function(){alert(j);};}(i));
should do it.
That said, you should really read up on JS closures as suggested in the comments to your question.
That problem is occurring because of the time alert is being called, value of i is incremented to 3 that's why it's giving 3 every time.
Try to bind a function with the current value of i like bellow
imgclassElements = document.getElementsByClassName('imgclass');
var printVal = function(i){
return function(){
alert(i);
};
}
for (var i = 0; i < imgclassElements.length; i++){
imgclassElements[i].onmouseover = printVal(i)
}
There can be better solutions also.
The easiest way is to extract the content of your loop in a function
function handleElement(element, i) {
element.onmouseover=function(){alert(i);};
};
for (var i = 0; i < imgclassElements.length; i++){
handleElement(imgclassElements[i], i);
}
Or you can use forEach (Sadly it's a HTMLCollection and not an Array, so it's a bit difficult)
Array.prototype.forEach.call(imgclassElements, function(element, i) {
element.onmouseover=function(){alert(i);};
});
Or give the index as an argument
for (var i = 0; i < imgclassElements.length; i++){
imgclassElements[i].onmouseover=(function(i){alert(i);}).bind(null, i);
}
And always a good thing to learn about closures

Categories