Почему некорректно работает JS-скрипт на Mac OS?

99
19 октября 2019, 01:50

При написании скрипта на плавное прокручивание блоков сайта (По-типу fullpage.js) возникла проблема. На устройствах под Windows, в любых браузерах скрипт корректно работает, анимация плавная и приятная, но при тестировании на устройстве с MacOS анимация начинает тормозить (сначала очень медленно и дёрганно проигрывается, а потом быстро доводит скролл). Опытным путём было выяснено, что функция scrollTo срабатывает корректно и на устройствах с MacOS. Тестирование под MacOS проводилось в браузерах Сафари и Яндекс.Браузер. Повторить ошибку на различных эмуляторах лично мне не удалось. Код на codepen.io

html:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <style>section{height: 100vh;padding: 0;margin: 0;} body{padding: 0;margin: 0;}</style>
    <link rel="stylesheet" href="">
</head>
<body>
    <section class="js-section1" style="background-color: red;"></section>
    <section class="js-section2" style="background-color: yellow;"></section>
    <section class="js-section3" style="background-color: green;"></section>
    <div>
        <section class="js-section4" style="background-color: orange; height: 200vh;"></section>
        <section class="js-section5" style="background-color: grey;"></section>
        <section class="js-section6" style="background-color: brown;"></section>
    </div>
</body>
</html>

js:

