How to prevent multiple duplicate events from being registered?

4k Views Asked by At

I have a situation where a .js library is registering a mouseup event to a DOM element. The DOM element is removed, and replaced and the event is re-registered. This causes two duplicate events to be registered. Here is a reproduction for example:

Please Note: This is using jQuery version 1.4.4

<div id="top">
 <div id="nested">
  <div id="stranded">
   Alien Code
  </div>
 </div>
</div>​

<script type="text/javascript">
 function addLive(){
  $("#stranded").live("mouseup",
   function (e) {
    var node = document.getElementById("stranded");
    var nodeCopy = $(node).clone(true)[0];
    var tar  = document.getElementById("nested");
    tar.appendChild(nodeCopy);
   }
  );
 }
 addLive();
 addLive();
</script>

Also, here is a jsFiddle: http://jsfiddle.net/3zbtK/

How can I prevent the second call to addLive from registering the mouse event if one already exists?

4

There are 4 best solutions below

0
On BEST ANSWER
function addLive(){
 $("#stranded").die("mouseup");
 $("#stranded").live("mouseup",
  function () {
   var node = document.getElementById("stranded");
   var nodeCopy = $(node).clone(true)[0];
   var tar  = document.getElementById("nested");
   tar.appendChild(nodeCopy);
 }
);
}
2
On

why are you calling addLive() function twice?

remove one, it will work :)

0
On

You can try to remove the event handler before registering the newer better one.

Failing that, if you're issue is with the default handlers, you can ignore them.

I think what you're looking for is preventDefault

<script>
$("a").click(function(event) {
  event.preventDefault();
  $('<div/>')
    .append('default ' + event.type + ' prevented')
    .appendTo('#log');
});
</script>

also you can test for it

For example, clicked anchors will not take the browser to a new URL. We can use event.isDefaultPrevented() to determine if this method has been called by an event handler that was triggered by this event.

7
On

You don't exactly tell us what your editing contraints are and what code you can change.

The simplest thing would be to stop using .live() and just attach the event directly to the object. Then, when the object is removed, so is the event handler.

If you can't do that for other reason, then you also keep track of whether the event handler has been installed already, either in a global variable or using jQuery's .data() on the #stranded element.

P.S. .live() has been deprecated and you should be using .on() (jQuery 1.7+) or .delegate() (jQuery before 1.7) for all versions of jQuery.