При написании скрипта на плавное прокручивание блоков сайта (По-типу 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();
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Почему var i = 15,4; генерирует ошибку? Ведь сначала должно присваивание выполнится, а затем оператор , вернет 4Или как это работает? Может , не является...
Мне необходимо создать список в виде древовидной структурыЧто-то вроде: