Skip to content

IntersectionObserver

J127_์šฐ์žฌ์„ edited this page Nov 6, 2021 · 1 revision

๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„์„ ํ•˜๋˜ ์ค‘ ์ •๋ณด๋ฅผ ์ฐพ์•„๋ณด๋‹ค๊ฐ€ Intersection Observer๋ฅผ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.

IntersectionObserver

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level documentโ€™s viewport.

Intersection Observer API๋Š” ํƒ€๊ฒŸ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์กฐ์ƒ ์—˜๋ฆฌ๋จผํŠธ, ๋˜๋Š” ์ตœ์ƒ์œ„ ๋ฌธ์„œ์˜ ๋ทฐํฌํŠธ(๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ๋ณดํ†ต ๋ธŒ๋ผ์šฐ์ €์˜ viewport)์˜ ๊ต์ฐจ์˜์—ญ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ณ€ํ™”๋ฅผ ๋น„๋™๊ธฐ๋กœ ๊ด€์ฐฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์–ด๋””์— ์“ฐ์ผ๊นŒ?

  • Lazy-loading of images or other content as a page is scrolled.

    ํŽ˜์ด์ง€ ์Šคํฌ๋กค ์‹œ ์ด๋ฏธ์ง€๋ฅผ Lazy loadingํ•  ๋•Œ

  • Implementing "infinite scrolling" web sites, where more and more content is loaded and rendered as you scroll, so that the user doesn't have to flip through pages.

    Infinite scrolling์„ ํ†ตํ•ด ์Šคํฌ๋กค์„ ํ•˜๋ฉฐ ์ƒˆ๋กœ์šด ์ฝ˜ํ…์ธ ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ

  • Reporting of visibility of advertisements in order to calculate ad revenues.

    ๊ด‘๊ณ ์˜ ์ˆ˜์ต์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ๊ด‘๊ณ ์˜ ๊ฐ€์‹œ์„ฑ์„ ์ฐธ๊ณ ํ•  ๋•Œ

  • Deciding whether or not to perform tasks or animation processes based on whether or not the user will see the result.

    ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ๊ฒƒ์ธ์ง€์— ๋”ฐ๋ผ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋™์ž‘ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•  ๋•Œ

Intersection Observer API - Web APIs | MDN (mozilla.org)

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

Intersection Observer ์ƒ์„ฑ ๋ฐฉ๋ฒ•

const io = new IntersectionObserver(callback[, options]);

IntersectionObserver๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ต์ฐจ๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰ํ•  callback ํ•จ์ˆ˜์™€ ์„ ํƒ์ ์œผ๋กœ options๋ฅผ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Parameters

callback ํƒ€๊ฒŸ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ๊ต์ฐจ๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰ํ•  ํ•จ์ˆ˜

  • entries: IntersectionObserverEntry ๊ฐ์ฒด์˜ ๋ฆฌ์ŠคํŠธ. ๋ฐฐ์—ด ํ˜•์‹์ด๊ธฐ ๋•Œ๋ฌธ์— forEach๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋‹จ์ผ ํƒ€๊ฒŸ์ผ ๊ฒฝ์šฐ ๋ฐฐ์—ด์ธ ์ ์„ ๊ณ ๋ คํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค.
  • observer: ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” IntersectionObserver

options

  • root: ๊ต์ฐจ ์˜์—ญ์˜ ๊ธฐ์ค€์ด ๋  root ์—˜๋ฆฌ๋จผํŠธ. obseve์˜ ๋Œ€์ƒ์œผ๋กœ ๋“ฑ๋กํ•  ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ฐ˜๋“œ์‹œ ๋ฐ˜๋“œ์‹œ root์˜ ํ•˜์œ„ ์—˜๋ฆฌ๋จผํŠธ์—ฌ์•ผ ํ•œ๋‹ค.

    default: null(๋ธŒ๋ผ์šฐ์ €์˜ viewport)

  • rootMargin: root ์—˜๋ฆฌ๋จผํŠธ์˜ ๋งˆ์ง„ ๊ฐ’.

    rootMargin ๊ฐ’์— ๋”ฐ๋ผ ๊ต์ฐจ ์˜์—ญ์ด ํ™•์žฅ ๋˜๋Š” ์ถ•์†Œ๋œ๋‹ค.

    default: '0px 0px 0px 0px'

    https://heropy.blog/images/screenshot/intersection-observer/intersection-observer-root-margin-0.jpg

    https://heropy.blog/images/screenshot/intersection-observer/intersection-observer-root-margin+100.jpg

