ben
ben

Reputation: 2047

calling javascript function too many times

I'm just getting into Javascript and I've run into the same problem a number of times with different pieces of code: I have a function that creates a type of element and a function that does something with that type of element. It seems obvious to me that I need to call the "do something" function after the element has been created, but when I do, it ends up running more times than I'd like.

Here's an example of my problem:

function rightClick(){
    $(".element").mousedown(function(e){
        switch (e.which){case 3: alert( $(this).attr("id") )};
    });
};

function doubleClick(){
    var counter = 0;
    $(document).dblclick(function(e){
        counter++;
        elementId = "element" + counter;
        $("#new_elements").append("<div class='element'"          +
                                   "id='"    + elementId + "'"   +
                                   "style='position:absolute;"   +
                                   "top:"    + e.pageY + ";"     +
                                   "left:"   + e.pageX + ";'>"   +
                                    elementId+ "</div>");
    rightClick();
});

In this example, if I create 4 elements and I right-click on the first one I created, I end up getting 4 alert boxes instead of one. If I right-click on the second element I created, I get three alerts; the third: 2 alerts; the fourth: one alert.

Can anyone explain to me why this is happening, and how to fix it so that I only get one alert each time I right-click on an element?

Upvotes: 2

Views: 1973

Answers (4)

aziz punjani
aziz punjani

Reputation: 25776

You do not need to bind the event everytime you insert and element into the DOM. You can use .on to attach event handlers for elements that are dynamically inserted.

$(document).on('mousedown','.element', (function(e){
    switch (e.which){
            case 3: alert( $(this).attr("id") ); 
            break; 
    };
});

var counter = 0;
$(document).dblclick(function(e){
    counter++;
    elementId = "element" + counter;
    $("#new_elements").append("<div class='element'"          +
                               "id='"    + elementId + "'"   +
                               "style='position:absolute;"   +
                               "top:"    + e.pageY + ";"     +
                               "left:"   + e.pageX + ";'>"   +
                                elementId+ "</div>");
});

Upvotes: 1

Jamund Ferguson
Jamund Ferguson

Reputation: 17014

  1. Binding is the act of associating an event with a DOM element. The .mousedown and similar events only bind on elements that already exist.
  2. Each time you call rightClick() you bind a new event to all current .element elements.
  3. You can bind functions to the same element as much as you'd like, which is why you see the function being called many times.
  4. For dynamic elements should checkout .on or .delegate which work like this:
Example of jQuery.fn.on
 $(document.body).on("mousedown", ".element", function(e) {
   if (e.which === 3) alert($(this).attr("id"));
 });
Example of jQuery.fn.delegate
 $(document.body).delegate(".element", "mousedown", function(e) {
   if (e.which === 3) alert($(this).attr("id"));
 });

Only call this once and you should be pretty much okay. If you're not using jQuery 1.7 or higher you will want to use .delegate() instead of .on.

Upvotes: 4

steve_c
steve_c

Reputation: 6255

You've bound your event handler to the class '.element'. This means that every element with the class '.element' on your page will fire that event when the right click occurs.

Upvotes: 0

ubik
ubik

Reputation: 4560

I believe you are adding the same handler several times, meaning that when you click a button you are re-binding the action to the same function.

Upvotes: 0

Related Questions