gpt4 book ai didi

javascript - 为什么 ScrollTop 位置在移动 Safari 上不起作用?

转载 作者:行者123 更新时间:2023-12-01 01:40:20 27 4
gpt4 key购买 nike

我的网站上有一个功能, Logo 会根据用户在网站上的位置垂直滚动。

您可以看到它在 Chrome here 上运行

但是它不适用于 Safari,包括手机和平板电脑。

滚动位置在控制台中似乎根本没有改变。

// logo positioning  

let logos, logoHeight, barTopMargin;
let viewportHeight;

window.addEventListener('load', init);
window.addEventListener('resize', setSizes);
document.addEventListener('scroll', update);


function init(lockUpdate) {
logos = document.querySelectorAll('.scroll-text');
setSizes(lockUpdate);
}

function update() {
// ensure initialization and prevent recursive call
if (!logos) init(true);
//*************************************************

/**************************************************
THIS LINE MUST BE HERE.
**************************************************/
let maxScrollDist = document.documentElement.scrollHeight - viewportHeight;
//*************************************************

let currentScrollPos = document.documentElement.scrollTop;
let newTop;

let middle = currentScrollPos + viewportHeight/2;
let middleY = maxScrollDist/2;

if (middle >= (maxScrollDist+viewportHeight)/2) {
let p = (middleY - Math.floor(middle - (maxScrollDist+viewportHeight)/2))*100/middleY;

newTop = viewportHeight/2 - logoHeight/2;
newTop += (100-p)*(viewportHeight/2)/100;
newTop -= (100-p)*(barTopMargin +logoHeight/2)/100;
newTop = Math.max(newTop, viewportHeight/2 - logoHeight/2); /*fix*/
} else {
let p = (middleY - Math.floor(-middle + (maxScrollDist+viewportHeight)/2))*100/middleY;
newTop = barTopMargin*(100-p)/100+(viewportHeight/2 - (logoHeight/2)*p/100 )*p/100;
newTop = Math.min(newTop, viewportHeight/2 - logoHeight/2); /*fix*/
}

logos.forEach(function(el) {
el.style.top = newTop + "px";
});
}

function setSizes(lockUpdate) {
logoHeight = logos[0].offsetHeight;
barTopMargin = parseInt(getComputedStyle(document.querySelector('#page'), '::before').top);
viewportHeight = window.innerHeight;
if (lockUpdate === true) return;
update();
}

最佳答案

这种行为背后的原因在于浏览器之间滚动实现的差异。例如,Chrome 根据 <html> 计算页面滚动。 ,而 Safari 在 <body> 上执行相同操作.

Chrome :

chrome scrollingElement

Safari :

safari scrollingElement

考虑到这些信息,可以合理地假设在 Safari document.documentElement 中完全不知道页面全局滚动值。

为了解决这个问题,您可以定义一个使用 document.scrollingElement 的辅助函数。回退到 getBoundingClientRectdocument.documentElement :

function getScrollingElement() {
if (document.scrollingElement) {
return document.scrollingElement;
}

const docElement = document.documentElement;
const docElementRect = docElement.getBoundingClientRect();

return {
scrollHeight: Math.ceil(docElementRect.height),
scrollTop: Math.abs(docElementRect.top)
}
}

并在您的 update 中使用它功能:
function update() {
// ensure initialization and prevent recursive call
if (!logos) init(true);
//*************************************************

/**************************************************
THIS LINE MUST BE HERE.
**************************************************/
let maxScrollDist = getScrollingElement().scrollHeight - viewportHeight;
//*************************************************

let currentScrollPos = getScrollingElement().scrollTop;

// ...
}

function getScrollingElement() {
// ...
}

完整代码:

// logo positioning  

let logos, logoHeight, barTopMargin;
let viewportHeight;

window.addEventListener('load', init);
window.addEventListener('resize', setSizes);
document.addEventListener('scroll', update);


function init(lockUpdate) {
logos = document.querySelectorAll('.scroll-text');
setSizes(lockUpdate);
}

function update() {
// ensure initialization and prevent recursive call
if (!logos) init(true);
//*************************************************

/**************************************************
THIS LINE MUST BE HERE.
**************************************************/
let maxScrollDist = getScrollingElement().scrollHeight - viewportHeight;
//*************************************************

let currentScrollPos = getScrollingElement().scrollTop;
let newTop;

let middle = currentScrollPos + viewportHeight/2;
let middleY = maxScrollDist/2;

if (middle >= (maxScrollDist+viewportHeight)/2) {
let p = (middleY - Math.floor(middle - (maxScrollDist+viewportHeight)/2))*100/middleY;

newTop = viewportHeight/2 - logoHeight/2;
newTop += (100-p)*(viewportHeight/2)/100;
newTop -= (100-p)*(barTopMargin +logoHeight/2)/100;
newTop = Math.max(newTop, viewportHeight/2 - logoHeight/2); /*fix*/
} else {
let p = (middleY - Math.floor(-middle + (maxScrollDist+viewportHeight)/2))*100/middleY;
newTop = barTopMargin*(100-p)/100+(viewportHeight/2 - (logoHeight/2)*p/100 )*p/100;
newTop = Math.min(newTop, viewportHeight/2 - logoHeight/2); /*fix*/
}

logos.forEach(function(el) {
el.style.top = newTop + "px";
});
}

function getScrollingElement() {
if (document.scrollingElement) {
return document.scrollingElement;
}

const docElement = document.documentElement;
const docElementRect = docElement.getBoundingClientRect();

return {
scrollHeight: Math.ceil(docElementRect.height),
scrollTop: Math.abs(docElementRect.top)
}
}

function setSizes(lockUpdate) {
logoHeight = logos[0].offsetHeight;
barTopMargin = parseInt(getComputedStyle(document.querySelector('#page'), '::before').top);
viewportHeight = window.innerHeight;
if (lockUpdate === true) return;
update();
}


希望这可以帮助。

关于javascript - 为什么 ScrollTop 位置在移动 Safari 上不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58693386/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com