click event firing multiple times in loop - javascript

I am firing click event inside the loop.it fires multiple times .
How can i stop firing multiple time.
My code:-
var myArray = [1,2,3,4,5,6];
var i;
for(i=0;i<myArray.length;i++){
$(".Mydiv").click(function(){
alert(myArray[i]);
});
}
just example code.
Actually, I am updating every second Mydiv attr id using jQuery attr to get current user.
so when i click mydiv i should only get the current user id. but i fires all.
Thanks

If I understood you well, this is the solution:
var myArray = [1,2,3,4,5,6];
var i = 0;
$(".Mydiv").click(function(){
alert(myArray[i]);
if(i < myArray.length-1) i++;
});
Hope this helps. Cheers

You cannot fire events in a loop using .click() it is binding a handler to an event for the element or elements found for the selector. To trigger a click you use .trigger()
But in order to access the attribute of a clicked element what you need is this:
$(".Mydiv").click(function(){
alert($(this).attr('id'));
});
While you are binding to all elements in the class, the $(this) means you are only acting on the element that was clicked.

In original code ,it bind click event myArray.length times,you just need to bind once.
so you can just simply do like this:
var myArray = [1,2,3,4,5,6];
var i = 0;
$(".Mydiv").click(function(){
alert(myArray[i]);
//here change the i
i = (i+1)%length ;
});

Related

How to set up a click event on HTML elements( li ) with JavaScript?

I am having some issues with running a click event.
My purpose is just to track click events basically, very simple stuff. For visual changes I was going to check one of my links to change the HTML text. When I run this code at the moment I get an error:
"document.getElementsByTagName(...).addEventListener is not a function"
var links = document
.getElementsByTagName("a")
.addEventListener("click", myFunction);
function myFunction() {
document.querySelector(".contact-link").innerHTML = "clicked!";
}
You need to loop through all the elements and then add the event listener
var list = document.getElementsByTagName("a");
for(let i=0; i<list.length; i++) {
list[i].addEventListener("click", myFunction);
}
function myFunction() {
console.log("clicked");
}
<span class="contact-link">ABC</span>
<span class="contact-link">DEF</span>
<span class="contact-link">GHI</span>
You can't set the event listener to all elements of the collection at once. You need to iterate over it and set the event listener for each one.
Hope it helps you!

Getting the source of this click event in JQuery

I have multiple dynamically created buttons with the same class on my page and when I try to call a function on the click of the button, the function gets called for all of the buttons with the same class.
I want the function to be called for this click event only.
Here is my function:-
$(".js-btn-plus").click(function (e) {
var link = $(e.target);
var val = link.next('.value').text();
val++
link.next('.value').text(val);
});
Maybe generate unique ID for the button and use that as an event reference instead of the class?
.text() returns a string. Convert the string val to a number
val = Number(val) + 1
or
val = +val++
Please could you provide some sample HTML to alongside the JQuery?
From what I can see you may want to have a look at using $(this) instead of e.target
$(document).on('click', '.js-btn-plus', function() {
var val = parseInt( $(this).find('.value').text() );
val++;
$(this).find('.value').text(val);
});
Not 100% sure what it is that you're trying to achieve, there may be a better way of doing it if you could explain a little bit more and provide some HTML to go alongside your question.
Edit: Using the 'on' function allows you to dynamically bind the function events instead of having them have a listener fire when the script is loaded and executed.
My solution:
$(".js-btn-plus").click(function (e) {
var val = parseInt($(this).next('.value').text());
val++;
$(this).next('.value').text(val);
});

click function within another click function is called multiple times

