Generieren von Inhalten mit Ajax – Scrollen zur ID funktioniert nicht
P粉208469050
P粉208469050 2024-04-04 09:29:39
0
1
581

Ich erstelle Seiteninhalte basierend auf Daten, die über Ajax erhalten wurden. Das Problem, das ich habe, ist, dass, wenn ich zu einer bestimmten ID scrollen möchte, das Scrollen entweder nicht erfolgt oder an die falsche Stelle gescrollt wird.

Ich habe mir die SO-Fragen und Antworten angesehen, aber keine guten Lösungen gefunden. Viele Antworten beziehen sich auf Angular oder React, aber nichts wirklich Solides für einfaches JS.

Angenommen, der Benutzer klickt auf einen Link „Über uns -> Projekt“, „Über uns“ ist die Seite und das Projekt befindet sich in der ID am Ende der Seite, die einige Inhalte enthält.

Das Problem tritt auf, wenn ich auf Links von verschiedenen Seiten klicke.

Vorausgesetzt, wir befinden uns auf der Startseite, klicken wir auf den Link zur Seite „Über uns“, Abschnitt „Projekte“ (id project). Dies ist der Fall, wenn die Schriftrolle nicht wie erwartet funktioniert. Wenn wir auf den verlinkten Artikel klicken, während wir zur Seite „Über uns“ gehen, tritt dieses Problem nicht auf.

Da die Seitendaten in Javascript gerendert werden, kann ich keine Ereignis-Listener verwenden DOMContentLoadedload, da diese ausgelöst werden, bevor der Inhalt generiert wird (glaube ich).

Unten ist meine Lösung, die nicht funktioniert hat. Es sollte prüfen, ob sich die ID im Ansichtsfenster befindet. Wenn nicht, sollte ein Bildlauf durchgeführt werden.

Ich möchte setTimeout nicht verwenden, da es möglicherweise nicht immer funktioniert (langsame Internetgeschwindigkeit, mehr Inhalte (Bilder) usw.)

Jede Hilfe wäre sehr dankbar.

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)
        );
    }
}

Wenn ich weitere Daten bereitstellen kann, lassen Sie es mich bitte wissen.

P粉208469050
P粉208469050

Antworte allen(1)
P粉978551081

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

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

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

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);
        }
    }
}
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage