๐ฆ INTERSECTION OBSERVER
๐น Intersection Observer : ์์์ ๊ฐ์์ฑ ๊ด์ฐฐ
- ๋ธ๋ผ์ฐ์
viewport์ ์ค์ ํ ์์(Element)์ ๊ต์ฐจ์ ์ ๊ด์ฐฐํ๋ฉฐ,
์์๊ฐ ๋ทฐํฌํธ์ ํฌํจ๋๋์ง ํฌํจ๋์ง ์๋์ง,
(๋ ์ฝ๊ฒ๋) ์ฌ์ฉ์ ํ๋ฉด์ ์ง๊ธ ๋ณด์ด๋ ์์์ธ์ง ์๋์ง๋ฅผ ๊ตฌ๋ณํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
- ์ด ๊ธฐ๋ฅ์ ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ค.
new IntersectionObserver()๋ฅผ ํตํด ์์ฑํ ์ธ์คํด์ค(io)๋ก
๊ด์ฐฐ์(Observer)๋ฅผ ์ด๊ธฐํํ๊ณ ๊ด์ฐฐํ ๋์(Element)์ ์ง์ ํ๋ค.
- ์์ฑ์๋ 2๊ฐ์ ์ธ์(
callback, options)๋ฅผ ๊ฐ์ง๋ค.
const io = new IntersectionObserver(callback, options);
io.observe(element);
๐น callback
- ์ฝ๋ฐฑํจ์ : ๋ค๋ฅธ ํจ์์ ์ธ์๋ก ๋๊ฒจ์ง๋ ํจ์
- ๊ด์ฐฐํ ๋์(
target)์ด ๋ฑ๋ก๋๊ฑฐ๋ ๊ฐ์์ฑ(visibility, ๋ณด์ด๋์ง ์๋ณด์ด๋์ง)์ ๋ณํ๊ฐ ์๊ธฐ๋ฉด
๊ด์ฐฐ์๋ ์ฝ๋ฐฑ(callback)์ ์คํํ๋ค.
- ์ฝ๋ฐฑ์ 2๊ฐ์ ์ธ์(
entries, observer)๋ฅผ ๊ฐ์ง๋ค.
const io = new IntersectionObserver( (entries, observer) => {} , options );
io.observe(element);
๐น entries
entries๋ IntersectionObserverEntry ์ธ์คํด์ค์ ๋ฐฐ์ด์ด๋ค.
IntersectionObserverEntry ๋ ์ฝ๊ธฐ์ ์ฉ(Read only)์ ๋ค์ ์์ฑ๋ค์ ํฌํจํ๋ค.
boundingClientRect : ๊ด์ฐฐ๋์์ ์ฌ๊ฐํ ์ ๋ณด

intersectionRect : ๊ด์ฐฐ๋์์ ๊ต์ฐจํ ์์ญ ์ ๋ณด

intersectionRatio : ๊ด์ฐฐ๋์์ ๊ต์ฐจํ ์์ญ ๋ฐฑ๋ถ์จ
(intersectionRect์์ญ์์ boundingClientRect์์ญ๊น์ง ๋น์จ, Number)
isInterecting : ๊ด์ฐฐ๋์์ ๊ต์ฐจ ์ํ(Boolean)

rootBounds : ์ง์ ํ ๋ฃจํธ ์์์ ์ฌ๊ฐํ ์ ๋ณด
target : ๊ด์ฐฐ ๋์ ์์ (Element)
time : ๋ณ๊ฒฝ์ด ๋ฐ์ํ ์๊ฐ ์ ๋ณด
๐น observer
- ์ฝ๋ฐฑ์ด ์คํ๋๋ ํด๋น ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๋ค.
const io = new IntersectionObserver((entries, observer) => {
console.log(observer); ๐ ๐ข๐IntersectionObserver์ ๊ฐ์ฒด๊ฐ ์ถ๋ ฅ๋๋ค.๐ข
}, options);
io.observe(element);
๐น options
root
target์ ๊ฐ์์ฑ์ ๊ฒ์ฌํ๊ธฐ ์ํด ๋ทฐํฌํธ ๋์ ์ฌ์ฉํ ์์ ๊ฐ์ฒด(๋ฃจํธ์์)๋ฅผ ์ง์ ํ๋ค.
target์ ์กฐ์์์์ด์ด์ผ ํ๋ฉฐ ์ง์ ํ์ง ์๊ฑฐ๋ null์ผ ๊ฒฝ์ฐ
๋ธ๋ผ์ฐ์ ์ ๋ทฐํฌํธ๊ฐ ๊ธฐ๋ณธ ์ฌ์ฉ๋๋ค.
- ๊ธฐ๋ณธ๊ฐ์
null
const io = new IntersectionObserver(callback, {
root : document.getElementId('my-viewport');
})
threshold
- ์ต์ ๋ฒ๊ฐ ์คํ๋๊ธฐ ์ํด
target์ ๊ฐ์์ฑ์ด ์ผ๋ง๋ ํ์ํ์ง ๋ฐฑ๋ถ์จ๋ก ํ์ํ๋ค.
- ๊ธฐ๋ณธ๊ฐ์
Arrayํ์
์ [0]์ด์ง๋ง Number ํ์
์ ๋จ์ผ ๊ฐ์ผ๋ก๋ ์์ฑํ ์ ์๋ค.
0 : target์ ๊ฐ์ฅ์๋ฆฌ ํฝ์
์ด Root๋ฒ์๋ฅผ ๊ต์ฐจํ๋ ์๊ฐ
(target์ ๊ฐ์์ฑ์ด 0%์ผ ๋) ์ต์ ๋ฒ๊ฐ ์คํ๋๋ค.

0.3 : target์ ๊ฐ์์ฑ 30%์ผ ๋ ์ต์ ๋ฒ๊ฐ ์คํ๋๋ค.

[0, 0.3, 1] : target์ ๊ฐ์์ฑ์ด 0% , 30% , 100%์ผ ๋ ๋ชจ๋ ์ต์ ๋ฒ๊ฐ ์คํ๋๋ค.

const io = new IntersectionObserver(callback, {
threhold : 0.3
})
๐น Method
observe() : ๋์ ์์์ ๊ด์ฐฐ์ ์์ํ๋ค.
unobserve() : ๋์ ์์์ ๊ด์ฐฐ์ ์ค์งํ๋ค.
disconnect() : IntersectionObserver ์ธ์คํด์ค๊ฐ ๊ด์ฐฐํ๋ ๋ชจ๋ ์์์ ๊ด์ฐฐ์ ์ค์งํ๋ค.
๐ฆ children
- ์์ ์์์ ์ ๊ทผ
- ํ์ฌ ์์์ ์์ ์์๊ฐ ํฌํจ๋ HTMLCollection์ ๋ฐํํฉ๋๋ค.
document.querySelector("div").children

๐ฆ element.offsetHeight
margin์ ์ ์ธํ, padding๊ฐ, border๊ฐ๊น์ง ๊ณ์ฐํ ๊ฐ์ ๊ฐ์ ธ์จ๋ค
๐ฆ element.clientHeight
margin๊ฐ๊ณผ border๊ฐ์ด ์ ์ธ๋, padding๊ฐ๊น์ง๋ง ์ ์ฉ๋ ๋ด๋ถ์ ์ค์ ํฌ๊ธฐ๋ฅผ ๊ฐ์ ธ์จ๋ค
- ์์ฆ์
scroll์ด๋ touchstart ๊ฐ์ ์ด๋ฒคํธ์ passive ์ต์
์ ์ถ๊ฐํ์ง ์์ผ๋ฉด ์ฝ์์ ๊ฒฝ๊ณ ๊น์ง ๋ฌ๋ค.
passive๊ฐ true์ธ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ preventDefault()๋ฅผ ํธ์ถํ ์ ์๋ค.
preventDefault()๋ฅผ ํธ์ถํ ์ผ์ด ์์ผ๋, ๋ธ๋ผ์ฐ์ ์ ๋ฉ์ธ ์ฐ๋ ๋์๊น์ง ์
์ํฅ์ ๋ผ์น๋ ์ผ ์ ๋ง์ ์ ์๋ค.
๐ฆ ์ด๋ฒคํธ์ ์ต์
addEventListener() ํจ์๋ ํ๋ผ๋ฉํฐ๋ก ์ต์
์ ์ถ๊ฐํ ์ ์๋ค
capture: ๊ธฐ๋ณธ๊ฐ false. ์ด๋ฒคํธ๋ฅผ ์บก์ณ๋ง(Capturing) ๋ฐฉ์์ผ๋ก ์ ํ(Propagation) ํ ์ง๋ฅผ ๊ฒฐ์ ํ๋ค. ์ด๋ฒคํธ ์บก์ณ๋ง๊ณผ ๋ฒ๋ธ๋ง์ ๋ํ ์ดํด๊ฐ ํ์ํ๋ค.
once: ์ด๋ฒคํธ๊ฐ ํ๋ฒ๋ง ํธ์ถ๋๊ณ ๋ฑ๋กํ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์ญ์ . ํ๋ฒ ์ฌ์ฉํ ํ๊ธฐํด์ผ ํ๋ ๊ฒฝ์ฐ.
passive: ๊ธฐ๋ณธ๊ฐ false.
true ์ธ ๊ฒฝ์ฐ ์ฝ๋ฐฑ ํจ์์์ preventDefault()(์ด๋ฒคํธ ์ทจ์ ๋ฐ ํ๊ฒ์ ๊ธฐ๋ณธ ๋์ ์ฐจ๋จ) ๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ด๋ฒคํธ์ ์ํด ์คํฌ๋กค์ด ๋ธ๋ญ๋๋ ๊ฒ์ ๋ง์์ฃผ๋ฉฐ, ์ฃผ๋ก ๋ชจ๋ฐ์ผ ๋ธ๋ผ์ฐ์ ์ ์คํฌ๋กค ์ฑ๋ฅ ํฅ์์ ์ํด ์ถ๊ฐ๋ ์ต์
์ด๋ค.
๐น ๋ด๊ฐ ๋ง๋ ๋ฌดํ์คํฌ๋กค ์์ค
setTableScrollInfinity : function () {
tableDivElem.addEventListener('scroll', () => {
let $tr = cmtListElem.lastElementChild;
const io = new IntersectionObserver((entries, observer) => {
const entry = entries[0];
const ioTarget = entry.target;
if (entry.isIntersecting && this.tableItemLength === this.tableLimit) {
console.log('ํ์ฌ ๋ณด์ด๋ ํ๊ฒ : ', ioTarget);
io.unobserve($tr);
this.tableItemLength = 0;
this.getCmtList(++this.currentTablePage);
$tr = cmtListElem.lastElementChild;
io.observe($tr);
}
}, {
root : tableDivElem,
threshold : 0.3
});
io.observe($tr);
}, {passive : true});
},