i am in touch with jquery for the first time and ran into this: I am trying to create a dynamic input-form. A click function creates a new list-item with another click function nested into it (to provide a remove function for the clicked item).
When i execute the nested click function it appears to be called the number of instances that have been created of it.
Here is the code (i tried to remove as much as possible, but i am not quite sure where the error is - so i guess i left to much stuff in - sorry).
$("#addIngredient").click(function(e){
e.preventDefault();
var prefix = "form-"
var last = $("#IngredientForm ul li").last().html();
$("#IngredientForm ul").append("<li>"+last+"</li>");
var name = $("#IngredientForm ul li:last input").attr("name");
name = name.replace(prefix,'');
var count = parseInt(name[0]);
count += 1;
$("#IngredientForm ul li:last input").attr("name",prefix+count+"-weight")
$("#IngredientForm ul li:last select").attr("name",prefix+count+"-ingredient")
$("#IngredientForm ul li:last input").attr("id","id_"+prefix+count+"-weight")
$("#IngredientForm ul li:last select").attr("id","id_"+prefix+count+"-ingredient")
$("#id_form-TOTAL_FORMS").val(count+1);
$(".deleteIngredient").click(function(e){
e.preventDefault();
var aktuell = $(this).closest('li');
var formCount;
name = aktuell.children('input').attr("name");
name = name.replace(prefix,'');
counter = name.replace("-weight",'');
formCount = parseInt($("#id_form-TOTAL_FORMS").val());
aktuell.remove();
--formCount;
$("#id_form-TOTAL_FORMS").val(formCount);
for (var i = parseInt(counter); i<formCount; i++){
var newName = "form-"+(i);
$("#id_form-"+(i+1)+"-weight").attr("name",newName+"-weight");
$("#id_form-"+(i+1)+"-ingredient").attr("name",newName+"-ingredient");
}
});
});
This block
$(".deleteIngredient").click(function(e){...
attaches a clickevent to all .deleteIngredient elements, also those created before.
You have to put this block outsite the click event of #addIngredient. You can make the delete event to be attached also to every element added in the future.
$("#addIngredient").click(function(e){
// ...
});
$(document).on("click", ".deleteIngredient", function(e){
// ...
});
As the other answers have noted, the click handler is adding a click handler to every .deleteIngredient element every time you run it, which adds multiple handlers to all the previous elements.
When you add a new item to the list, you don't have to add a click handler to it. You can use delegation to create a handler one time that will apply to dynamically-added elements:
$("#IngredientForm").on("click", ".deleteIngredient", function(e) {
...
});
See Event binding on dynamically created elements? for more information.
Every time that outer "click" event happens, you're adding another "click" handler for the ".deleteIngredient" element(s). The .click function does not remove previously-assigned event handlers.
You can get rid of old handlers with .unbind or, preferably with new versions of jQuery, .off:
$('.deleteIngredient').unbind('click').click(function(event) {
// ...
});
No, the thing is, here I think you probably want to bind to the .deleteIngredient button that you're adding for the new ingredient. The code you've got — based on the reference to $('.deleteIngredient') — will affect all of the elements on the page with that class. My guess here is that you're adding a button or something for each <li>. Thus, what you should probably be doing is finding the button inside the newly-added structure:
$('#IngredientForm ul li:last .deleteIngredient').click(function(event) {
// ...
});
Use this format instead
$("#addIngredient").on('click', function() {
$(this).off();
});

Writing this jQuery click function in JavaScript

I am slowly making my way from jQuery to vanilla JS, but I am struggling with wanting to write the following in JavaScript, would I have to setup a 'for' loop for each element? How would I target the child elements an an ID?
Here's what I would want to understand:
$('#id li').click(function(){
$(this).addClass('active');
});
I understand document getElementById to grab the '#id' but how would I achieve getting the child <li> elements? And how would I get the 'onclick' function to work for ANY list element clicked? Would I have to setup a 'for' loop for each element? Any help much appreciated!
Here is a JSFiddle that does what you want:
http://jsfiddle.net/digitalzebra/ZMXGC/10/
(function() {
var wrapper = document.getElementById("id");
var clickFunc = function(event) {
var target = event.originalTarget || event.target;
target.className = "active";
};
wrapper.addEventListener("click",clickFunc);
})();
A little bit of an explanation is in order...
First, I'm using a self executing function to fetch the wrapper div, using getElementById(). This is equivalent to using an id selector in jQuery: $('#id')
Next, I'm attaching a click handler to the element using the function addEventListener() and passing in an event type of click.
This binds the click handler function to the div element, the same as jQuery's click() would do. I'm using something called event bubbling, where a click event on any of the children of the wrapper will call the click handler attached to the wrapper.
Once the user clicks on the element, our function is called. originalTarget or target is the element that the user actually clicked in to, which in this case will always be an li. I'm then setting the class on that element to active.
Here is example for above question
http://jsfiddle.net/G3ADG/2/
(function() {
var id = document.getElementById("id");
var liele = id.getElementsByTagName("li");
for (var i = 0; i < liele.length; i++) {
liele[i].addEventListener("click", function () {
this.className = "active";
})
}
})();
Well I really liked Polaris878 solution as he is not using any loop inside it. In my solution first get HTML node information using document.getElementById this works similarly to $("#id"). than in next step I am fetching all tag type of "li" which are children of "id", than on this li tag array adding event listener to listen click functionality
className is one of attribute that allow to add class on that Node
I have tested above code in mozilla and chrome
This will work (IE >= 10), not want to search classList.add() replacement for IE<10,
var elems = document.querySelectorAll('#id li');
for (var i = 0; i < elems.length; i++) {
var elem=elems[i];
elem.addEventListener("click", function (e) {
this.classList.add('active');
});
}
fiddle

Way to remove javascript events from the html tags?

Is there any way to remove all the javascript events from the html tags?
For example
<img src=" " onclick="" />
<img src=" " onerror="" />
I want to strip onclick and onerror from these tags. As in the example, I want to strip all the javascript events from the html tags.
You can do this to clear the events :
// get all img elements
var imgElements = document.getElementsByTagName('img');
// loop elements
for (var i = 0; i < imgelements.length; i++) {
// clear handler
imgElements[i].onclick = null;
// add other handlers here
// imgElements[i].<here> = null;
}
Docs for getElementsByTagName() here
Update 1 - All elements on document
If you want to get all of the elements on the document then use document.getElementsByTagName('*')
Update 2 - All events
To clear all events have a look at this answer
You can check out jquery .unbind().
Reference: http://api.jquery.com/unbind/
It's also easy to put the event handler back when you need it using .bind()
by using jquery:
$('*').each(function(){
if ($(this).is('img')) {
$(this).unbind('click');
}
});
if you want to only remove the specific function onclick event, you can do like this..
$(this).unbind('click', FunctionName);
As of jQuery 1.7, you are also able use $.on() and $.off() for event binding, so to unbind the click event, you would use the simpler and tidier:
$(this).off('click');
If you mean "remove" as in physically remove them from the page source, you could probably use a regular expression to get most of them, replacing pattern on(\w+?)="(.*?)" with a blank string. (I've not tested, it may need tweaking)
If you mean "remove" as in logically remove them by unbinding them, you could use the unbind() method in jQuery, or set each event to null looping through the DOM.
Try this javascript in the document.onload event (untested):
var all = document.getElementsByTagName('*');
for (var i = 0; i < all.length; i++) {
all[i].onclick = undefined;
all[i].onerror = undefined;
}

Categories

Resources