Intersection Observer API๋ฅผ ์ฌ์ฉํ์ฌ ์ง์ฐ ๋ก๋ฉ๊ณผ ๋ฌดํ ์คํฌ๋กค์ ๊ตฌํํ๊ณ , ์ ์ธ๊ณ์ ์ผ๋ก ์น์ฌ์ดํธ ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
Intersection Observer: ์ง์ฐ ๋ก๋ฉ๊ณผ ๋ฌดํ ์คํฌ๋กค๋ก ์น ์ฑ๋ฅ ์ต์ ํํ๊ธฐ
์ค๋๋ ์ ์น ๊ฐ๋ฐ ํ๊ฒฝ์์ ์ฑ๋ฅ์ ๊ฐ์ฅ ์ค์ํฉ๋๋ค. ์ฌ์ฉ์๋ค์ ์์น๋ ๊ธฐ๊ธฐ์ ์๊ด์์ด ๋น ๋ฅด๊ณ ๋ฐ์์ด ๋น ๋ฅธ ์น์ฌ์ดํธ๋ฅผ ๊ธฐ๋ํฉ๋๋ค. Intersection Observer API๋ ์ง์ฐ ๋ก๋ฉ(lazy loading) ๋ฐ ๋ฌดํ ์คํฌ๋กค(infinite scroll)๊ณผ ๊ฐ์ ๊ธฐ์ ์ ๊ตฌํํ์ฌ ์น ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํค๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํด ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ง๋ค๊ธฐ ์ํด Intersection Observer API๋ฅผ ์ดํดํ๊ณ ํ์ฉํ๋ ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
Intersection Observer API๋ ๋ฌด์์ธ๊ฐ?
Intersection Observer API๋ ํ๊ฒ ์์๊ฐ ์กฐ์ ์์ ๋๋ ๋ฌธ์์ ๋ทฐํฌํธ์ ๊ต์ฐจํ๋ ์ง์ ์ ๋ณํ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๊ด์ฐฐํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๊ฐ๋จํ ๋งํด, ์ง์์ ์ธ ํด๋ง์ด๋ ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์๋ชจํ๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์์ด๋ ์์๊ฐ ํ๋ฉด์ ๋ณด์ด๊ฒ ๋๋ ์์ (๋๋ ๋ค๋ฅธ ์์๋ฅผ ๊ธฐ์ค์ผ๋ก)์ ๊ฐ์งํ ์ ์๊ฒ ํด์ค๋๋ค. ์ด๋ ์ค์ ๋ก ํ์ํ ๋๊น์ง ํน์ ์์ ์ ๋ก๋ฉ์ด๋ ์คํ์ ์ง์ฐ์ํฌ ์ ์๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ต์ ํ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ฃผ์ ๊ฐ๋ :
- ํ๊ฒ ์์(Target Element): ๊ต์ฐจ ์ฌ๋ถ๋ฅผ ๊ด์ฐฐํ๊ณ ์ ํ๋ ์์์ ๋๋ค.
- ๋ฃจํธ ์์(Root Element): ๊ต์ฐจ๋ฅผ ์ํ ๋ทฐํฌํธ(๋๋ ๊ฒฝ๊ณ ์์) ์ญํ ์ ํ๋ ์กฐ์ ์์์
๋๋ค.
null
๋ก ์ค์ ํ๋ฉด ๋ฌธ์์ ๋ทฐํฌํธ๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. - ์๊ณ๊ฐ(Threshold): ํ๊ฒ ์์์ ๊ฐ์์ฑ์ด ์ด๋ ๋น์จ์ ๋๋ฌํ์ ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์คํํ ์ง๋ฅผ ๋ํ๋ด๋ ์ซ์ ๋๋ ์ซ์ ๋ฐฐ์ด์ ๋๋ค. ์๊ณ๊ฐ์ด 0์ด๋ฉด ํ๊ฒ์ ๋จ 1ํฝ์ ์ด๋ผ๋ ๋ณด์ด์๋ง์ ์ฝ๋ฐฑ์ด ์คํ๋ฉ๋๋ค. 1.0์ ํ๊ฒ ์์๊ฐ 100% ๋ณด์ฌ์ผ ํจ์ ์๋ฏธํฉ๋๋ค.
- ์ฝ๋ฐฑ ํจ์(Callback Function): ๊ต์ฐจ ์ํ๊ฐ ๋ณ๊ฒฝ๋์ด ์ง์ ๋ ์๊ณ๊ฐ์ ์ถฉ์กฑํ ๋ ์คํ๋๋ ํจ์์ ๋๋ค.
- ๊ต์ฐจ ๋น์จ(Intersection Ratio): ๋ฃจํธ ์์ ๋ด์์ ๋ณด์ด๋ ํ๊ฒ ์์์ ๋น์จ์ ๋ํ๋ด๋ 0๊ณผ 1 ์ฌ์ด์ ๊ฐ์ ๋๋ค.
์ง์ฐ ๋ก๋ฉ: ํ์ํ ๋ ๋ฆฌ์์ค ๋ก๋ํ๊ธฐ
์ง์ฐ ๋ก๋ฉ์ ๋ฆฌ์์ค(์ด๋ฏธ์ง, ๋น๋์ค, ์คํฌ๋ฆฝํธ ๋ฑ)๊ฐ ํ์ํ ๋๊น์ง, ์ฆ ์ผ๋ฐ์ ์ผ๋ก ๋ทฐ์ ๋ค์ด์ค๊ธฐ ์ง์ ๊น์ง ๋ก๋๋ฅผ ์ง์ฐ์ํค๋ ๊ธฐ์ ์ ๋๋ค. ์ด๋ ํนํ ๋ง์ ๋ฆฌ์์ค๊ฐ ์๋ ํ์ด์ง์์ ์ด๊ธฐ ํ์ด์ง ๋ก๋ ์๊ฐ์ ํฌ๊ฒ ์ค์ด๊ณ ์ฑ๋ฅ์ ํฅ์์ํต๋๋ค. ๋ชจ๋ ์ด๋ฏธ์ง๋ฅผ ํ ๋ฒ์ ๋ก๋ํ๋ ๋์ , ์ฌ์ฉ์๊ฐ ์ฆ์ ๋ณผ ๊ฐ๋ฅ์ฑ์ด ์๋ ์ด๋ฏธ์ง๋ง ๋ก๋ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์คํฌ๋กคํ๋ฉด ๋ ๋ง์ ์ด๋ฏธ์ง๊ฐ ๋ก๋๋ฉ๋๋ค. ์ด๋ ์ธํฐ๋ท ์ฐ๊ฒฐ์ด ๋๋ฆฌ๊ฑฐ๋ ๋ฐ์ดํฐ ์๊ธ์ ๊ฐ ์ ํ์ ์ธ ์ฌ์ฉ์์๊ฒ ํนํ ์ ์ฉํฉ๋๋ค.
Intersection Observer๋ก ์ง์ฐ ๋ก๋ฉ ๊ตฌํํ๊ธฐ
Intersection Observer API๋ฅผ ์ฌ์ฉํ์ฌ ์ง์ฐ ๋ก๋ฉ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- HTML ์ค์ : ์ค์ ์ด๋ฏธ์ง URL์ ํฌํจํ๋
data-src
์์ฑ์ ๊ฐ์ง ํ๋ ์ด์คํ๋ ์ด๋ฏธ์ง ๋๋ ๋น<img>
ํ๊ทธ๋ก ์์ํฉ๋๋ค. - Intersection Observer ์์ฑ: ์ฝ๋ฐฑ ํจ์์ ์ ํ์ ์ต์
๊ฐ์ฒด๋ฅผ ์ ๋ฌํ์ฌ ์๋ก์ด
IntersectionObserver
๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํฉ๋๋ค. - ํ๊ฒ ์์ ๊ด์ฐฐ:
observe()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ํ๊ฒ ์์(์ด ๊ฒฝ์ฐ ์ด๋ฏธ์ง)๋ฅผ ๊ด์ฐฐ ์์ํฉ๋๋ค. - ์ฝ๋ฐฑ ํจ์ ๋ด์์: ํ๊ฒ ์์๊ฐ (์ง์ ๋ ์๊ณ๊ฐ์ ๋ฐ๋ผ) ๋ทฐํฌํธ์ ๊ต์ฐจํ ๋, ํ๋ ์ด์คํ๋๋ฅผ ์ค์ ์ด๋ฏธ์ง URL๋ก ๊ต์ฒดํฉ๋๋ค.
- ํ๊ฒ ์์ ๊ด์ฐฐ ์ค์ง: ์ด๋ฏธ์ง๊ฐ ๋ก๋๋๋ฉด ๋ ์ด์ ๋ถํ์ํ ์ฝ๋ฐฑ์ ๋ฐฉ์งํ๊ธฐ ์ํด ํ๊ฒ ์์์ ๊ด์ฐฐ์ ์ค์งํฉ๋๋ค.
์ฝ๋ ์์ : ์ด๋ฏธ์ง ์ง์ฐ ๋ก๋ฉ
์ด ์์ ๋ Intersection Observer API๋ฅผ ์ฌ์ฉํ ์ด๋ฏธ์ง ์ง์ฐ ๋ก๋ฉ์ ๋ณด์ฌ์ค๋๋ค.
<!-- HTML -->
<img data-src="image1.jpg" alt="์ด๋ฏธ์ง 1" class="lazy-load">
<img data-src="image2.jpg" alt="์ด๋ฏธ์ง 2" class="lazy-load">
<img data-src="image3.jpg" alt="์ด๋ฏธ์ง 3" class="lazy-load">
<script>
const lazyLoadImages = document.querySelectorAll('.lazy-load');
const options = {
root: null, // ๋ทฐํฌํธ๋ฅผ root๋ก ์ฌ์ฉ
rootMargin: '0px',
threshold: 0.2 // ์ด๋ฏธ์ง๊ฐ 20% ๋ณด์ผ ๋ ๋ก๋
};
const lazyLoad = (image, observer) => {
image.src = image.dataset.src;
image.onload = () => {
image.classList.remove('lazy-load');
observer.unobserve(image);
};
};
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
lazyLoad(entry.target, observer);
}
});
}, options);
lazyLoadImages.forEach(image => {
observer.observe(image);
});
</script>
์ง์ฐ ๋ก๋ฉ์ ์ด์ :
- ์ด๊ธฐ ๋ก๋ ์๊ฐ ๋จ์ถ: ํ์ํ ๋ฆฌ์์ค๋ง ๋ฏธ๋ฆฌ ๋ก๋ํจ์ผ๋ก์จ ์ด๊ธฐ ํ์ด์ง ๋ก๋ ์๊ฐ์ด ํฌ๊ฒ ์ค์ด๋ค์ด ๋ ๋น ๋ฅด๊ณ ๋ฐ์์ด ๋น ๋ฅธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค.
- ๋์ญํญ ์ ์ฝ: ์ฌ์ฉ์๋ ์ค์ ๋ก ํ์ํ ๋ฆฌ์์ค๋ง ๋ค์ด๋ก๋ํ๋ฏ๋ก, ํนํ ๋ชจ๋ฐ์ผ ๊ธฐ๊ธฐ๋ ๋ฐ์ดํฐ ์๊ธ์ ๊ฐ ์ ํ์ ์ธ ์ฌ์ฉ์์ ๋์ญํญ์ ์ ์ฝํ ์ ์์ต๋๋ค.
- ์ฑ๋ฅ ํฅ์: ๋ฆฌ์์ค ๋ก๋๋ฅผ ์ง์ฐ์ํค๋ฉด ๋ธ๋ผ์ฐ์ ๋ฆฌ์์ค๊ฐ ํ๋ณด๋์ด ์ ๋ฐ์ ์ธ ์ฑ๋ฅ์ด ํฅ์๋๊ณ ์คํฌ๋กค์ด ๋ ๋ถ๋๋ฌ์์ง๋๋ค.
- SEO ์ด์ : ๋น ๋ฅธ ๋ก๋ฉ ์๊ฐ์ ๊ฒ์ ์์ง์ ๊ธ์ ์ ์ธ ์์ ์์ธ์ ๋๋ค.
๋ฌดํ ์คํฌ๋กค: ๋๊น ์๋ ์ฝํ ์ธ ๋ก๋ฉ
๋ฌดํ ์คํฌ๋กค์ ์ฌ์ฉ์๊ฐ ํ์ด์ง๋ฅผ ์๋๋ก ์คํฌ๋กคํ ๋ ๋ ๋ง์ ์ฝํ ์ธ ๋ฅผ ๋ก๋ํ์ฌ ๋๊น ์๊ณ ์ฐ์์ ์ธ ๋ธ๋ผ์ฐ์ง ๊ฒฝํ์ ๋ง๋ค์ด์ฃผ๋ ๊ธฐ์ ์ ๋๋ค. ์ด๋ ์์ ๋ฏธ๋์ด ํผ๋, ์ ์์๊ฑฐ๋ ์ํ ๋ชฉ๋ก, ๋ด์ค ์น์ฌ์ดํธ์์ ํํ ์ฌ์ฉ๋ฉ๋๋ค. ์ฝํ ์ธ ๋ฅผ ๋ณ๋์ ํ์ด์ง๋ก ๋๋๋ ๋์ , ์ฌ์ฉ์๊ฐ ํ์ฌ ์ฝํ ์ธ ์ ๋์ ๋๋ฌํ๋ฉด ์๋ก์ด ์ฝํ ์ธ ๊ฐ ์๋์ผ๋ก ๋ก๋๋์ด ๊ธฐ์กด ์ฝํ ์ธ ์ ์ถ๊ฐ๋ฉ๋๋ค.
Intersection Observer๋ก ๋ฌดํ ์คํฌ๋กค ๊ตฌํํ๊ธฐ
Intersection Observer API๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์๊ฐ ์ฝํ ์ธ ์ ๋์ ๋๋ฌํ์์ ๊ฐ์งํ๊ณ ๋ ๋ง์ ์ฝํ ์ธ ๋ก๋ฉ์ ํธ๋ฆฌ๊ฑฐํ ์ ์์ต๋๋ค.
- ๊ฐ์ ์์(Sentinel Element) ์์ฑ: ์ฝํ
์ธ ๋์ ๊ฐ์ ์์(์:
<div>
)๋ฅผ ์ถ๊ฐํฉ๋๋ค. ์ด ์์๋ ์ฌ์ฉ์๊ฐ ํ์ด์ง ํ๋จ์ ๋๋ฌํ๋์ง ๊ฐ์งํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. - Intersection Observer ์์ฑ: ๊ฐ์ ์์๋ฅผ ๊ด์ฐฐํ๋ ์๋ก์ด
IntersectionObserver
๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํฉ๋๋ค. - ์ฝ๋ฐฑ ํจ์ ๋ด์์: ๊ฐ์ ์์๊ฐ ๋ทฐํฌํธ์ ๊ต์ฐจํ ๋ ๋ ๋ง์ ์ฝํ ์ธ ๋ก๋ฉ์ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ๋ค์ ๋ฐ์ดํฐ ๋ฐฐ์น๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ API ์์ฒญ์ ํฌํจํฉ๋๋ค.
- ์๋ก์ด ์ฝํ ์ธ ์ถ๊ฐ: ์๋ก์ด ์ฝํ ์ธ ๋ฅผ ๊ฐ์ ธ์จ ํ, ํ์ด์ง์ ๊ธฐ์กด ์ฝํ ์ธ ์ ์ถ๊ฐํฉ๋๋ค.
- ๊ฐ์ ์์ ์ด๋: ์๋ก์ด ์ฝํ ์ธ ๋ฅผ ์ถ๊ฐํ ํ, ์ถ๊ฐ์ ์ธ ์คํฌ๋กค์ ๊ณ์ ๊ด์ฐฐํ๊ธฐ ์ํด ๊ฐ์ ์์๋ฅผ ์๋ก ์ถ๊ฐ๋ ์ฝํ ์ธ ์ ๋์ผ๋ก ์ด๋์ํต๋๋ค.
์ฝ๋ ์์ : ๋ฌดํ ์คํฌ๋กค
์ด ์์ ๋ Intersection Observer API๋ฅผ ์ฌ์ฉํ ๋ฌดํ ์คํฌ๋กค์ ๋ณด์ฌ์ค๋๋ค.
<!-- HTML -->
<div id="content">
<p>์ด๊ธฐ ์ฝํ
์ธ </p>
</div>
<div id="sentinel"></div>
<script>
const content = document.getElementById('content');
const sentinel = document.getElementById('sentinel');
let page = 1; // ์ด๊ธฐ ํ์ด์ง ๋ฒํธ
let loading = false; // ์ค๋ณต ๋ก๋ฉ ๋ฐฉ์ง ํ๋๊ทธ
const options = {
root: null, // ๋ทฐํฌํธ๋ฅผ root๋ก ์ฌ์ฉ
rootMargin: '0px',
threshold: 0.1 // ๊ฐ์ ์์๊ฐ 10% ๋ณด์ผ ๋ ๋ก๋
};
const loadMoreContent = async () => {
if (loading) return;
loading = true;
// API์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์๋ฎฌ๋ ์ด์
(์ค์ API ํธ์ถ๋ก ๋์ฒดํ์ธ์)
setTimeout(() => {
const newContent = Array.from({ length: 10 }, (_, i) => `<p>${page + 1}ํ์ด์ง ์ฝํ
์ธ , ํญ๋ชฉ ${i + 1}</p>`).join('');
content.innerHTML += newContent;
page++;
loading = false;
}, 1000);
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && !loading) {
loadMoreContent();
}
});
}, options);
observer.observe(sentinel);
</script>
๋ฌดํ ์คํฌ๋กค ๊ณ ๋ ค์ฌํญ:
- ์ ๊ทผ์ฑ: ๋ฌดํ ์คํฌ๋กค์ด ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์์๊ฒ๋ ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ํด์ผ ํฉ๋๋ค. ๋ง์ฐ์ค๋ ์คํฌ๋กค ํ ์ ์ฌ์ฉํ ์ ์๋ ์ฌ์ฉ์๋ฅผ ์ํด "๋ ๋ณด๊ธฐ" ๋ฒํผ๊ณผ ๊ฐ์ ๋์ฒด ํ์ ์ต์ ์ ์ ๊ณตํ์ธ์. ๋ํ, ์๋ก์ด ์ฝํ ์ธ ๊ฐ ๋ก๋๋ ํ ํฌ์ปค์ค๊ฐ ์ ์ ํ ๊ด๋ฆฌ๋์ด ์คํฌ๋ฆฐ ๋ฆฌ๋ ์ฌ์ฉ์๊ฐ ๋ณํ๋ฅผ ์ธ์งํ ์ ์๋๋ก ํ์ธ์.
- ์ฑ๋ฅ: ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ํผํ๊ธฐ ์ํด ์๋ก์ด ์ฝํ ์ธ ๋ก๋ฉ์ ์ต์ ํํ์ธ์. ๋๋ฐ์ด์ฑ์ด๋ ์ค๋กํ๋ง๊ณผ ๊ฐ์ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ API ์์ฒญ ๋น๋๋ฅผ ์ ํํ์ธ์.
- ์ฌ์ฉ์ ๊ฒฝํ: ๋ ๋ง์ ์ฝํ ์ธ ๊ฐ ๋ก๋๋๊ณ ์์์ ๋ํ๋ด๋ ์๊ฐ์ ํผ๋๋ฐฑ์ ์ ๊ณตํ์ธ์. ํ ๋ฒ์ ๋๋ฌด ๋ง์ ์ฝํ ์ธ ๋ก ์ฌ์ฉ์๋ฅผ ์๋ํ์ง ๋ง์ธ์. ์์ฒญ๋น ๋ก๋๋๋ ํญ๋ชฉ ์๋ฅผ ์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์.
- SEO: ๋ฌดํ ์คํฌ๋กค์ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํ๋์ง ์์ผ๋ฉด SEO์ ๋ถ์ ์ ์ธ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ๊ฒ์ ์์ง์ด ๋ชจ๋ ์ฝํ ์ธ ๋ฅผ ํฌ๋กค๋งํ๊ณ ์ธ๋ฑ์ฑํ ์ ์๋๋ก ํ์ธ์. ์ ์ ํ HTML ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๊ณ ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๋ฅผ ์ํด ํ์ด์ง๋ค์ด์ ๊ตฌํ์ ๊ณ ๋ คํ์ธ์.
- History API: History API๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์๊ฐ ์คํฌ๋กคํ ๋ URL์ ์ ๋ฐ์ดํธํ์ฌ ํ์ด์ง์ ํน์ ์น์ ์ ๊ณต์ ํ๊ฑฐ๋ ๋ถ๋งํฌํ ์ ์๋๋ก ํ์ธ์.
๋ธ๋ผ์ฐ์ ํธํ์ฑ ๋ฐ ํด๋ฆฌํ
Intersection Observer API๋ ๋๋ถ๋ถ์ ์ต์ ๋ธ๋ผ์ฐ์ ์์ ๋๋ฆฌ ์ง์๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ๊ตฌํ ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ์ง ์์ ์ ์์ต๋๋ค. ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ํธํ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ํด๋ฆฌํ(polyfill)์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํด๋ฆฌํ์ ๊ตฌํ ๋ธ๋ผ์ฐ์ ์์ ์๋ก์ด API์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ฝ๋ ์กฐ๊ฐ์ ๋๋ค.
์ฌ๋ฌ Intersection Observer ํด๋ฆฌํ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ธ๊ธฐ ์๋ ์ต์ ์ค ํ๋๋ ๊ณต์ W3C ํด๋ฆฌํ์ ๋๋ค. ํด๋ฆฌํ์ ์ฌ์ฉํ๋ ค๋ฉด Intersection Observer API๋ฅผ ์ฌ์ฉํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋ ์์ HTML์ ํฌํจ์ํค๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
<script src="intersection-observer.js"></script>
<script src="your-script.js"></script>
๋ชจ๋ฒ ์ฌ๋ก ๋ฐ ์ต์ ํ ๊ธฐ๋ฒ
- ์ ์ ํ ์๊ณ๊ฐ(Threshold) ์ ํ: ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ ์ฌ์ด์ ์ต์ ์ ๊ท ํ์ ์ฐพ๊ธฐ ์ํด ๋ค์ํ ์๊ณ๊ฐ์ผ๋ก ์คํํด๋ณด์ธ์. ๋ฎ์ ์๊ณ๊ฐ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ ์ผ์ฐ ํธ๋ฆฌ๊ฑฐํ๊ณ , ๋์ ์๊ณ๊ฐ์ ์ง์ฐ์ํต๋๋ค.
- API ์์ฒญ์ ๋๋ฐ์ด์ค ๋๋ ์ค๋กํ ์ ์ฉ: ์๋ฒ ๊ณผ๋ถํ๋ฅผ ํผํ๊ณ ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํด ๋ฌดํ ์คํฌ๋กค์ API ์์ฒญ ๋น๋๋ฅผ ์ ํํ์ธ์. ๋๋ฐ์ด์ฑ์ ๋ง์ง๋ง ํธ์ถ ์ดํ ์ผ์ ์๊ฐ์ด ์ง๋ ํ์๋ง ํจ์๊ฐ ํธ์ถ๋๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ค๋กํ๋ง์ ์ง์ ๋ ์๊ฐ ๋์ ํจ์๊ฐ ์ต๋ ํ ๋ฒ๋ง ํธ์ถ๋๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ์ด๋ฏธ์ง ๋ก๋ฉ ์ต์ ํ: ์ต์ ํ๋ ์ด๋ฏธ์ง ํ์(์: WebP)์ ์ฌ์ฉํ๊ณ ์ด๋ฏธ์ง๋ฅผ ์์ถํ์ฌ ํ์ผ ํฌ๊ธฐ๋ฅผ ์ค์ด์ธ์. ์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ(CDN)๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ์์น์ ๊ฐ๊น์ด ์๋ฒ์์ ์ด๋ฏธ์ง๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์.
- ๋ก๋ฉ ํ์๊ธฐ ์ฌ์ฉ: ๋ฆฌ์์ค๊ฐ ๋ก๋๋๊ณ ์์์ ๋ํ๋ด๋ ์๊ฐ์ ํผ๋๋ฐฑ์ ์ ๊ณตํ์ธ์. ๊ฐ๋จํ ์คํผ๋๋ ์งํ๋ฅ ํ์์ค์ด ๋ ์ ์์ต๋๋ค.
- ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌ: ๋ฆฌ์์ค ๋ก๋์ ์คํจํ๋ ๊ฒฝ์ฐ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ์ธ์. ์ฌ์ฉ์์๊ฒ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๊ณ ๋ฆฌ์์ค ๋ก๋๋ฅผ ์ฌ์๋ํ ์ ์๋ ์ต์ ์ ์ ๊ณตํ์ธ์.
- ๋ ์ด์ ํ์ํ์ง ์์ ์์ ๊ด์ฐฐ ์ค์ง: ๋ ์ด์ ํ์ํ์ง ์์ ์์์ ๊ด์ฐฐ์ ์ค์งํ๋ ค๋ฉด
unobserve()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ธ์. ์ด๋ ๋ธ๋ผ์ฐ์ ๋ฆฌ์์ค๋ฅผ ํ๋ณดํ๊ณ ์ฑ๋ฅ์ ํฅ์์ํต๋๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ฏธ์ง๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋ก๋๋๋ฉด ๊ด์ฐฐ์ ์ค์งํด์ผ ํฉ๋๋ค.
์ ๊ทผ์ฑ ๊ณ ๋ ค์ฌํญ
์ง์ฐ ๋ก๋ฉ๊ณผ ๋ฌดํ ์คํฌ๋กค์ ๊ตฌํํ ๋๋ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๋ฅผ ํฌํจํ ๋ชจ๋ ์ฌ๋์ด ์น์ฌ์ดํธ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์ ๊ทผ์ฑ์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ๋์ฒด ๋ค๋น๊ฒ์ด์ ์ ๊ณต: ๋ฌดํ ์คํฌ๋กค์ ๊ฒฝ์ฐ, ๋ง์ฐ์ค๋ ์คํฌ๋กค ํ ์ ์ฌ์ฉํ ์ ์๋ ์ฌ์ฉ์๋ฅผ ์ํด "๋ ๋ณด๊ธฐ" ๋ฒํผ์ด๋ ํ์ด์ง๋ค์ด์ ๊ณผ ๊ฐ์ ๋์ฒด ํ์ ์ต์ ์ ์ ๊ณตํ์ธ์.
- ํฌ์ปค์ค ๊ด๋ฆฌ: ๋ฌดํ ์คํฌ๋กค๋ก ์๋ก์ด ์ฝํ
์ธ ๋ฅผ ๋ก๋ํ ๋ ํฌ์ปค์ค๊ฐ ์ ์ ํ ๊ด๋ฆฌ๋๋๋ก ํ์ธ์. ์๋ก ๋ก๋๋ ์ฝํ
์ธ ๋ก ํฌ์ปค์ค๋ฅผ ์ด๋ํ์ฌ ์คํฌ๋ฆฐ ๋ฆฌ๋ ์ฌ์ฉ์๊ฐ ๋ณํ๋ฅผ ์ธ์งํ ์ ์๋๋ก ํ์ธ์. ์ด๋ ์ ์ฝํ
์ธ ์ ์ปจํ
์ด๋ ์์์
tabindex
์์ฑ์-1
๋ก ์ค์ ํ ๋ค์ ํด๋น ์์์focus()
๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ฌ์ฑํ ์ ์์ต๋๋ค. - ์๋งจํฑ HTML ์ฌ์ฉ: ์๋งจํฑ HTML ์์๋ฅผ ์ฌ์ฉํ์ฌ ์ฝํ
์ธ ์ ๊ตฌ์กฐ์ ์๋ฏธ๋ฅผ ๋ถ์ฌํ์ธ์. ์ด๋ ์คํฌ๋ฆฐ ๋ฆฌ๋๊ฐ ์ฝํ
์ธ ๋ฅผ ์ดํดํ๊ณ ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ด๋ จ ์ฝํ
์ธ ๋ฅผ ๊ทธ๋ฃนํํ๊ธฐ ์ํด
<article>
์์๋ฅผ ์ฌ์ฉํ์ธ์. - ARIA ์์ฑ ์ ๊ณต: ARIA(Accessible Rich Internet Applications) ์์ฑ์ ์ฌ์ฉํ์ฌ ๋ณด์กฐ ๊ธฐ์ ์ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ธ์. ์๋ฅผ ๋ค์ด, ํ์ด์ง์ ํน์ ์์ญ์ด ๋์ ์ผ๋ก ์
๋ฐ์ดํธ๋๊ณ ์์์ ๋ํ๋ด๊ธฐ ์ํด
aria-live
์์ฑ์ ์ฌ์ฉํ์ธ์. - ๋ณด์กฐ ๊ธฐ์ ๋ก ํ ์คํธ: ์คํฌ๋ฆฐ ๋ฆฌ๋์ ๊ฐ์ ๋ณด์กฐ ๊ธฐ์ ๋ก ์น์ฌ์ดํธ๋ฅผ ํ ์คํธํ์ฌ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์์๊ฒ ์ ๊ทผ ๊ฐ๋ฅํ์ง ํ์ธํ์ธ์.
์ค์ ์ฌ์ฉ ์ฌ๋ก
๋ง์ ์ธ๊ธฐ ์น์ฌ์ดํธ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ธฐ ์ํด ์ง์ฐ ๋ก๋ฉ๊ณผ ๋ฌดํ ์คํฌ๋กค์ ์ฌ์ฉํฉ๋๋ค. ๋ช ๊ฐ์ง ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์์ ๋ฏธ๋์ด ํ๋ซํผ (์: Facebook, Twitter, Instagram): ์ด๋ฌํ ํ๋ซํผ์ ์ฌ์ฉ์๊ฐ ํผ๋๋ฅผ ์๋๋ก ์คํฌ๋กคํ ๋ ๋ ๋ง์ ์ฝํ ์ธ ๋ฅผ ๋ก๋ํ๊ธฐ ์ํด ๋ฌดํ ์คํฌ๋กค์ ์ฌ์ฉํฉ๋๋ค. ๋ํ, ์ด๋ฏธ์ง์ ๋น๋์ค๊ฐ ๋ทฐ์ ๋ค์ด์ค๊ธฐ ์ง์ ์๋ง ๋ก๋ํ๊ธฐ ์ํด ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํฉ๋๋ค.
- ์ ์์๊ฑฐ๋ ์น์ฌ์ดํธ (์: Amazon, Alibaba, eBay): ์ด๋ฌํ ์น์ฌ์ดํธ๋ ์ ํ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๊ธฐ ์ํด ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ๊ณ , ์ฌ์ฉ์๊ฐ ํ์ด์ง๋ฅผ ์๋๋ก ์คํฌ๋กคํ ๋ ๋ ๋ง์ ์ ํ ๋ชฉ๋ก์ ๋ก๋ํ๊ธฐ ์ํด ๋ฌดํ ์คํฌ๋กค์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ํนํ ์๋ง์ ์ ํ์ ๋ณด์ ํ ์ ์์๊ฑฐ๋ ์ฌ์ดํธ์ ์ค์ํฉ๋๋ค.
- ๋ด์ค ์น์ฌ์ดํธ (์: The New York Times, BBC News): ์ด๋ฌํ ์น์ฌ์ดํธ๋ ์ด๋ฏธ์ง์ ๋น๋์ค๋ฅผ ๋ก๋ํ๊ธฐ ์ํด ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ๊ณ , ์ฌ์ฉ์๊ฐ ํ์ด์ง๋ฅผ ์๋๋ก ์คํฌ๋กคํ ๋ ๋ ๋ง์ ๊ธฐ์ฌ๋ฅผ ๋ก๋ํ๊ธฐ ์ํด ๋ฌดํ ์คํฌ๋กค์ ์ฌ์ฉํฉ๋๋ค.
- ์ด๋ฏธ์ง ํธ์คํ ํ๋ซํผ (์: Unsplash, Pexels): ์ด๋ฌํ ํ๋ซํผ์ ์ฌ์ฉ์๊ฐ ํ์ด์ง๋ฅผ ์๋๋ก ์คํฌ๋กคํ ๋ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๊ธฐ ์ํด ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํค๊ณ ๋์ญํญ ์๋น๋ฅผ ์ค์ ๋๋ค.
๊ฒฐ๋ก
Intersection Observer API๋ ์ง์ฐ ๋ก๋ฉ ๋ฐ ๋ฌดํ ์คํฌ๋กค๊ณผ ๊ฐ์ ๊ธฐ์ ์ ๊ตฌํํ์ฌ ์น ์ฑ๋ฅ์ ์ต์ ํํ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ์ด API๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๊ธฐ ํ์ด์ง ๋ก๋ ์๊ฐ์ ํฌ๊ฒ ์ค์ด๊ณ , ๋์ญํญ์ ์ ์ฝํ๋ฉฐ, ์ ๋ฐ์ ์ธ ์ฑ๋ฅ์ ํฅ์์ํค๊ณ , ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํด ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ธฐ์ ์ ๊ตฌํํ ๋ ๋ชจ๋ ์ฌ๋์ด ์น์ฌ์ดํธ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์ ๊ทผ์ฑ์ ๊ณ ๋ คํ๋ ๊ฒ์ ์์ง ๋ง์ธ์. ์ด ๊ธ์์ ์ค๋ช ํ ๊ฐ๋ ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํดํจ์ผ๋ก์จ, Intersection Observer API๋ฅผ ํ์ฉํ์ฌ ๋ ๋น ๋ฅด๊ณ , ๋ ๋ฐ์์ด ๋น ๋ฅด๋ฉฐ, ๋ ์ ๊ทผ์ฑ ๋์ ์น์ฌ์ดํธ๋ฅผ ๊ตฌ์ถํ ์ ์์ต๋๋ค.