https://heropy.blog/images/screenshot/intersection-observer/intersection-observer-root-margin-100.jpg

  • threshold: 0.0๋ถ€ํ„ฐ 1.0 ์‚ฌ์ด์˜ ์ˆซ์ž ํ˜น์€ ์ด ์ˆซ์ž๋“ค๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฐฐ์—ด๋กœ ํƒ€์ผ“ ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•œ ๊ต์ฐจ ์˜์—ญ ๋น„์œจ์„ ์˜๋ฏธํ•œ๋‹ค.

    0.0์˜ ๊ฒฝ์šฐ ํƒ€์ผ“ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ๊ต์ฐจ์˜์—ญ์— ์ง„์ž…ํ–ˆ์„ ์‹œ์ ์ด๊ณ  1.0์˜ ๊ฒฝ์šฐ ํƒ€๊ฒŸ ์—˜๋ฆฌ๋จผํŠธ ์ „์ฒด๊ฐ€ ๊ต์ฐจ ์˜์—ญ์— ๋“ค์–ด์™”์„ ์‹œ์ ์ด๋‹ค.

    <div class="lazy-loading-example">
      <img src="์ด๋ฏธ์ง€ URL" alt="image" class="image-default">
      <img data-src="์ด๋ฏธ์ง€ URL" alt="image" class="image">
      <img data-src="์ด๋ฏธ์ง€ URL" alt="image" class="image">
    	<img data-src="์ด๋ฏธ์ง€ URL" alt="image" class="image">
    	<img data-src="์ด๋ฏธ์ง€ URL" alt="image" class="image">
    	<img data-src="์ด๋ฏธ์ง€ URL" alt="image" class="image">
    	<img data-src="์ด๋ฏธ์ง€ URL" alt="image" class="image">
    </div>
    const options = {
    	root: null, // null์ธ ๊ฒฝ์šฐ ๋ธŒ๋ผ์šฐ์ € viewport
    	rootMargin: '30px',
    	threshold: 0 // ํƒ€๊ฒŸ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ๊ต์ฐจ์˜์—ญ์— ์ง„์ž…ํ–ˆ์„ ๋•Œ, observe๊ฐ€ ๋ฐ˜์‘ํ•œ๋‹ค.
    }
    
    const callback = (entries, observer) => {
    	// ์›ํ•˜๋Š” ๋™์ž‘ ์ž‘์„ฑ
    	entries.forEach(entry => {
    		if (entry.isIntersecting) { // ๊ด€์ฐฐ ๋Œ€์ƒ์ด viewport ์•ˆ์— ๋“ค์–ด์˜จ ๊ฒฝ์šฐ
    			entry.target.src = entry.target.dataset.src;
    			observer.unobserve(entry.target); // target ๊ฐ์‹œ ์ทจ์†Œ
    		}
    	}
    }
    
    const io= new IntersectionObserver(callback, options);
    const images = document.querySelectorAll('.image');
    images.forEach((image) => {
      io.observe(image);
    })

    IntersectionObserver์˜ Methods

    IntersectionObserver.observe(targetElement)

    • ํƒ€๊ฒŸ ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•œ IntersectionObserver๋ฅผ ๋“ฑ๋กํ•  ๋•Œ(๊ด€์ฐฐ์„ ์‹œ์ž‘ํ•  ๋•Œ) ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    IntersectionObserver.unobserve(targetElement)

    • ํƒ€๊ฒŸ ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•œ ๊ด€์ฐฐ์„ ๋ฉˆ์ถ”๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Lazy-loading(์ง€์—ฐ ๋กœ๋”ฉ)์„ ํ•  ๋•Œ๋Š” ํ•œ ๋ฒˆ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ ํ›„์—๋Š” ๊ด€์ฐฐ์„ ๋ฉˆ์ถฐ๋„ ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” ์ฒ˜๋ฆฌ๋ฅผ ํ•œ ํ›„ ํ•ด๋‹น ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•ดย unobserve(targetElement)์„ ์‹คํ–‰ํ•˜๋ฉด ์ด ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•œ ๊ด€์ฐฐ๋งŒ ๋ฉˆ์ถœ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    IntersectionObserver.disconnect()

    • ๋‹ค์ˆ˜์˜ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๊ด€์ฐฐํ•˜๊ณ  ์žˆ์„ ๋•Œ, ์ด์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ด€์ฐฐ์„ ๋ฉˆ์ถ”๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

    IntersectionObserver.takerecords()

    • IntersectionObserverEntryย ๊ฐ์ฒด์˜ ๋ฐฐ์—ด์„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

    ๋” ์ถ”๊ฐ€ํ•  ๋‚ด์šฉ

    .....

    ์ฐธ์กฐ

    ๋ฐ”๋‹๋ผ JS๋กœ ๋ฌดํ•œ์Šคํฌ๋กค ๊ตฌํ˜„์„ ์œ„ํ•œ ๋ฒ ์ด์ง ๊ณต๋ถ€ (velog.io)

    Intersection Observer - ์š”์†Œ์˜ ๊ฐ€์‹œ์„ฑ ๊ด€์ฐฐ | HEROPY

    Intersection Observer API - Web APIs | MDN (mozilla.org)

    Intersection Observer API์˜ ์‚ฌ์šฉ๋ฒ•๊ณผ ํ™œ์šฉ๋ฐฉ๋ฒ• ยท Yoon's devlog (hyeyoonjung.com)

๐Ÿ“– ๊ฐœ๋ฐœ๋ฌธ์„œ

๐Ÿšฅ ๊ทœ์น™

๐Ÿค” ์Šคํ”„๋ฆฐํŠธ ํšŒ์˜

๐Ÿ“” ํ•™์Šต

๐Ÿ•™ ๋ฐ์ผ๋ฆฌ ์Šคํฌ๋Ÿผ

๐Ÿ’ญ ํšŒ๊ณ ๋ก

๐Ÿ‘จโ€๐Ÿ‘ฆ ๋ฉ˜ํ† ๋ง

๋ฐ๋ชจ์˜์ƒ

Clone this wiki locally