簡體   English   中英

如何讓 IntersectionObserver 使用 div ID 的 nodeList 或 div ID 的數組?

[英]How to get IntersectionObserver to work with a nodeList of div IDs or array of div IDs?

我正在創建一個在同一個 HTML 頁面上有多個“章節”的站點。

每章的頂部有兩個跳過按鈕。 左邊的跳過按鈕跳轉到上一章。 右側的跳過按鈕跳轉到下一章。

我希望 SkipButtons 只有在靠近視口頂部時才獲得 0.5 或 1.0 的不透明度。 (否則它們的不透明度為 0.0。)

我想出了如何為每個 skipButtonId 創建一個 IntersectionObserver; 但是代碼超級丑陋和多余。

觀察者觀察到的每個元素都是我要更改其類名的相同元素。

我怎樣才能重寫代碼以便只有一個觀察者?

理想情況下,我想從具有 className trailingArrowsClass 的所有 skipButtonIds 的 NodeList 中工作。

或者,如果有理由這樣做,則從轉換為數組的 NodeList 開始工作。

或者,如果這些選擇都不起作用,則使用手動創建的 div ID 數組。

我試過的都沒有用。 請您的專業知識!

整個 HTML 頁面的代碼粘貼在下面。

工作演示頁面位於https://jerrymarlow.com/intersectionobserver

如果您在瀏覽器中查看代碼或演示頁面,控制台將記錄: o NodeList o NodeList 轉換為數組 o 手動創建的 skipButtonIds 數組

謝謝! 傑瑞

