Menjana kandungan menggunakan Ajax - menatal ke Id tidak berfungsi
P粉208469050
P粉208469050 2024-04-04 09:29:39
0
1
584

Saya menjana kandungan halaman berdasarkan data yang diperoleh melalui ajax. Masalah yang saya hadapi ialah apabila saya ingin menatal ke ID tertentu, penatalan sama ada tidak berlaku atau ia menatal ke lokasi yang salah.

Saya telah melihat SO Q&A tetapi tidak menemui sebarang penyelesaian yang baik. Banyak jawapan adalah untuk Angular atau React, tetapi tiada apa yang benar-benar kukuh untuk js biasa.

Sebagai contoh, katakan pengguna mengklik pada pautan "Tentang Kami -> Projek", "Tentang Kami" ialah halaman dan projek itu terletak dalam id di hujung halaman, yang mengandungi beberapa kandungan.

Masalah berlaku apabila saya klik pada pautan dari halaman yang berbeza.

Andaikan kami berada di halaman utama, kami klik pada pautan ke halaman Mengenai Kami, bahagian Projek (projek id). Ini adalah apabila skrol tidak berfungsi seperti yang diharapkan. Jika kita mengklik pada item yang dipautkan, apabila kita pergi ke halaman Mengenai Kami, masalah ini tidak berlaku.

Memandangkan data halaman dipaparkan dalam javascript, saya tidak boleh menggunakan pendengar acara DOMContentLoadedload kerana mereka menyala sebelum kandungan dijana (saya rasa).

Di bawah ialah penyelesaian saya yang tidak berkesan. Ia harus menyemak sama ada id berada dalam viewport, jika tidak ia harus menatal.

Saya tidak mahu menggunakan setTimeout kerana ia mungkin tidak selalu berfungsi (kelajuan internet perlahan, lebih banyak kandungan (imej) dsb.)

Sebarang bantuan amat kami hargai.

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

Jika saya boleh memberikan sebarang data lain, sila beritahu saya.

P粉208469050
P粉208469050

membalas semua(1)
P粉978551081

Walaupun ia bukan penyelesaian yang paling elegan setakat ini.

Jika sesiapa boleh mencari cara yang lebih baik, sila beritahu saya.

EDIT: Ubah sedikit kod untuk menghapuskan isu penatalan terprogram walaupun selepas pengguna telah menatal.

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);
        }
    }
}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan