
๐ก IntersectionObserver
๋ทฐํฌํธ ์ฌ์ด์ ๊ต์ฐจ ์์ญ์ ๊ฐ์ํ๊ณ , ํด๋น ๊ต์ฐจ ์์ญ์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ API๋ค.
์ด๋ฅผ ํตํด ์คํฌ๋กค, ๋ฌดํ์คํฌ๋กค, ์ด๋ฏธ์ง ๋ก๋ฉ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ค.
1. ๋น๋๊ธฐ์ ๊ฐ์
IntersectionObserver๋ ๋น๋๊ธฐ์ ์ผ๋ก ์์์ ๊ต์ฐจ ์ํ๋ฅผ ๊ฐ์ํ๋ค.
2. ๋น๋๊ธฐ์ ์ฝ๋ฐฑ ์คํ
๊ต์ฐจ ์์ญ์ด ๋ณ๊ฒฝ๋๋ฉด ์ฝ๋ฐฑ ํจ์๊ฐ ํธ์ถ๋๋ค.
์ด๋ฅผ ํตํด ๊ต์ฐจ ์์ญ์ ๋ณํ์ ๋ฐ๋ผ ๋์์ ์ฒ๋ฆฌํ ์ ์๋ค.
3. ๋ฃจํธ ์์์ ํ๊ฒ ์์
๊ต์ฐจ ์์ญ์ ๊ด์ฐฐํ๋ ์์๋ฃจํธ(root)
๊ต์ฐจ ์์ญ์ ๊ฐ์ํ๋ ๋์ ์์ํ๊ฒ(target)
๋ฃจํธ ์์๋ ๋์ ์์์ ๊ต์ฐจํ๋ ์์ญ์ ๊ด์ฐฐํ๊ณ , ๋ฃจํธ ์์์ ๊ธฐ๋ณธ ๊ฐ์ ๋ทฐํฌํธ๋ค.
4. ๊ต์ฐจ ์ํ ์ ๋ณด
์ฝ๋ฐฑ ํจ์์ ์ ๋ฌ๋๋ ์ธ์์๋ ๊ต์ฐจ ์ํ ์ ๋ณด๊ฐ ํฌํจ๋๋ค.
์ด ์ ๋ณด๋ ๋์ ์์์ ๋ฃจํธ ์์ ๊ฐ์ ๊ต์ฐจ ์์ญ์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค.
๋ฌดํ์คํฌ๋กค
์คํฌ๋กค์ ๋ด์ผ ๋ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๋์ ์ผ๋ก ๋ก๋ํ๋๋ฐ ์ฌ์ฉ๋๋ค.
์ด๋ฏธ์ง ๋ก๋ฉ ์ง์ฐ
์ด๋ฏธ์ง๊ฐ ๋ทฐํฌํธ ๋ด์ ์ง์ ํ์ ๋ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๋๋ก ํ ์ ์๋ค.
๊ด๊ณ ํธ๋ํน
๊ด๊ณ ๊ฐ ํ๋ฉด์ ๋ณด์ด๋์ง ์ฌ๋ถ๋ฅผ ๊ฐ์ํ๊ฑฐ๋, ๊ด๊ณ ์ ํ์ถ ํ์๋ฅผ ์ถ์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
์น ํ์ด์ง ๋ถ์
ํน์ ์ปจํ ์ธ ์ ๊ฐ์์ฑ๊ณผ ์ฌ์ฉ์์ ์คํฌ๋กค ๋์์ ๋ถ์ํ๋๋ฐ ํ์ฉ๋๋ค.
์คํฌ๋กค์ด ๋์ ๋, ๋ง์ง๋ง ์์ดํ ์ด ๊ฐ์ง๋๋ฉด ๋ค์ ๋ฐ์ดํฐ๋ค์ด ๋ฟ๋ ค์ง๋ ๋ฌดํ์คํฌ๋กค ์ฝ๋๋ก ์์๋ฅผ ๋ค์ด๋ณด์.
listObserver = new IntersectionObserver((items, observer) => {
items.forEach((item) => {
// ์์ดํ
์ด ํ๋ฉด์ ๋ณด์ผ ๋
if (item.isIntersecting){
// ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๋ค
item.target.querySelector('img').src = item.target.querySelector('img').dataset.src;
// ๋ง์ง๋ง ์์์์ ํ์ธ
let dataIndex = Number(item.target.dataset.index);
// ๋ง์ง๋ง ์์๋ผ๋ฉด
if (dataIndex + 1 === this.data.length){
// nextPage๋ฅผ ํธ์ถํ๋ค
this.onNextPage();
}
}
});
});
item.isIntersecting์ ํด๋น ์์ดํ
์ด ํ์ฌ ๋ทฐํฌํธ์ ๋ณด์ด๋์ง๋ฅผ ๋ํ๋ด๋ ๋ถ๋ฆฌ์ธ ๊ฐ์ด๋ค.
item.target.querySelector('img').src = item.target.querySelector('img').dataset.src;
์์ดํ
์ด ํ๋ฉด์ ๋ณด์ด๋ฉด ์ด๋ฏธ์ง์ 'src'์์ฑ์ ํด๋น ์ด๋ฏธ์ง ์์์ data-src์์ฑ๊ฐ์ผ๋ก ๋ณ๊ฒฝํด ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๋ค.
์์ฑ๊ฐ์ ์ฌ์ฉํด ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๋ ์ด์ ๋ ์ง์ฐ๋ก๋ฉ(lazy loading)์ ๊ตฌํํ๊ธฐ ์ํด์๋ค.
์ง์ฐ ๋ก๋ฉ์ ์น ํ์ด์ง์ ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํ ๋ฐฉ๋ฒ ์ค ํ๋๋ก, ์ด๊ธฐ ๋ก๋ฉ ์์๋ ์ด๋ฏธ์ง๋ฅผ ์ค์ ๋ก ๋ก๋ํ์ง ์๊ณ ํ์ํ ๋๋ง ๋ก๋ํ๋ ๋ฐฉ์์ ์๋ฏธํ๋ค.
์ด๋ฅผ ํตํด ์ด๊ธฐ ํ์ด์ง ๋ก๋ฉ ์๊ฐ์ ์ค์ผ ์ ์๋ค.
let dataIndex = Number(item.target.dataset.index);
ํด๋น ์์ดํ
์ ์ธ๋ฑ์ค๋ฅผ ๊ฐ์ ธ์์ค๋ค.
dataIndex + 1 === this.data.length
ํด๋น ์์ดํ
์ด ๋ฐ์ดํฐ์ ๋ง์ง๋ง ์์ดํ
์ธ์ง์ ์ฌ๋ถ๋ฅผ ํ์ธํด์ค๋ค.
dataIndex์ 1์ ๋ํด์ค ์ด์ ๋ ๋ฐฐ์ด์ ์ธ๋ฑ์ค๊ฐ 0๋ถํฐ ์์ํ๊ธฐ ๋๋ฌธ์, ๋ง์ง๋ง ์์ดํ
์ ํ์ธํด ์ฃผ๊ธฐ ์ํด +1์ ์ถ๊ฐํ๋ค.
render() {
~~~~๋ ๋๋๋ ๋
์๋ค
this.$result.querySelectorAll('.item').forEach(($item, index) => {
this.listObserver.observe($item);
});
}
์ด์ render๋๋ ์์ญ์์ ํ๋ฉด์ ๋ฟ๋ ค์ง ์์ดํ
๋ค์ observe๋ฅผ ๋ฃ์ด์ค๋ค.
์ด๋ ๊ฒ ํ๋ฉด ๋ง์ง๋ง ์์ดํ
์ด ํ๋ฉด์ ๋ณด์ผ ๋ ์๋ก์ด ์ด๋ฏธ์ง๊ฐ ๋ก๋ฉ๋๋ฉฐ ๋ฌดํ ์คํฌ๋กค์ด ๊ฐ๋ฅํด์ง๋ค.