Event listener in a loop - javascript

So I have this eventListner that calls an Class, works like a charm but only once since inte call the add class with index 0.
Im trying to create a loop that will call every add class inside the script, but i cant get loop...
This is the event listner without the loop
var AddEvent = "add";
var addClass = document.getElementsByClassName(AddEvent)[0]
addClass.addEventListener("click", addDiceEvent, false);
function addDiceEvent() {
dicesides_funcfunc();
}
And this is what Im trying to create.
function AddDice(){
for (i = 0; i < 5; i++) {
var addClass = document.getElementsByClassName("add");
addClass.addEventListener("click", addDiceEvent, false);
function addDiceEvent(){
dicesides_funcfunc();
}
}
} AddDice();
Any ideas ?

Hope this work.......
var addClassArr= document.getElementsByClassName(AddEvent);
for (var x in addClassArr)
{
var addClass = addClassArr[x];
addClass.addEventListener("click", addDiceEvent, false);
}
function addDiceEvent() {
dicesides_funcfunc();
}

You need to create new skope in for loop, try this:
function AddDice(){
for (i = 0; i < 5; i++) {
(function(){
var addClass = document.getElementsByClassName("add");
addClass.addEventListener("click", function(){
dicesides_funcfunc();
}, false);
})();
}
}

Related

Removing an event listener the proper way

How do I properly remove an event listener...
function createMaze() {
var x;
for (x = 0; x < 4; x++) {
var mazeBlock = document.createElement('div');
document.body.appendChild(mazeBlock);
mazeBlock.setAttribute('class', 'blockStyle');
mazeBlock.setAttribute('id', 'mazeBlock'+x);
mazeBlock.addEventListener( 'click', function(){ eventCall(this) } );
}
}
function eventCall(t) {
alert( t.id );
t.removeEventListener(); //...know that I'm missing something here.
// Also in my code, this remove will not happen here but be initiated somewhere else in the script.
}
I did bunch of digging and the top answer there suggest to add the listener to an object for easier removal but... I'm not sure how to accomplish that
While you could save a reference to the function you call addEventListener with so you can remove it:
for (let x = 0; x < 4; x++) {
const mazeBlock = document.createElement('div');
document.body.appendChild(mazeBlock);
mazeBlock.className = 'blockStyle';
mazeBlock.id = 'mazeBlock' + x;
mazeBlock.addEventListener('click', function handler() {
mazeBlock.removeEventListener('click', handler);
eventCall(mazeBlock);
});
}
(above, eventCall is called with the <div> as the first argument)
It would be easier to make sure the function can only be called once by passing { once: true } as a third argument to addEventListener:
mazeBlock.addEventListener( 'click', eventCall, { once: true });
(above, eventCall is called with the event as the first argument - to get to the <div>, access the .target of the argument)
If you need to remove listeners for all such elements, you might consider a different approach - rather than attaching lots of listeners and then removing them all, use event delegation instead. That way, all you have to do is remove the single delegated listener:
document.body.addEventListener('click', function handler(event) {
if (!event.target.matches('.blockStyle')) return;
// A block was clicked on, remove the listener:
document.body.removeEventListener('click', handler);
// Do stuff with the clicked element:
eventCall(event.target);
});
If you're forced by weird school rules to add listeners to each element, create the listener function outside the loop, then iterate over all elements and remove the listener from each when needed:
const handler = (event) => {
document.querySelectorAll('.blockStyle').forEach((div) => {
div.removeEventListener('click', handler);
});
// do stuff with event and event.target
};
...ended up doing this:
function createMaze() {
var x;
for (x = 0; x < 4; x++) {
const mazeBlock = document.createElement('div');
document.body.appendChild(mazeBlock);
mazeBlock.className = 'blockStyle';
mazeBlock.id = 'mazeBlock' + x;
mazeBlock.addEventListener( 'click', eventCall );
}
}
function eventCall() {
alert( this.id );
}
//...this is called from another piece of the script on a separate occasion
function removeListeners() {
var blocks = document.getElementsByClassName('blockStyle');
for (var i = 0; i < blocks.length; i++) {
var block = blocks[i];
block.removeEventListener( 'click', eventCall );
}
}
#CertainPerformance Thanks for all your help! :)

Having a for loop inside a jQuery append Method