<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>How to get IntersectionObserver to work with a nodeList of div IDs or array of div IDs?</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>
        /* This section of CSS is for styling only. It does not affect IntersectionObserver. */
        .containerDivClass {
            width: auto;
            margin: auto;
            background-color: lightgray;
        }

        .chapterContainerClass {
            background-color: white;
            margin: auto;
            max-width: 400px;
            padding: 0px;
            width: 100%;
            max-width: 400px;
            border-bottom: solid 3px rgba(230, 230, 230, 1.00);
            margin-bottom: 20px;
        }

        .chapterHeaderClass {
            box-sizing: border-box;
            background-color: #F8F8F8;
            background-color: white;
            margin: 0px;
            padding: 14px;
            border-top: thick;
            border-top-color: currentcolor;
            border-bottom: 5px #F0E008;
            border-bottom-color: rgb(240, 224, 8);
            border-bottom-style: none;
            border-bottom-style: solid;
            border-color: #990101;
        }

        h2 {
            color: #990101;
        }

        .storyTellerClass {
            padding: 14px;
        }

        .skipButtonsContainerClass {
            box-sizing: border-box;
            width: 100%;
            height: 35px;
            background-color: #990101;
        }


        .skipLeftButtonClass,
        .skipRightButtonClass {
            width: 105px;
            height: 35px;
            margin-top: 0px;
            margin-bottom: 0px;
            background-size: 105px 35px;
        }

        .skipLeftButtonClass,
        .skipLeftButtonClass:hover {
            float: left;
            margin-left: 0px;
        }

        .skipLeftButtonClass {
            background-image: url(https://jerrymarlow.com/images/skip_left.jpg)
        }

        .skipLeftButtonClass:hover {
            background-image: url(https://jerrymarlow.com/images/skip_left_hover.jpg)
        }

        .skipRightButtonClass,
        .skipRightButtonClass:hover {
            float: right;
            margin-right: 0px;
        }

        .skipRightButtonClass {
            background-image: url(https://jerrymarlow.com/images/skip_right.jpg)
        }

        .skipRightButtonClass:hover {
            background-image: url(https://jerrymarlow.com/images/skip_right_hover.jpg)
        }

        .spacerClass {
            height: 70px;
        }
    </style>
    <style>
        /* IntersectionObserver uses this section of CSS to change the opacity of the skip buttons.  */

        .skipButtonOpacity0 {
            opacity: 0;
            pointer-events: none;
        }

        .skipButtonOpacity50 {
            opacity: 0.5;
            pointer-events: auto;
        }

        .skipButtonOpacity100 {
            opacity: 1;
            pointer-events: auto;
        }
    </style>
</head>

<body>
    <main>
        <div id="containerDivID" class="containerDivClass">
            <div class="spacerClass"> </div>

            <div class="chapterContainerClass" id="AlohaChapterID">
                <div class="singleColumnContainerClass">

                    <div class="skipButtonsContainerClass">
                        <a href="#DingoChapterID">
                            <div id="AlohaLeftskipButtonId" class="skipLeftButtonClass trailingArrowClass skipButtonOpacity0">
                            </div>
                        </a>
                        <a href="#BravoChapterID">
                            <div id="AlohaRightskipButtonId" class="skipRightButtonClass trailingArrowClass skipButtonOpacity0">
                            </div>
                        </a>
                    </div>

                    <div class="chapterHeaderClass">
                        <h2>
                            Aloha Chapter
                        </h2>
                    </div>
                    <div class="storyTellerClass">
                        <p> Aloha, aloha, aloha. </p>
                        <p> Aloha, aloha, aloha. </p>
                        <p> Aloha, aloha, aloha. </p>
                        <p> Aloha, aloha, aloha. </p>
                        <p> Aloha, aloha, aloha. </p>
                        <p> Aloha, aloha, aloha. </p>
                        <p> Aloha, aloha, aloha. </p>
                        <p> Aloha, aloha, aloha. </p>
                    </div>
                </div>
            </div>

            <div class="chapterContainerClass" id="Bravo_left_you_upset_rattled_or_traumatized_think">
                <div class="singleColumnContainerClass">

                    <div class="skipButtonsContainerClass">
                        <a href="#AlohaChapterID">
                            <div id="BravoLeftskipButtonId" class="skipLeftButtonClass trailingArrowClass skipButtonOpacity0">
                            </div>
                        </a>
                        <a href="#CandyChapterID">
                            <div id="BravoRightskipButtonId" class="skipRightButtonClass trailingArrowClass skipButtonOpacity0">
                            </div>
                        </a>
                    </div>

                    <div class="chapterHeaderClass">
                        <h2>Bravo Chapter
                        </h2>
                    </div>
                    <div class="storyTellerClass">
                        <p> Bravo, bravo, bravo. </p>
                        <p> Bravo, bravo, bravo. </p>
                        <p> Bravo, bravo, bravo. </p>
                        <p> Bravo, bravo, bravo. </p>
                        <p> Bravo, bravo, bravo. </p>
                    </div>
                </div>
            </div>


            <div class="chapterContainerClass" id="CandyChapterID">
                <div class="singleColumnContainerClass">
                    <div class="skipButtonsContainerClass">
                        <a href="#Bravo_left_you_upset_rattled_or_traumatized_think">
                            <div id="CandyLeftskipButtonId" class="skipLeftButtonClass trailingArrowClass skipButtonOpacity0">
                            </div>
                        </a>
                        <a href="#DingoChapterID">
                            <div id="CandyRightskipButtonId" class="skipRightButtonClass trailingArrowClass skipButtonOpacity0">
                            </div>
                        </a>
                    </div>
                    <div class="chapterHeaderClass">
                        <h2> Candy Chapter </h2>
                    </div>
                    <div class="storyTellerClass">
                        <p> Candy, candy, candy. </p>
                        <p> Candy, candy, candy. </p>
                        <p> Candy, candy, candy. </p>
                        <p> Candy, candy, candy. </p>
                        <p> Candy, candy, candy. </p>
                        <p> Candy, candy, candy. </p>
                        <p> Candy, candy, candy. </p>
                    </div>
                </div>
            </div>

            <div class="chapterContainerClass" id="DingoChapterID">
                <div class="singleColumnContainerClass">
                    <div class="skipButtonsContainerClass">
                        <a href="#CandyChapterID">
                            <div id="DingoLeftskipButtonId" class="skipLeftButtonClass trailingArrowClass skipButtonOpacity0">
                            </div>
                        </a>
                        <a href="#AlohaChapterID">
                            <div id="DingoRightskipButtonId" class="skipRightButtonClass trailingArrowClass skipButtonOpacity0">
                            </div>
                        </a>
                    </div>
                    <div class="chapterHeaderClass">
                        <h2> Dingo Chapter</h2>
                    </div>
                    <div class="storyTellerClass">
                        <p> Dingo, dingo, dingo. </p>
                        <p> Dingo, dingo, dingo. </p>
                        <p> Dingo, dingo, dingo. </p>
                        <p> Dingo, dingo, dingo. </p>
                        <p> Dingo, dingo, dingo. </p>
                        <p> Dingo, dingo, dingo. </p>
                    </div>
                </div>
            </div>
            <div class="spacerClass"> </div>
            <div class="spacerClass"> </div>
            <div class="spacerClass"> </div>
            <div class="spacerClass"> </div>
            <div class="spacerClass"> </div>
            <div class="spacerClass"> </div>
            <div class="spacerClass"> </div>
            <div class="spacerClass"> </div>
        </div>
    </main>

    <script>
        var AlohaLeftskipButtonId;
        var AlohaRightskipButtonId;
        var BravoLeftskipButtonId;
        var BravoRightskipButtonId;
        var CandyLeftskipButtonId;
        var CandyRightskipButtonId;
        var DingoLeftskipButtonId;
        var DingoRightskipButtonId;


        var trailingArrowsNodeList;
        var trailingIDsArray;
        var skipButtonsIDsArray;

        window.addEventListener("load", function() {

            // This demo web page has four "chapters."
            // At the top of each chapter is a LeftSkipButton that jumps the reader back one chapter
            // and a RightSkipButton that jumps the reader ahead one chapter. 

            AlohaLeftskipButtonId = document.getElementById("AlohaLeftskipButtonId");
            AlohaRightskipButtonId = document.getElementById("AlohaRightskipButtonId");
            BravoLeftskipButtonId = document.getElementById("BravoLeftskipButtonId");
            BravoRightskipButtonId = document.getElementById("BravoRightskipButtonId");
            CandyLeftskipButtonId = document.getElementById("CandyLeftskipButtonId");
            CandyRightskipButtonId = document.getElementById("CandyRightskipButtonId");
            DingoLeftskipButtonId = document.getElementById("DingoLeftskipButtonId");
            DingoRightskipButtonId = document.getElementById("DingoRightskipButtonId");

            // I want the SkipButtons to get 0.5 or 1.0 opacity only when they are near the top of the viewport. 
            // (Otherwise they have opacities of 0.0.)


            // I figured out how to create an IntersectionObserver for each skipButtonId. 
            // But the code is super ugly and redundant. 
            // Each element that an observer observes is the same element for which I want to change the className.
            // How can I rewrite the code so that there is only one observer?

            const AlohaLeftskipButtonObserver = new IntersectionObserver(function(entries) {
                if (entries[0].intersectionRatio < 0.5) {
                    AlohaLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity0";
                }
                if (entries[0].intersectionRatio >= 0.5 &&
                    entries[0].intersectionRatio < 1.0) {
                    AlohaLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity50";
                }
                if (entries[0].intersectionRatio >= 1.0) {
                    AlohaLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity100";
                }
            }, {
                "threshold": [0, 0.5, 1.0],
                "rootMargin": "-50px 0px -67% 0px"
            });
            AlohaLeftskipButtonObserver.observe(AlohaLeftskipButtonId);


            const AlohaRightskipButtonObserver = new IntersectionObserver(function(entries) {
                if (entries[0].intersectionRatio < 0.5) {
                    AlohaRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity0";
                }
                if (entries[0].intersectionRatio >= 0.5 &&
                    entries[0].intersectionRatio < 1.0) {
                    AlohaRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity50";
                }
                if (entries[0].intersectionRatio >= 1.0) {
                    AlohaRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity100";
                }
            }, {
                "threshold": [0, 0.5, 1.0],
                "rootMargin": "-50px 0px -67% 0px"
            });
            AlohaRightskipButtonObserver.observe(AlohaRightskipButtonId);



            const BravoLeftskipButtonObserver = new IntersectionObserver(function(entries) {
                if (entries[0].intersectionRatio < 0.5) {
                    BravoLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity0";
                }
                if (entries[0].intersectionRatio >= 0.5 &&
                    entries[0].intersectionRatio < 1.0) {
                    BravoLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity50";
                }
                if (entries[0].intersectionRatio >= 1.0) {
                    BravoLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity100";
                }
            }, {
                "threshold": [0, 0.5, 1.0],
                "rootMargin": "-50px 0px -67% 0px"
            });
            BravoLeftskipButtonObserver.observe(BravoLeftskipButtonId);


            const BravoRightskipButtonObserver = new IntersectionObserver(function(entries) {
                if (entries[0].intersectionRatio < 0.5) {
                    BravoRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity0";
                }
                if (entries[0].intersectionRatio >= 0.5 &&
                    entries[0].intersectionRatio < 1.0) {
                    BravoRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity50";
                }
                if (entries[0].intersectionRatio >= 1.0) {
                    BravoRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity100";
                }
            }, {
                "threshold": [0, 0.5, 1.0],
                "rootMargin": "-50px 0px -67% 0px"
            });
            BravoRightskipButtonObserver.observe(BravoRightskipButtonId);



            const CandyLeftskipButtonObserver = new IntersectionObserver(function(entries) {
                if (entries[0].intersectionRatio < 0.5) {
                    CandyLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity0";
                }
                if (entries[0].intersectionRatio >= 0.5 &&
                    entries[0].intersectionRatio < 1.0) {
                    CandyLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity50";
                }
                if (entries[0].intersectionRatio >= 1.0) {
                    CandyLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity100";
                }
            }, {
                "threshold": [0, 0.5, 1.0],
                "rootMargin": "-50px 0px -67% 0px"
            });
            CandyLeftskipButtonObserver.observe(CandyLeftskipButtonId);


            const CandyRightskipButtonObserver = new IntersectionObserver(function(entries) {
                if (entries[0].intersectionRatio < 0.5) {
                    CandyRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity0";
                }
                if (entries[0].intersectionRatio >= 0.5 &&
                    entries[0].intersectionRatio < 1.0) {
                    CandyRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity50";
                }
                if (entries[0].intersectionRatio >= 1.0) {
                    CandyRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity100";
                }
            }, {
                "threshold": [0, 0.5, 1.0],
                "rootMargin": "-50px 0px -67% 0px"
            });
            CandyRightskipButtonObserver.observe(CandyRightskipButtonId);


            const DingoLeftskipButtonObserver = new IntersectionObserver(function(entries) {
                if (entries[0].intersectionRatio < 0.5) {
                    DingoLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity0";
                }
                if (entries[0].intersectionRatio >= 0.5 &&
                    entries[0].intersectionRatio < 1.0) {
                    DingoLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity50";
                }
                if (entries[0].intersectionRatio >= 1.0) {
                    DingoLeftskipButtonId.className = "skipLeftButtonClass skipButtonOpacity100";
                }
            }, {
                "threshold": [0, 0.5, 1.0],
                "rootMargin": "-50px 0px -67% 0px"
            });
            DingoLeftskipButtonObserver.observe(DingoLeftskipButtonId);


            const DingoRightskipButtonObserver = new IntersectionObserver(function(entries) {
                if (entries[0].intersectionRatio < 0.5) {
                    DingoRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity0";
                }
                if (entries[0].intersectionRatio >= 0.5 &&
                    entries[0].intersectionRatio < 1.0) {
                    DingoRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity50";
                }
                if (entries[0].intersectionRatio >= 1.0) {
                    DingoRightskipButtonId.className = "skipRightButtonClass skipButtonOpacity100";
                }
            }, {
                "threshold": [0, 0.5, 1.0],
                "rootMargin": "-50px 0px -67% 0px"
            });
            DingoRightskipButtonObserver.observe(DingoRightskipButtonId);


            
            // Ideally, I would like to work from a trailingArrowsNodeList:
            trailingArrowsNodeList = document.querySelectorAll(".trailingArrowClass");
            console.log("trailingArrowsNodeList " + trailingArrowsNodeList);

            for (var entry of trailingArrowsNodeList.entries()) {
                console.log(entry);
            }

            // Or, if there is a reason to do so, work from that NodeList converted to an array: 
            var trailingArrowsArray = Array.from(trailingArrowsNodeList);
            console.log("trailingArrowsArray " + trailingArrowsArray);

            for (var entry of trailingArrowsArray.entries()) {
                console.log(entry);
            }


            // Or, if neither of those choices work, work from a manually created array of div IDs: 
            const skipButtonsIDsArray = [AlohaLeftskipButtonId, AlohaRightskipButtonId, BravoLeftskipButtonId, BravoRightskipButtonId, CandyLeftskipButtonId, CandyRightskipButtonId, DingoLeftskipButtonId, DingoRightskipButtonId];
            console.log("skipButtonsIDsArray " + skipButtonsIDsArray);

            for (var entry of skipButtonsIDsArray.entries()) {
                console.log(entry);
            }
            
            // Nothing I've tried worked. Your expertise please!
            // Thank you. 
            // Jerry 
        });
    </script>
</body>
</html>
//E[foo$="bar"]     an E element whose "foo" attribute value ends exactly with the string "bar"     Attribute selectors     3
//div[id$="skipButtonId"]

mybuttons = document.querySelectorAll("div[id$='skipButtonId']");

const mybuttonObserver = new IntersectionObserver(function(entries){

console.log("Num entries= " + entries.length);


entries.forEach((n) => {
// I want the SkipButtons to get 0.5 or 1.0 opacity only when they are near the top of the viewport. 
// (Otherwise they have opacities of 0.0.)


if (n.intersectionRatio < 0.5) {
    n.target.classList.remove("skipButtonOpacity50", "skipButtonOpacity100");
    n.target.classList.add("skipButtonOpacity0");
    console.log("io = <0.5 - ",n.target.classList);
}

if(n.intersectionRatio>=0.5 && n.intersectionRatio < 1.0){
    n.target.classList.remove("skipButtonOpacity0","skipButtonOpacity100");
    n.target.classList.add("skipButtonOpacity50");
    console.log("io = >=0.5  and <1.0" , n.target.classList);
}   

if (n.intersectionRatio >= 1.0) {
    n.target.classList.remove("skipButtonOpacity0","skipButtonOpacity50");
    n.target.classList.add("skipButtonOpacity100");
    console.log("io = >=1 " , n.target.classList);
}



});


},{ 
    threshold  : [0,0.5,1],
    rootMargin : "-50px 0px -67% 0px"
});




for (var e of mybuttons){
    mybuttonObserver.observe(e);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM