首页  >  问答  >  正文

使用 Ajax 生成内容 - 滚动到 Id 不起作用

我根据通过 ajax 获取的数据生成页面内容。 我遇到的问题是,当我想滚动到某个 ID 时,滚动要么不会发生,要么滚动到错误的位置。

我一直在查看SO问答,但没有找到任何好的解决方案。很多答案都是针对 Angular 或 React 的,但对于普通 js 来说没有什么真正可靠的答案。

举个例子,假设用户点击了一个链接“关于我们 -> 项目”,“关于我们”是页面,项目位于页面末尾的 id 中,其中包含一些内容。

当我从不同页面点击链接时,就会出现问题。

假设我们在主页上,我们单击“关于我们”页面、项目部分(id 项目)的链接。这是当卷轴无法按预期工作时。如果我们点击链接项目,当我们进入关于我们页面时,这个问题就不会发生。

由于页面数据是用javascript呈现的,我无法使用事件侦听器DOMContentLoadedload,因为它们在生成内容之前触发(我认为)。

下面是我的无效解决方案。它应该检查 id 是否在视口中,如果没有,它应该滚动。

我不想使用 setTimeout 因为它可能并不总是有效(网速慢,更多内容(图像)等)

任何帮助将不胜感激。

function generate(data){
   // code

    let idx = 0 //just in case, so we don't have an infinite loop
    if (window.location.href.indexOf("#") !== -1) {
        const id = window.location.href.split("#")[1];

        const element = document.getElementById(id);
        document.addEventListener('DOMContentLoaded', function () {
            console.log("loaded");
            if (element) {
                while (!isInViewport(id)) {
                    idx = idx + 1;
                    console.log(isInViewport(id))
                    scrollToElement(id);
                    if (idx === 10000){
                        break;
                    }
                };
            }
        });
    }
}

generateContent();


function scrollToElement(id) {
    const element = document.getElementById(id);
    if (element) {
        element.scrollIntoView({
            behavior: 'smooth'
        });
    }
}

function isInViewport(id) {
    const element = document.getElementById(id);
    if (element) {
        const rect = element.getBoundingClientRect();
        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }
}

如果我可以提供任何其他数据,请告诉我。

P粉208469050P粉208469050178 天前411

全部回复(1)我来回复

  • P粉978551081

    P粉9785510812024-04-05 09:06:23

    虽然它不是迄今为止最优雅的解决方案。

    如果有人能找到更好的方法,请告诉我。

    编辑:稍微更改了代码,即使在用户滚动后也消除了编程滚动的问题。

    function generateContent(data){
       // code
    
        if (window.location.href.indexOf("#") !== -1) {
            const id = window.location.href.split("#")[1];
            const element = document.getElementById(id);
            if (element) {
                scrollToLoop(id);
            }
        }
    }
    generateContent();
    
    let isUserScrolling = false;
    window.addEventListener("wheel", function () {
        isUserScrolling = true;
    });
    window.addEventListener("touchmove", function () {
        isUserScrolling = true;
    });
    function scrollToLoop(id, scrl) {
        let scroll = scrl;
        const element = document.getElementById(id);
    
        if (element) {
            if (!isInViewport(id) && scroll && !isUserScrolling) {
                scrollToElement(id);
                setTimeout(() => {
                    if (!isInViewport(id)) {
                        scrollToLoop(id, true);
                    }
                }, 500);
            } else {
                setTimeout(() => {
                    if (!isInViewport(id) && scroll && !isUserScrolling) {
                        scrollToLoop(id, true);
                    }
                }, 500);
            }
        }
    }

    回复
    0
  • 取消回复