PushALU
PushALU

Reputation: 277

jquery click event fireing off when I attach it with 'on'

I'm making an application where I 'have' to enable and disable mouseenter/leave and click on a div frequently. But I've run into a problem where I use the enable function but this will cause it to run prematurely, without the user have clicked anything.

I have a outter div which contain six small divs. When the user clicks the outer outter div the smaller div will get their mouseenter/leave and click event attached whilst the outter div will get its turned off. And then in reverse once a small box is clicked.

below functions disables and enables the events for the divs.

function enableHalve(){
            $("#top-wrapper, #bottom-wrapper").on({
                mouseenter: function (e) {
                    e.preventDefault();
                    $(this).css("background-color", "#00cc66");
                    $(this).css('cursor','pointer');
                },
                mouseleave: function (e) {
                    e.preventDefault();
                    $(this).css("background-color", "#c0c0c0"); 
                }
            });  

            $("#top-wrapper, #bottom-wrapper").on({
                click: function(e) {
                e.preventDefault();
                update($(this).attr('id'));
            }});
        }

        function disableHalve(){
            $("#top-wrapper, #bottom-wrapper").off('click');
            $("#top-wrapper, #bottom-wrapper").off('mouseenter').off('mouseleave');                 
            $("#top-wrapper, #bottom-wrapper").css({'cursor' :"default"});
            $("#top-wrapper, #bottom-wrapper").css({'background-color' :"#c0c0c0"});
        }   

        function disableBoxes(){
            $("#one, #two, #three, #four, #five, #six, #seven, #eight, #nine, #ten, #eleven, #twelve").off('click');                
            $("#one, #two, #three, #four, #five, #six, #seven, #eight, #nine, #ten, #eleven, #twelve").off('mouseenter').off('mouseleave');
            for (var y = 0; y < boxes.length; y++) {
                $("#"+boxes[y]+"").css("background-color", "blue"); 
                $("#"+boxes[y]+"").css('cursor','default');
            }
        }

        function enableBoxes(){
            $("#one, #two, #three, #four, #five, #six, #seven, #eight, #nine, #ten, #eleven, #twelve").on({
                click: function(e) {
                e.preventDefault();
                update($(this).attr('id'));
            }});

            $("#one, #two, #three, #four, #five, #six, #seven, #eight, #nine, #ten, #eleven, #twelve").on({
                mouseenter: function () {
                    $(this).css("background-color", "#00cc66");
                    $(this).css('cursor','pointer');
                },
                mouseleave: function () {
                    $(this).css("background-color", "blue"); 
                }
            });     
        }

This function is triggered from the click event. 

function update(answer){            
            console.log("answer: " + answer);

            if(answer === "top-wrapper" || answer === "bottom-wrapper"){
                console.log("ny test");
                serverRequest(answer);

            }else if(boxes.indexOf(answer) > -1) {
                console.log(answer);
                zeroCount = zeroCount - 1;
                currentAnswerSequence = currentAnswerSequence + answer;
                console.log("Inde zero: " + zeroCount);

                if(zeroCount == 0){
                    //This part here will make the function trigger again, because the click event calls update()
                    disableBoxes(); 
                    enableHalve();
                    serverRequest(currentAnswerSequence);
                    currentAnswerSequence = "";
                }
            }       
        }

my html

<div id="top-wrapper">
    <div id="one"></div>
    <div id="two"></div>
    <div id="three"></div>
    <div id="four"></div>
    <div id="five"></div>
    <div id="six"></div>                
</div>

<div id="bottom-wrapper">
    <div id="seven"></div>
    <div id="eight"></div>
    <div id="nine"></div>
    <div id="ten"></div>
    <div id="eleven"></div>
    <div id="twelve"></div>             
</div>

Upvotes: 0

Views: 41

Answers (1)

castletheperson
castletheperson

Reputation: 33486

The issue is when the inner divs are clicked, the event still propogates up to the outer divs before the handler gets removed. To fix this, change e.preventDefault() to e.returnValue = false;. In jQuery, this is the same as calling both e.preventDefault() and e.stopPropagation().

jQuery objects can be given custom attributes using .data(). It would greatly simplify your code and speed it up if, instead of adding and removing event handlers, you do a check for if it should run using an if statement on something like .data("clickEnabled") or .data("mouseEnterEnabled"). Then to enable or disable the events, just set the custom attribute of the jQuery object by using .data("clickEnabled", false) or .data("clickEnabled", true).

Upvotes: 1

Related Questions