1

I have a jQuery slider on my WP website.

When clicking repetitively (without waiting between the clicks) on the arrows to move slides it continues to slide more slides + I have an "addClass" and "removeClass" that makes the image in the centre grow bigger and smaller

how it looks:

The problem when clicking too fast

How do I create a pause in clicks when clicking reverentially?

This is my code part:

/**************** Slider STUFF ****************/

//relevant slide parameters: 
var singleSlide         = '14.5em'; 
var slideAnimationSpeed = 500;
var currentSlide        =  5;

//cache DOM
var $slider         = $('.slider'); 
var $slideContainer = $slider.find('.slides'); 
var $slides         = $slideContainer.find('.slide');
var totalSlides     = $slides.length;

console.log('Total Slides: '+ totalSlides);

// Adds an Id to all li-images 
$slides.attr('id', function(i) {
   return 'slide_'+(i+1);
});

//Add a shadowe for the next Client 
function addTheShadowRight(currentSlide){
    nextSlide = currentSlide + 1 ;
    $('#slide_'+currentSlide).removeClass("sliderPoiner");
    $('#slide_'+nextSlide).addClass("sliderPoiner");
}

//Add a shadowe for the previous Client 
function addTheShadowleft(currentSlide){
    prevSlide = currentSlide - 1 ;
    $('#slide_'+currentSlide).removeClass("sliderPoiner");
    $('#slide_'+prevSlide).addClass("sliderPoiner");
}

//When clicking on the right: 
$('.scroll-right').click(function(){
    //margin-left the slide including -= :
    $slideContainer.stop().animate({'margin-left': '-='+singleSlide}, slideAnimationSpeed, function(){
        currentSlide++;
        console.log('Current Slide: '+ currentSlide);
        if ((currentSlide+1) === totalSlides) {
            $('#slide_'+currentSlide).removeClass("sliderPoiner");              
            currentSlide = 5;
            $('#slide_'+currentSlide).addClass("sliderPoiner");
            $slideContainer.css('margin-left', '-42em');
        }
    });
    addTheShadowRight(currentSlide);
})

//When clicking on the left: 
$('.scroll-left').click(function(){
    //margin-left the slide including -= :
    $slideContainer.stop().animate({'margin-left': '+='+singleSlide}, slideAnimationSpeed, function(){
        currentSlide--;
        console.log('Current Slide: '+ currentSlide);
        if ((currentSlide) === 3) {
            $('#slide_'+currentSlide).removeClass("sliderPoiner");                              
            currentSlide = 24;
            $('#slide_'+currentSlide).addClass("sliderPoiner");
            $slideContainer.css('margin-left', '-317.5em');  
        }
    });
    addTheShadowleft(currentSlide);
})




// ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~

I used the .stop() function before the .animate - but it seems like nothing is happening.

note: When clicking on the arrows and waiting between every click, it slides fine. The problem is only when clicking fast.

Imnotapotato
  • 5,308
  • 13
  • 80
  • 147

3 Answers3

0

What you're trying to do is called throttling or debouncing. There are multiple plugins available to do this, but I'd recommend jQuery throttle/debounce by Ben Allman. Just wrap your click handlers in the throttle function:

$('.scroll-right').click(function(){
     $.throttle(250, function(){
          //handle click event
     });
});

There's also a debounce function in the plugin, but it sounds like throttle is the one you want. The difference is subtle, but debounce won't fire the handler until the user is "done" (meaning he/she stops clicking for a second or two).

Justin Morgan - On strike
  • 30,035
  • 12
  • 80
  • 104
0

How about using a setTimeout() to set a global var

//Global var
var timeout = false;

//When clicking on the right: 
$('.scroll-right').click(function(){
    //only do stuff when timeout is false
    if (!timeout) {
        //margin-left the slide including -= :
        $slideContainer.stop().animate({'margin-left': '-='+singleSlide}, slideAnimationSpeed, function(){
            currentSlide++;
            console.log('Current Slide: '+ currentSlide);
            if ((currentSlide+1) === totalSlides) {
                $('#slide_'+currentSlide).removeClass("sliderPoiner");              
                currentSlide = 5;
                $('#slide_'+currentSlide).addClass("sliderPoiner");
                $slideContainer.css('margin-left', '-42em');
            }
        });
        addTheShadowRight(currentSlide);

        //set timeout to true and back to false after 500 milliseconds
        timeout = true;
        setTimeout(function(){ 
            timeout = false;
        }, 500);
    }
});

So basically clicking really fast on the button wouldn't trigger the function. Which should solve your problem.

You can do the same for scroll-left

Note: This might not be the best solution, but it should work.

Update: To disable double click selection you could use this:

function clearSelection() {
    if(document.selection && document.selection.empty) {
        document.selection.empty();
    } else if(window.getSelection) {
        var sel = window.getSelection();
        sel.removeAllRanges();
    }
}

Or you could use this CSS trick:

span.no_selection {
    -webkit-user-select: none; /* webkit (safari, chrome) browsers */
    -moz-user-select: none; /* mozilla browsers */
    -khtml-user-select: none; /* webkit (konqueror) browsers */
    -ms-user-select: none; /* IE10+ */
}

Please remember this is default browser behavior you are going to disable.

Source

Community
  • 1
  • 1
Bram
  • 2,515
  • 6
  • 36
  • 58
  • When over-clicking on the arrow - it works! BUT! It gets everything marked. ---- Just to make sure I understand the 'setTimeout' thing. So you turn the variable into true after doing all the 'click stuff', then you give it half a second, and then turn it back to true. Am I getting it right? --- I'm not sure it's the best solution, but I'm gonna wait for more comments about this.. Thanks a lot! If I wont find any solution I'll mark it as solved. – Imnotapotato Apr 13 '15 at 14:46
  • @Hatul That selecting problem is default browser behavior. When you double click on something it will select the text. I think you can solve that with this => http://stackoverflow.com/a/880518/2932698 Yes you are right. When you click on it it will set the variable timeout to true and will set the timeout. So if you click on the buttons during the timeout it wouldn't do your stuff again untill the timeout sets the variable back to false. – Bram Apr 13 '15 at 16:04
  • @Hatul Tried that piece of code to disable the double click select? I added the code to my answer – Bram Apr 14 '15 at 07:48
  • Or you can just use e.preventDefault() as pointed out in my answer – patman Apr 14 '15 at 10:11
-1

Okay here's a solution with a saved timestamp:

var lastClick = 0;
//When clicking on the left: 
$('.scroll-left').click(function(e){
    if(lastClick + slideAnimationSpeed > Date.now()) {
        return e.preventDefault();
    }
    lastClick = Date.now();

    //margin-left the slide including -= :
    $slideContainer.stop().animate({'margin-left': '+='+singleSlide}, slideAnimationSpeed, function(){
        currentSlide--;
        console.log('Current Slide: '+ currentSlide);
        if ((currentSlide) === 3) {
            $('#slide_'+currentSlide).removeClass("sliderPoiner");                              
            currentSlide = 24;
            $('#slide_'+currentSlide).addClass("sliderPoiner");
            $slideContainer.css('margin-left', '-317.5em');  
        }
    });
    addTheShadowleft(currentSlide);
})

Make sure to implement the same block for .scroll-right.

Not that you can increase cross browser compatibility by adding

if (!Date.now) {
  Date.now = function now() {
    return new Date().getTime();
  };
}

see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Date/now

patman
  • 2,780
  • 4
  • 30
  • 54
  • To the person who downvoted this: please explain why? This is a more complete answer than the one with timeout (see double click selection problem). And aso a completely valid solution. – patman Apr 14 '15 at 10:15