scorpio1441
scorpio1441

Reputation: 3088

jQuery-UI effect - double triggers event

Trying to solve this one for a long time, jsfiddle wont re-produce this code to show the problem.

'click' event is getting triggered twice on the element, which was previously processed with hide() and show('slide').

Doesn't happen when using show() or fadeIn(1000); Doesn't happen when moving event handler inside $(document).ready(){}.

I have to use this exact structure with <script></script> inside of the element. No way I can change it.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
<link href='/styles/jquery-ui-1.8.18.custom.css' rel='stylesheet' type='text/css'>
<script src='/js/jquery.js' type='text/javascript'></script>
<script src='/js/jquery-ui-1.8.18.custom.js' type='text/javascript'></script>
<script type='text/javascript'>
  $(document).ready(function() {
    $('#container').hide().delay(750).show('slide');
  });
</script>
</head>
<body>

<div id='container'>
  <div class='download'>Download</div>
  <script type='text/javascript' id='js4container'>
    $('.download').click(function() {
      alert('Trigger');
    });
  </script>
</div>

</body>
</html>

I understand that show() does launch the inside of <script></script> once more, binding same event.

Is there a workaround? =)

Please help. Thanks.

Upvotes: 0

Views: 971

Answers (1)

Jeff B
Jeff B

Reputation: 30099

You can always use .one(), which only fires on the first event. But you may still end up with multiple .one() triggers if you don't click between each call to .one():

$('.download').one('click', function() {
     alert('Trigger');
});

Or, remove the handler(s) each time with .off():

$('.download').off('click').on('click', function() {
     alert('Trigger');
});

This can also be written in the delegate syntax attached to #container or body:

$('body').off('click', '.download').on('click', '.download', function() {
     alert('Trigger');
});

Demo: http://jsfiddle.net/QnfMZ/1/

The reason this happens is that jQuery UI uses helper elements to create transitions. They maintain correct layout, etc while the animation is occuring. These helper elements are created using clone() which copies the html of the element, which in your case means it copies the script, too. The script then runs, adding a second handler. After the transition is done, the helper clone is deleted, but you are still left with an extra handler.

Upvotes: 3

Related Questions