| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/ko/docs/Web/API/Intersection_Observer_API | [Back] [Original] |
Get to know MDN better
This page was translated from English by the community. Learn more and join the MDN Web Docs community.
This feature is well established and works across many devices and browser versions. Its been available across browsers since 2019 3.
* Some parts of this feature may have varying levels of support.
Intersection Observer API viewport .
, . Web , . .
Element.getBoundingClientRect() . , . , .
. , , . . . , , , .
Intersection Observer API ( viewport) . , , .
Intersection Observer API : . API " N% " .
Intersection Observer API .
, , . root null . .
, API .
intersection ratio . 0.0 1.0 .
intersection observer , threshold callback .
let options = {
root: document.querySelector("#scrollArea"),
rootMargin: "0px",
threshold: 1.0,
};
let observer = new IntersectionObserver(callback, options);
threshold 1.0 root 100% . .
IntersectionObserver() options observer . .
root . . null .
rootMargin . CSS margin . . "10px 20px 30px 40px" (, , , ). . . 0.
threshold. 50% , 0.5 . 25% , [0, 0.25, 0.5, 0.75, 1] . 0 . (1 , .) 1.0 .
, .
let target = document.querySelector("#listItem");
observer.observe(target);
// observer
// . ( )
IntersectionObserver , . IntersectionObserverEntry .
let callback = (entries, observer) => {
entries.forEach((entry) => {
// .
// :
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
. isIntersecting .
. . , Window.requestIdleCallback() .
, root , .
Intersection Observer API . . , , .
, . . document null .
. .
Document), .getBoundingClientRect() ) IntersectionObserver , root margin , rootMargin . rootMargin ( IntersectionObserverEntry.rootBounds ) .
Intersection Observer API thresholds . , . , API .
, 25% , [0, 0.25, 0.5, 0.75, 1] .
, IntersectionObserverEntry .
isIntersecting . true , . .
boundingClientRect 0 . .
, . , . .
IntersectionObserver.thresholds [0.00, 0.01, 0.02, /*,*/ 0.99, 1.00] .<template id="boxTemplate">
<div class="sampleBox">
<div class="label topLeft"></div>
<div class="label topRight"></div>
<div class="label bottomLeft"></div>
<div class="label bottomRight"></div>
</div>
</template>
<main>
<div class="contents">
<div class="wrapper"></div>
</div>
</main>
.contents {
position: absolute;
width: 700px;
height: 1725px;
}
.wrapper {
position: relative;
top: 600px;
}
.sampleBox {
position: relative;
left: 175px;
width: 150px;
background-color: rgb(245, 170, 140);
border: 2px solid rgb(201, 126, 17);
padding: 4px;
margin-bottom: 6px;
}
#box1 {
height: 200px;
}
#box2 {
height: 75px;
}
#box3 {
height: 150px;
}
#box4 {
height: 100px;
}
.label {
font:
14px "Open Sans",
"Arial",
sans-serif;
position: absolute;
margin: 0;
background-color: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(0, 0, 0, 0.7);
width: 3em;
height: 18px;
padding: 2px;
text-align: center;
}
.topLeft {
left: 2px;
top: 2px;
}
.topRight {
right: 2px;
top: 2px;
}
.bottomLeft {
bottom: 2px;
left: 2px;
}
.bottomRight {
bottom: 2px;
right: 2px;
}
let observers = [];
startup = () => {
let wrapper = document.querySelector(".wrapper");
//
let observerOptions = {
root: null,
rootMargin: "0px",
threshold: [],
};
// An array of threshold sets for each of the boxes. The
// first box's thresholds are set programmatically
// since there will be so many of them (for each percentage
// point).
let thresholdSets = [
[],
[0.5],
[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
[0, 0.25, 0.5, 0.75, 1.0],
];
for (let i = 0; i <= 1.0; i += 0.01) {
thresholdSets[0].push(i);
}
// Add each box, creating a new observer for each
for (let i = 0; i < 4; i++) {
let template = document
.querySelector("#boxTemplate")
.content.cloneNode(true);
let boxID = `box${i + 1}`;
template.querySelector(".sampleBox").id = boxID;
wrapper.appendChild(document.importNode(template, true));
// Set up the observer for this box
observerOptions.threshold = thresholdSets[i];
observers[i] = new IntersectionObserver(
intersectionCallback,
observerOptions,
);
observers[i].observe(document.querySelector(`#${boxID}`));
}
// Scroll to the starting position
document.scrollingElement.scrollTop =
wrapper.firstElementChild.getBoundingClientRect().top + window.scrollY;
document.scrollingElement.scrollLeft = 750;
};
intersectionCallback = (entries) => {
entries.forEach((entry) => {
let box = entry.target;
let visiblePct = `${Math.floor(entry.intersectionRatio * 100)}%`;
box.querySelector(".topLeft").innerHTML = visiblePct;
box.querySelector(".topRight").innerHTML = visiblePct;
box.querySelector(".bottomLeft").innerHTML = visiblePct;
box.querySelector(".bottomRight").innerHTML = visiblePct;
});
};
startup();
. .
getBoundingClientRect() . . .overflow . overflow visible clipping .<iframe> ) , , . <iframe> , , .document . , IntersectionObserver . , IntersectionObserverEntry IntersectionObserver .
IntersectionObserverEntry , , , .
75% . 0.0 () approximately isIntersecting . , intersectionRatio 75% .
const intersectionCallback = (entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let elem = entry.target;
if (entry.intersectionRatio >= 0.75) {
intersectionCounter++;
}
}
});
};
IntersectionObserverIntersectionObserverEntry . IntersectionObserver IntersectionObserver.takeRecords() .
. Intersection Observer API , (: ) , .
HTML ( ID "box") .
<div id="box">
<div class="vertical">Welcome to <strong>The Box!</strong></div>
</div>
CSS . background-color border CSS transitions , .
#box {
background-color: rgba(40, 40, 190, 1);
border: 4px solid rgb(20, 20, 120);
transition:
background-color 1s,
border 1s;
width: 350px;
height: 350px;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.vertical {
color: white;
font: 32px "Arial";
}
.extra {
width: 350px;
height: 350px;
margin-top: 10px;
border: 4px solid rgb(20, 20, 120);
text-align: center;
padding: 20px;
}
, Intersection Observer API JavaScript .
, observer .
const numSteps = 20.0;
let boxElement;
let prevRatio = 0.0;
let increasingColor = "rgba(40, 40, 190, ratio)";
let decreasingColor = "rgba(190, 40, 40, ratio)";
// Set things up
window.addEventListener(
"load",
(event) => {
boxElement = document.querySelector("#box");
createObserver();
},
false,
);
.
numSteps0.0 1.0 .
prevRatio. .
increasingColor. "ratio" , .
decreasingColor, .
load Window.addEventListener() . , querySelector() "box" ID , createObserver() .
createObserver() IntersectionObserver .
function createObserver() {
let observer;
let options = {
root: null,
rootMargin: "0px",
threshold: buildThresholdList(),
};
observer = new IntersectionObserver(handleIntersect, options);
observer.observe(boxElement);
}
options . root null . rootMargin "0px" . ( ) .
threshold buildThresholdList() . .
options , IntersectionObserver() , handleIntersect() . observe() .
observer.observe() .
buildThresholdList() .
function buildThresholdList() {
let thresholds = [];
let numSteps = 20;
for (let i = 1.0; i <= numSteps; i++) {
let ratio = i / numSteps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
1 numSteps i i/numSteps thresholds 0.0 1.0 . 0 . , numSteps(20) .
| # | Ratio | # | Ratio |
|---|---|---|---|
| 0 | 0.05 | 11 | 0.6 |
| 1 | 0.1 | 12 | 0.65 |
| 2 | 0.15 | 13 | 0.7 |
| 3 | 0.2 | 14 | 0.75 |
| 4 | 0.25 | 15 | 0.8 |
| 5 | 0.3 | 16 | 0.85 |
| 6 | 0.35 | 17 | 0.9 |
| 7 | 0.4 | 18 | 0.95 |
| 8 | 0.45 | 19 | 1 |
| 9 | 0.5 | 20 | 0 |
| 10 | 0.55 |
, , . .
( ID "box" ) , handleIntersect() .
function handleIntersect(entries, observer) {
entries.forEach((entry) => {
if (entry.intersectionRatio > prevRatio) {
entry.target.style.backgroundColor = increasingColor.replace(
"ratio",
entry.intersectionRatio,
);
} else {
entry.target.style.backgroundColor = decreasingColor.replace(
"ratio",
entry.intersectionRatio,
);
}
prevRatio = entry.intersectionRatio;
});
}
entries IntersectionObserverEntry intersectionRatio . , background-color increasingColor(. "rgba(40, 40, 190, ratio)" .) , "ratio" intersectionRatio . , . , .
, intersectionRatio , decreasingColor background-color "ratio" intersectionRatio .
, prevRatio .
. .
. Timing element visibility with the Intersection Observer API.
| Specification |
|---|
| Intersection Observer # intersection-observer-interface |
IntersectionObserver and IntersectionObserverEntryThis page was last modified on 2025 12 4 by MDN contributors.
Your blueprint for a better internet.
Portions of this content are 19982026 by individual mozilla.org contributors. Content available under a Creative Commons license.
| Web Proxy Viewer | New URL | Original Page |