Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery functions executing multiple times

I've found similarly titled questions on SO, but none seem related to my issue.

This one has been driving me nuts all day and most of the night.

First, the what the running code looks like:

enter image description here

Next, an MCV version of my code:

<!DOCTYPE html>
<!-- file: index2.html -->
<html>
<head>
    <link rel="stylesheet" href="css/style2.css">
</head>
<body>
    <form id="form-container">
        <button id="submit-btn">Make things happen</button>
    </form>
    <div id="toggler">Click this to toggle Stuff</div>
    <div id="stuff-container">
        Stuff
    </div>
    <script src="js/libs/jquery.min.js"></script>
    <script src="js/script2.js"></script>
</body>
</html>
// file: script2.js
function loadData() {
    $('#toggler').hover( 
        function() {
            $(this).css('cursor', 'pointer');
        },
        function() {
            $(this).css('cursor', 'text');
        });

    $('#toggler').click(function() {
        $('#stuff-container').toggle();
    });

    return false;
};
$('#form-container').submit(loadData);
/* file: style2.css */
#stuff-container {
    display: block;
}

And the behavior:

  1. navigate to index2.html

Run #1:

  1. click button "Make things happen"
  2. hover over "Click this to toggle Stuff"
    -- cursor changes to a hand
  3. click "Click this to toggle Stuff"
  4. "Stuff" toggles correctly.

Run #2:
Steps 1, 2, 3 as before.

  1. "Stuff" does not toggle.

Using console.log() calls, I found that each function in script2.js executes multiple times if the "Make things happen" button has been clicked more than once.

e.g., if the button has been clicked 5 times since page reload, when I do Step 2 above, the first .css() in hover() is executed 5 times.

So, if the button has been clicked any even number of times, the toggle() calls have no effect.

The questions:

What (probably very basic) concept am I missing? How do I prevent the multiple executions of each function?

like image 564
jazcap53 Avatar asked Dec 07 '25 06:12

jazcap53


1 Answers

That is because the $('#toggler').hover and $('#toggler').click() binds new (additional) event handlers each time it is executed. And you execute those each time you press on the button which in turn runs the loadData function.

So,

  • First run, you bind hover/click handlers (one bound handler): runs fine
  • Second run, you bind another hover/click handler (two bound handlers): problem because first handler toggles on while second toggles off
  • third run,.... (three bound handlers): runs fine (but only because it is toggled on/off/on)

In general it will work on the odd runs and fail on the even ones.

You should only bind once.


On solution is to unbind before re-binding

$('#toggler').off('mouseenter mouseleave').hover(...);
$('#toggler').off('click').click(...);

But it really depends on what other things you want to do inside the loadData function.

like image 182
Gabriele Petrioli Avatar answered Dec 08 '25 20:12

Gabriele Petrioli