'use strict';
var lastScrollTop = 0;
var sections = document.querySelectorAll('section');
var nSect = sections[sections.length - 1].className;
var getIndexnSect = nSect.substring(nSect).indexOf('js-section') + 10;
var mSect = Number.parseInt(nSect[getIndexnSect]) + 1;
var delta = 0;
if (document.addEventListener) {
  if ('onwheel' in document) {
    // IE9+, FF17+, Ch31+
    document.addEventListener("wheel", onWheel);
  } else if ('onmousewheel' in document) {
    // устаревший вариант события
    document.addEventListener("mousewheel", onWheel);
  } else {
    // Firefox < 17
    document.addEventListener("MozMousePixelScroll", onWheel);
  }
} else { // IE8-
  document.attachEvent("onmousewheel", onWheel);
}
function onWheel(e) {
  e = e || window.event;
  delta = e.deltaY || e.detail || e.wheelDelta;
            if (getELem().section.clientHeight <= document.documentElement.clientHeight){
                  e.preventDefault ? e.preventDefault() : (e.returnValue = false);
            }
            else if (getELem().section.clientHeight > document.documentElement.clientHeight){
                if (delta > 0){
                    var posBottom = window.pageYOffset + document.documentElement.clientHeight + delta;
                    if (posBottom >= getCoord(getELem().section).posXb){
                        e.preventDefault ? e.preventDefault() : (e.returnValue = false); 
                    }
                }
                else if (delta < 0){
                    var posTop = getCoord(getELem().section).posX - delta;
                    if (window.pageYOffset <= posTop){
                        e.preventDefault ? e.preventDefault() : (e.returnValue = false); 
                    }
                }
            }
  if (delta < 0){
    moveTop();
  }
  else if (delta > 0) {
    moveDown();
  }
}
function moveTop(){
          var seClassName = getELem().section.className;
          var getIndexSeClassName = seClassName.substring(seClassName).indexOf('js-section') + 10;
          var numSect = Number.parseInt(seClassName[getIndexSeClassName]) -1;
          var playTo = 'js-section' + numSect;
          // 
          if (numSect > 0){
            if(document.getElementsByClassName(playTo)[0].clientHeight <= document.documentElement.clientHeight){

                if (getELem().section.clientHeight <= document.documentElement.clientHeight){
                    scrollIt(document.getElementsByClassName(playTo)[0], 1000,'easeInOutQuint')
                }
                else if (getELem().section.clientHeight > document.documentElement.clientHeight){
                    var posTop = getCoord(getELem().section).posX - delta;
                    if (window.pageYOffset <= posTop){
                        scrollIt(document.getElementsByClassName(playTo)[0], 1000,'easeInOutQuint')
                    }
                }
            }

            else if(document.getElementsByClassName(playTo)[0].clientHeight > document.documentElement.clientHeight){
                var posBottom = getCoord(document.getElementsByClassName(playTo)[0]).posXb - document.documentElement.clientHeight;

                if (getELem().section.scrollHeight <= document.documentElement.clientHeight){
                    scrollIt(posBottom, 1000,'easeInOutQuint')
                }
                else if (getELem().section.scrollHeight > document.documentElement.clientHeight){
                    var posTop = getCoord(getELem().section).posX - delta;
                    if (window.pageYOffset <= posTop){
                        scrollIt(posBottom, 1000,'easeInOutQuint')
                    }
                }
            }
          }
          else if (numSect < 0){
          }
}
function moveDown(){
          var seClassName = getELem().section.className;
          var getIndexSeClassName = seClassName.substring(seClassName).indexOf('js-section') + 10;
          var numSect = Number.parseInt(seClassName[getIndexSeClassName]) + 1;
          var playTo = 'js-section' + numSect;
          if (numSect < mSect){
            if (getELem().section.clientHeight <= document.documentElement.clientHeight){
                scrollIt(document.getElementsByClassName(playTo)[0], 1000,'easeInOutQuint')
            }
            else if (getELem().section.clientHeight > document.documentElement.clientHeight){
                var posBottom = window.pageYOffset + document.documentElement.clientHeight + delta;
                if (posBottom >= getCoord(getELem().section).posXb){
                    scrollIt(document.getElementsByClassName(playTo)[0], 1000,'easeInOutQuint')
                }
            }
          }
          else if (numSect > mSect) {
          }
}
function getELem(){
    for (var i = 0; i < sections.length; ++i) {
        if (delta > 0){
            var offTop = window.pageYOffset + delta;
        }
        else if (delta < 0) {
            var offTop = window.pageYOffset - delta;
        }
        if (getCoord(sections[i]).posX <= offTop){
            var section = sections[i];
        } 
    };
    return{section};
}
function getCoord(elem) {
      var posX = elem.offsetTop;
       var posXb = elem.offsetTop + elem.clientHeight; 
  return {posX, posXb};
};
function scrollIt(destination, duration = 200, easing = 'linear', callback) {
  const easings = {
    linear(t) {
      return t;
    },
    easeInQuad(t) {
      return t * t;
    },
    easeOutQuad(t) {
      return t * (2 - t);
    },
    easeInOutQuad(t) {
      return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
    },
    easeInCubic(t) {
      return t * t * t;
    },
    easeOutCubic(t) {
      return (--t) * t * t + 1;
    },
    easeInOutCubic(t) {
      return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
    },
    easeInQuart(t) {
      return t * t * t * t;
    },
    easeOutQuart(t) {
      return 1 - (--t) * t * t * t;
    },
    easeInOutQuart(t) {
      return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
    },
    easeInQuint(t) {
      return t * t * t * t * t;
    },
    easeOutQuint(t) {
      return 1 + (--t) * t * t * t * t;
    },
    easeInOutQuint(t) {
      return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t;
    }
  };
  const start = window.pageYOffset;
  const startTime = 'now' in window.performance ? performance.now() : new Date().getTime();
  const documentHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
  const windowHeight = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight;
  const destinationOffset = typeof destination === 'number' ? destination : destination.offsetTop;
  const destinationOffsetToScroll = Math.round(documentHeight - destinationOffset < windowHeight ? documentHeight - windowHeight : destinationOffset);
  if ('requestAnimationFrame' in window === false) {
    window.scroll(0, destinationOffsetToScroll);
    if (callback) {
      callback();
    }
    return;
  }
  function scroll() {
    const now = 'now' in window.performance ? performance.now() : new Date().getTime();
    const time = Math.min(1, ((now - startTime) / duration));
    const timeFunction = easings[easing](time);
    window.scroll(0, Math.ceil((timeFunction * (destinationOffsetToScroll - start)) + start));
    if (window.pageYOffset === destinationOffsetToScroll) {
      if (callback) {
        callback();
      }
      return;
    }
    requestAnimationFrame(scroll);
  }
  scroll();
}
READ ALSO
var и оператор запятая

var и оператор запятая

Почему var i = 15,4; генерирует ошибку? Ведь сначала должно присваивание выполнится, а затем оператор , вернет 4Или как это работает? Может , не является...

121
Создание вложенных списков в React

Создание вложенных списков в React

Мне необходимо создать список в виде древовидной структурыЧто-то вроде:

100