Note that there are some explanatory texts on larger screens.

plurals
  1. POjQuery debounced slideshow skips slides
    text
    copied!<p>I have written a plugin for my personal homepage, which is supposed to scroll through a series of elements, snapping to each elements offsetTop.<br> I am using <em>requestanimationframe</em> to debounce the scrolling events but sometimes slides are being skipped and I just can't figure why. <strong>Additionally</strong> on Chrome and Safari I have the problem that <em>window.pageYOffset</em> can be smaller than 0 and bigger than document hight because of some kind of easing those browsers are using on mac (with the touchpad) – how would you handle that?</p> <p>Here is the Code:</p> <pre><code>// requerstanimationframe for all browsers window.rAF = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }; })(); // main plugin code var Slides = { el: ".slide", arrowUp: $(".btn-previous"), arrowDown: $(".btn-next"), lastSlide: 0, lastY: 0, scrolling: false, scrollSpeed: 500, init: function(){ this.$elem = $(this.el); this.catchSlides(); this.newPos(true); // event handler this.registerHandler(); return this; }, registerHandler: function(){ var that = this, handler = { "resize.slider": jQuery.proxy(this.onResize,this), "scroll.slider": jQuery.proxy(this.onScroll,this), "keydown.slider": jQuery.proxy(this.keyhandler,this), "mousedown.slider": function(){ that.scrolling = true; }, "mouseup.slider": function(){ that.scrolling = false; } }; $(window).on(handler); $(".btn").on("click.slider", jQuery.proxy(this.btnhandler,this)) }, catchSlides: function(){ // count slides and save selectors var array = []; for(var i=0; i&lt;this.$elem.length; i++){ var el = this.$elem.eq(i); array[i] = el; } this.elements = array; this.slideCount = this.elements.length; }, getPositions: function(){ // what are the postions of those slides? var array = []; for(var i=0; i&lt;this.slideCount; i++){ var el = this.elements[i]; array[i] = el[0].offsetTop; } this.posArray = array; }, arrows: function(){ if(this.slideCount&gt;1){ switch(this.lastSlide) { case 0: // erster slide if(this.arrowUp.is(":visible")) this.arrowUp.hide(); if(!this.arrowDown.is(":visible")) this.arrowDown.show(); break; case this.slideCount-1: // letzter slide if(this.arrowDown.is(":visible")) this.arrowDown.hide(); if(!this.arrowUp.is(":visible")) this.arrowUp.show(); break; default: this.arrowUp.show(); this.arrowDown.show(); } } else { this.arrowUp.hide(); this.arrowDown.hide(); } }, getY: function(){ return window.pageYOffset; }, newPos: function(jump){ // go to the new coordinate, hide one of those arrows // if first or last slide this.arrows(); this.getPositions(); this.jumpTo(jump); }, clear: function(){ this.lastY = this.getY(); this.scrolling = false; }, onResize: function(){ if(!this.scrolling){ rAF(jQuery.proxy(this.newPos,this)); } this.scrolling = true; }, onScroll: function(){ if(!this.scrolling){ rAF(jQuery.proxy(this.update,this)); } this.scrolling = true; }, update: function(){ // which direction did the user scroll? if(this.lastY&lt;this.getY()){ // down? this.slide("down"); } else if(this.lastY&gt;this.getY()){ // or up? this.slide("up"); } else this.clear(); }, slide: function(string){ if(string==="down" &amp;&amp; this.lastSlide&lt;this.slideCount-1){ this.lastSlide++; this.newPos(); } else if(string==="up" &amp;&amp; this.lastSlide&gt;0){ this.lastSlide--; this.newPos(); } else this.clear(); }, jumpTo: function(jump, slideIndex){ var that = this, slideIndex = slideIndex || this.lastSlide, destination = this.posArray[slideIndex]; this.scrolling = true; if(jump &amp;&amp; jump!==undefined){ // jump to position without animation $("html,body").stop().animate({scrollTop: destination}, 0, function(){ that.clear(); }); } else $("html,body").stop().animate({scrollTop: destination}, this.scrollSpeed, function(){ that.clear(); }); }, keyhandler: function(e){ switch(e.which) { case 38: e.preventDefault(); this.slide("up");// up break; case 40: e.preventDefault(); this.slide("down");// down break; default: return; } }, btnhandler: function(e){ // register arrow-buttons from ui var $next = $(".btn-next"), $prev = $(".btn-previous"); e.preventDefault(); if(e.target===$next || $.contains($next[0], e.target)) this.slide("down"); else if(e.target===$prev || $.contains($prev[0], e.target)) this.slide("up"); } }; Slides.init(); </code></pre> <p>Hope someone can help. Thanks.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload