简体   繁体   中英

stop mouse double click on certain elements with javascript

I have a small navigation menu with sliding images when the user clicks on the image or an arrow. The images slide by changing their background position over a png image file with a .5s css transition.

When a user clicks on the menu, I grab the x postion of the element & increment it. It takes .5 seconds for this to complete so if the user double clicks while the image is moving it messes up the css position by changing it twice.

I think the best solution would be to disble the user from double clicking on these buttons within .5s, is there a way to do this?

Below is the relevent excerpt from JS

    function getXAxis (div, val){
        var x_axis = div.css("background-position");
        x_axis = x_axis.split("px");
        x_axis = x_axis[0];
        x_axis = parseInt(x_axis);
        x_axis = x_axis + val;
        return x_axis;
    }

    function rotateControlsRight(){
        x = getXAxis(hpLeftArrow, 9);
        hpLeftArrow.css("background-position", x+"px 0px");
        x = getXAxis(hpPosition1, 57);
        hpPosition1.css("background-position", x+"px -2px");
        x = getXAxis(hpPosition2, 65);
        hpPosition2.css("background-position", x+"px -1px");
        x = getXAxis(hpPosition3, 57);
        hpPosition3.css("background-position", x+"px -2px");
        x = getXAxis(hpRightArrow, 9);
        hpRightArrow.css("background-position", x+"px -15px");
        console.log("moving RIGHT by "+x);

    }

    function rotateControlsLeft(){
        x = getXAxis(hpLeftArrow, -9);
        hpLeftArrow.css("background-position", x+"px 0px");
        x = getXAxis(hpPosition1, -57);
        hpPosition1.css("background-position", x+"px -2px");
        x = getXAxis(hpPosition2, -65);
        hpPosition2.css("background-position", x+"px -1px");
        x = getXAxis(hpPosition3, -57);
        hpPosition3.css("background-position", x+"px -2px");
        x = getXAxis(hpRightArrow, -9);
        hpRightArrow.css("background-position", x+"px -15px");
        console.log("moving Left by "+x);

    }


    hpLeftArrow.click(function(){
        checkForChange = hpSlidePosition;
        hpPrevPosition = hpSlidePosition;
        if (hpSlidePosition > 1 ){
            -- hpSlidePosition;
        } else {
            hpSlidePosition = 1;
        }
        hpMovingRight = false;
        rotateControlsLeft();

        hpInitSlide()

    });

    hpRightArrow.click(function(){
        checkForChange = hpSlidePosition;
        hpPrevPosition = hpSlidePosition;
        if (hpSlidePosition < 3 ){
            ++ hpSlidePosition;
        } else {
            hpSlidePosition = 3;
        }
        hpMovingRight = true;
        rotateControlsRight();

        hpInitSlide()
    });

May I suggest you to declare some "in progress" flag? For example set some global variable in onclick handler and reset it when animations ends.

the best way would be to check to see if the element is animating, if so, then skip the function:

var leftCheck=false;
hpLeftArrow.click(function(){
    if(!leftCheck){
        leftCheck=true;
        checkForChange = hpSlidePosition;
        hpPrevPosition = hpSlidePosition;
        if (hpSlidePosition > 1 ){
            -- hpSlidePosition;
        } else {
            hpSlidePosition = 1;
        }
        hpMovingRight = false;
        rotateControlsLeft();

        hpInitSlide();
        setTimeout(function(){
            leftCheck=false;
        },500);
    }
    });
    var rightCheck=false;
    hpRightArrow.click(function(){
      if(!rightCheck){
        rightCheck=true;
        checkForChange = hpSlidePosition;
        hpPrevPosition = hpSlidePosition;
        if (hpSlidePosition < 3 ){
            ++ hpSlidePosition;
        } else {
            hpSlidePosition = 3;
        }
        hpMovingRight = true;
        rotateControlsRight();

        hpInitSlide();
        setTimeout(function(){
            rightCheck=false;
        },500);
      }
    });

You can define a variable which tells if the motion (Left or Right) status is complete or not.

var motionComplete = true;

hpLeftArrow.click(function(){
       if(motionComplete) // check complete or not
      {
        motionComplete = false;// set motion started
        checkForChange = hpSlidePosition;
        hpPrevPosition = hpSlidePosition;
        if (hpSlidePosition > 1 ){
            -- hpSlidePosition;
        } else {
            hpSlidePosition = 1;
        }
        hpMovingRight = false;
        rotateControlsLeft();

        hpInitSlide(); // you missed semicolon here
        motionComplete = true;// set motion complete
      }
    });

    hpRightArrow.click(function(){
     if(motionComplete)// check complete or not
      {
        motionComplete = false;// set motion started
        checkForChange = hpSlidePosition;
        hpPrevPosition = hpSlidePosition;
        if (hpSlidePosition < 3 ){
            ++ hpSlidePosition;
        } else {
            hpSlidePosition = 3;
        }
        hpMovingRight = true;
        rotateControlsRight();

        hpInitSlide(); // you missed semicolon here
        motionComplete = true;// set motion complete
      }
    });

Method 1: i am not very sure of this but it should work. The handler which handle click check the event.type.

If event.type == "dblclick"
then return

Method2: Like the person before me answered. Enable a flag and then disable it after the animation is complete. As far as i know there is a callback to indicated animation complete or may be a jquery callback

Method3: When you register the click event register it to a className say class = "slideOnClick" ie $(document).on("click",".slideOnClick",handler); remember not to use $(".slideOnClick").on("click"); after you start the animation remove the className and when the animation is done add back the className. This way when a user does double click the first click results in animation and the second click does not untill animation is complete and className is added back.

Method4: Have a data-* attribute on the element being animated. Say data-animationState = "idle"/"progress"/"complete". And apply the animation only when data-animationState!="progress"

Method5: Similar to method 3 but instead of changing the className of element clicked, change the className of element which is being animated ie apply animation to the class="animateElement" and when in progress change it to class="animateElementInProgress" and after complete change it back to class="animateElement"

Thanks for all your help, in the end I used a variable to store the state of the slide, by setting it's value to true if the slide was active, and then setting it back to false after .5s.

var rotateFlag = false;
function rotateControlsLeft(){
    if(!rotateFlag){
        x = getXAxis(hpLeftArrow, -9);
        hpLeftArrow.css("background-position", x+"px 0px");
        x = getXAxis(hpPosition1, -57);
        hpPosition1.css("background-position", x+"px -2px");
        x = getXAxis(hpPosition2, -65);
        hpPosition2.css("background-position", x+"px -1px");
        x = getXAxis(hpPosition3, -57);
        hpPosition3.css("background-position", x+"px -2px");
        x = getXAxis(hpRightArrow, -9);
        hpRightArrow.css("background-position", x+"px -15px");
        rotateFlag = true;
        setTimeout(function(){
            rotateFlag=false;
        },500);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM