Поэтому, когда я беру ваш пример js и помещаю его поверх некоторых случайных элементов списка, он работает для меня в iOS Safari так же, как и в macOS Chrome. Но и то, и другое ужасно коренасто, потому что вы просите браузер пересчитать макет / поток почти рекурсивным способом. Когда вы обновляете высоту строки одного li, вы перекомпоновываете макет всех последующих элементов li. Это действительно дорого / неэффективно. Вместо обновления свойств, связанных с макетом / потоком, вы должны найти способ создать желаемый эффект с помощью краски или более сложных, но связанных свойств.
https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/
Если бы это был я, я бы попытался найти способ использовать свойство transform
с уникальными значениями translateY
для каждого li после первоначального размещения их с постоянной высотой строки. Это также имеет то преимущество, что вы не изменяете высоту всего списка при каждом обновлении, благодаря чему scrollHeight окна не пересчитывается в середине прокрутки снова и снова.
function throttled(delay, fn) {
let lastCall = 0;
return function(...args) {
const now = (new Date).getTime();
if (now - lastCall < delay) {
return;
}
lastCall = now;
return fn(...args);
}
}
const testElement = document.querySelectorAll("li");
console.log(testElement.offsetTop);
window.addEventListener("scroll", throttled(10, (e) => {
for(let i = testElement.length-1;i>=0;i--){
let posTopElement = (testElement[i].offsetTop)-600;
if (document.documentElement.scrollTop > posTopElement) {
window.requestAnimationFrame(function() {
let minLineHeight = 4;
let lineHeight = (window.scrollY - posTopElement) * 0.1;
if (lineHeight < minLineHeight) lineHeight = minLineHeight;
else if (lineHeight > 36) lineHeight = 36;
testElement[i].style.lineHeight = lineHeight + "px";
});
}
}
}));
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1, width=device-width, maximum-scale=1, user-scalable=no, shrink-to-fit=no, viewport-fit=cover">
<style>
ul {
min-height: 200vh;
overflow: hidden;
}
</style>
</head>
<body>
<ul>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
</ul>
</body>
</html>