My Question
I am having trouble finding how to place a for loop inside a jQuery append method. Should it be a strong, should it be just there, how do I format the code so it works?
My Code
window.onload = function () {
$(function () {
$('#li22').append($('<table/>').append(for (var i = 0; i <= 3; i++) {'$('#li22').append($(""));'}));
});
}
Firstly, don't put a for loop directly in the append() method. Secondly, don't put a document.ready event handler inside a window.onload handler - it's pointless.
Also, it's not exactly clear what you're trying to achieve. You're appending a table to #li22, then appending nothing to #li22 and returning that to the table...? As such the below is a general guide on how to use append() properly.
append() accepts a either string, so you should put the for outside the append(), like this:
$(function () {
for (var i = 0; i <= 3; i++) {
$('#li22').append($('<table/>'));
}
});
Alternatively you can provide a function to append() which returns the HTML to be appended. You can put the for in there:
$(function () {
$('#li22').append(function() {
var html = '';
for (var i = 0; i <= 3; i++) {
html += '<table></table>';
}
return html;
});
}
});
You can not execute code inside of a function's argument. Therefor, the code must be formatted like:
window.onload = function () {
$(function () {
var tableTag = $('<table><table/>');
$('#li22').append( tableTag );
for (var i = 0; i <= 3; i++) {
$( tableTag ).append( "" );
}
});
}
Try Like this .
$(document).ready(function () {
var string="<table>";
for (var i = 0; i <= 3; i++)
{
string += "what you need";
}
string +="</table>"
$('#li22').append(string);
});

javascript click game using less html

I'm making a basic javascript game where you need to click multiple images in a certain period of time. (currently 4 seconds)
My javascript looks like this
document.getElementById("myBtn").addEventListener("click", countdown);
function countdown() {
setTimeout(function(){
prompt("you got" + counter);
}, 4000);
}
var counter = 0;
function countup() {
counter = counter + 1;
}
And while that does work, every img in my HTML has to have:
onclick="countup(); this.onclick=null"
which after 20 pictures is a lot. My question is, is there a way to condense this? Some js method of collecting all the pictures by class and applying the click countup and null to it?
You can use document.querySelectorAll() to select all your images and add an event listener to count up and remove the event listener like so:
function handleClick(e)
{
countup();
e.target.removeEventListener('click', handleClick);
}
var images = document.querySelectorAll('img');
for (var i = 0; i < images.length; i++)
{
images[i].addEventListener('click', handleClick);
}
More about document.querySelectorAll here: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
You can also use a classname with querySelectorAll, pass in '.myClass'
Yes - use getElementsByClassName. E.g. if you apply the class 'button' to all of your button images:
var buttons = document.getElementByClassName('button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', countup);
}
To remove the event listener after the first click requires something a bit more complicated, however. For example, you can write a second function that adds an event listener which calls your original function and then removes itself.
var buttons = document.getElementByClassName('button');
function clickOnce(el, func) {
function listener() {
func();
el.removeEventListener('click', listener);
}
el.addEventListener('click', listener);
}
for (var i = 0; i < buttons.length; i++) {
clickOnce(buttons[i], countup);
}

Changing text inside of a dynamically created element

I want to change the text inside of an element for dynamically created elements. i = 2 because that's Why is it not working?
var loanName = function() {
for(var t=1; t < i; t++) {
$('body').on('keyup', '.loanNameV'+t, function () {
var loanN = $('.loanNameV'+t).val();
$('.nameLoan'+t).text(loanN);
});
}
};
$('body').on('keyup', '[class^="loanNameV"]', function () {
var numbesideclass = ($(this).attr('class').split('loanNameV'))[1];
var loanN = $(this).val();
$('.nameLoan'+numbesideclass).text(loanN);
});
Note: this code will work if you don't have another class for loanNameV elements like class="loanNameV1 anotherclass anotherclass" in this case this code will not work as expected

Call a function according to the elements of an array

I am a beginner in JavaScript and jQuery, and I would like to have an idea to how to proceed with this part of a code,
I have a function with a callback, for example:
myFunc(elem, callback) {
$(elem).fadeIn(function(){ callback(); });
}
and I want to run this function for elements that are in an array:
elems = ['#elem1', '#elem2_3', '#elem4_5', '#elem3', '#elem_five'];
but, I want to execute this function for each element of the array, one by one through the callback.
eg. once #elem1 has fadein, it must fadein second element ..etc
now I proceed like this:
I have tried to do a for loop, but they are executed in the same time.
for (i = 0; i < elems.length; i++) {
myFunc(elem[i], function(){
if (elem[i+1]) {
myFunc(elem[i+1]);
}
});
}
So how would you proceed?
Do like this, A recursive solution for your problem,
function myFunc(elems, cnt)
{
if(cnt > (elems.length - 1)) { return; }
$(elems[cnt]).fadeIn("slow", function(){ myFunc(elems , ++cnt); });
}
myFunc(['#elem1', '#elem2_3', '#elem4_5', '#elem3', '#elem_five'], 0);
DEMO
Update on link:
http://jsfiddle.net/kuw6tt92/1/
function fadeIn(selectors) {
var elements = Array.prototype.slice.call($(selectors));
function fade() {
jQuery(elements.shift()).fadeIn("slow", fade);
}
fade();
}
fadeIn("div");
try
var elems = ['#elem1', '#elem2_3', '#elem4_5', '#elem3', '#elem_five'];
var len = elems.length;
function myFunc(index) {
$(elems[index]).fadeIn(function () {
if (len > ++index) myFunc(index);
return;
});
}
myFunc(0);
DEMO

Categories

Resources