Плавная прокрутка простого javascript - Safari не работает Firefox - PullRequest
0 голосов
/ 09 мая 2018

Пересмотрено по состоянию на август 2018 г. - теперь более элегантно, с ускорением и замедлением. Протестировано в Mozilla и Safari сейчас.

Я разработал этот сценарий, используя объект «requestAnimFrame (callback)» для плавной прокрутки без библиотеки, он отлично работает с Safari, но не с Firefox, не могу понять почему.

Обратный вызов вызывается косвенно - функцией-оберткой для передачи дополнительных аргументов (помимо метки времени).

/*
 * smoothScroll to a supplied target using "requestAnimationFrame"
 */
var starttime,         // start of animation
 runtime,               // animation duration
 distance,              // distance of the target in reference to the viewport top
 docpos,                // distance document top to viewport top 
 delta,                  // distance left to scroll till target reached
 step,                   // travelled distance
 correct=10,          // correct y destination position
 t=900,                 // absolute duration 
 v,            
 a=0.001;

//wrapper function, necessary for passing arguments with requestAnimationFrame to the real callback function -> smoothScroll

function wrapsmoothScrl(callback, id, target){                           
      return function(timestamp){
            callback(id, target, timestamp);
      };
}
function smoothScroll(id, target, timestamp){
     $(id).addEventListener("click", function(event){event.preventDefault();});
     if (!starttime) starttime=timestamp;
     if (!distance) distance=$(target).getBoundingClientRect().top;
     if (!docpos) docpos=window.pageYOffset;

     v=Math.abs(distance)/t;
     runtime=timestamp-starttime;

     step=runtime<(t/2)?(v+a*runtime)*runtime:((v+a*t/2)-a*(runtime-t/2))*runtime;
     step=distance>0?step:step*(-1);
     document.documentElement.scrollTop=docpos+step;    // for mozilla
     document.body.scrollTop=docpos+step;                     // for safari (and others?)

     delta=$(target).getBoundingClientRect().top;
     if (distance>0 && delta>correct || distance<0 && delta<correct){
            var animReq1=window.requestAnimationFrame(wrapsmoothScrl(smoothScroll, id, target));
     } else {window.cancelAnimationFrame(animReq1); starttime=null; distance=null; docpos=null;}
}
...