[英]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.