[Observer API ํŒŒํ—ค์น˜๊ธฐ] 2. IntersectionObserver

โฐ 2024-06-14 (๊ธˆ) 01:37:29

screener
์‹œ๋ฆฌ์ฆˆ ๋ชจ์•„๋ณด๊ธฐ
Observer API ํŒŒํ—ค์น˜๊ธฐ

2 / 6

Table of Contents


IntersectionObserver

IntersectionObserver๋Š” DOM๊ณผ ๋ทฐํฌํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐ ํŠนํ™”๋œ ์˜ต์ €๋ฒ„๋‹ค. DOM์ด ๋ทฐํฌํŠธ์™€ ๊ต์ฐจํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ DOM์ด ์‹ค์ œ ์‚ฌ์šฉ์ž ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๋Š”์ง€, ์•„๋‹ˆ๋ฉด ์ˆจ๊ฒจ์กŒ๋Š”์ง€ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

TYPESCRIPT

1
const io = new IntersectionObserver(callback, options);

์œ„ ์ฝ”๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, callback, options ๋‘ ๊ฐ€์ง€ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›๋Š”๋‹ค.

callback

IntersectionObserver์˜ ์ฝœ๋ฐฑ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์š”์†Œ๊ฐ€ ๋ทฐํฌํŠธ์— ๋ณด์ด๊ฑฐ๋‚˜, ๋ณด์ด์ง€ ์•Š์„ ๋•Œ ๋™์ž‘ํ•˜๋Š” ์ด๋ฒคํŠธ ๋ฉ”์„œ๋“œ๋‹ค.

IntersectionObserverCallback ํƒ€์ž…์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ฝ”๋“œ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

TYPESCRIPT

1
const io = new IntersectionObserver((entries, observer) => {});

IntersectionObserverEntry

entries๋Š” IntersectionObserverEntry[] ํƒ€์ž…์„ ๊ฐ–๋Š”๋‹ค. IntersectionObserver์— ๋“ฑ๋ก๋œ ์š”์†Œ์˜ ์ด๋ฒคํŠธ ์ •๋ณด๋ฅผ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋ฐฐ์—ด ํƒ€์ž…์ธ ์ด์œ ๋Š” IntersectionObserver์— ์—ฌ๋Ÿฌ DOM์„ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ต์ฐจ ์—ฌ๋ถ€ (isIntersecting)

isIntersecting

isIntersecting ์†์„ฑ์€ ๊ต์ฐจ ์—ฌ๋ถ€๋ฅผ boolean ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. ์ง€์ •๋œ ์˜ต์…˜์— ๋”ฐ๋ผ DOM์— ๋ณด์—ฌ์งˆ ๊ฒฝ์šฐ true, ์•„๋‹ ๊ฒฝ์šฐ false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋Œ€์ƒ DOM (target)

target

์ด๋ฒคํŠธ ์†์„ฑ์—์„œ ํ”ํžˆ ๋ณด๋Š” target ์†์„ฑ๊ณผ ๋™์ผํ•˜๊ฒŒ, ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ž์‹ ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๊ต์ฐจ ๋น„์œจ (intersectionRatio)

intersectionRatio

DOM์ด ๊ต์ฐจ๋œ ๋น„์œจ์„ number๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. ์ถ”ํ›„ ์„ค๋ช…ํ•  options์—์„œ ์ง€์ •ํ•˜๋Š” threshold์™€ ๋ฐ€์ ‘ํ•œ ์—ฐ๊ด€์ด ์žˆ๋‹ค.

threshold์— ๋ฐฐ์—ด์„ ์ง€์ •ํ•˜์—ฌ ๋‹ค์ˆ˜์˜ ๋น„์œจ์„ ์ง€์ •ํ–ˆ์„ ๊ฒฝ์šฐ, ์ด ๊ฐ’์„ ํ†ตํ•ด ๋น„์œจ์„ ํŠน์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฃจํŠธ DOM (rootBounds)

rootBounds

๋ทฐํฌํŠธ์˜ ๊ธฐ์ค€์ธ DOM์„ Element ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. options์—์„œ root ์†์„ฑ์„ ์ง€์ •ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ๊ฐ„ (time)

์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์‹œ๊ฐ„์„ number ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

๋Œ€์ƒ DOM์˜ ๋ฐ”์šด๋”๋ฆฌ (boundingClientRect)

time

๋Œ€์ƒ DOM์˜ ๋ฐ”์šด๋”๋ฆฌ ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. x, y, width, height ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

๋Œ€์ƒ DOM์˜ ๊ต์ฐจ ๋ฐ”์šด๋”๋ฆฌ (intersectionRect)

intersectionRect

๋Œ€์ƒ DOM๊ณผ ๋ทฐํฌํŠธ์˜ ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฐ”์šด๋”๋ฆฌ ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. boundingClientRect์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ x, y, width, height ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ทฐํฌํŠธ์™€ ๊ต์ฐจ๋œ ์˜์—ญ์— ํ•œ์ •๋œ๋‹ค๋Š” ์ฐจ์ด์ ์ด ์žˆ๋‹ค.

observer

IntersectionObserver ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ๋„ IntersectionObserver๋ฅผ ์—ฐ์‡„์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.

options

options ์†์„ฑ์„ ์ „๋‹ฌํ•˜์—ฌ IntersectionObserver์˜ ์„ธ๋ถ€ ๋™์ž‘์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฃจํŠธ DOM (root)

root

๋ทฐํฌํŠธ์˜ ๊ธฐ์ค€์ด ๋˜๋Š” ๋ฃจํŠธ DOM์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์ง€์ •ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ํ˜„์žฌ ๋ณด๊ณ ์žˆ๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ๋ทฐํฌํŠธ๊ฐ€ ์ง€์ •๋œ๋‹ค.

๋ฃจํŠธ DOM์˜ margin (rootMargin)

rootMargin

๋ฃจํŠธ DOM์„ ๊ธฐ์ค€์œผ๋กœ ๊ต์ฐจ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ, rootMargin์„ ํ†ตํ•ด ๊ฐ์ง€ ์˜์—ญ์„ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค๋ฉด, root๊ฐ€ ๋ทฐํฌํŠธ์ผ ๋•Œ, rootMargin์„ 100px๋กœ ์ง€์ •ํ•˜๋ฉด ๋ทฐํฌํŠธ๋ณด๋‹ค 100px ๋จผ ๊ณณ์—์„œ๋ถ€ํ„ฐ ๊ต์ฐจ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด, ๋ฏธ๋ฆฌ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์‹์˜ ํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

CSS์˜ margin ์†์„ฑ๊ณผ ๋™์ผํ•˜๊ฒŒ y x ํ˜น์€ top right bottom left ๋ฐฉ์‹์œผ๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋Œ€์ƒ DOM์˜ ๊ต์ฐจ ๋น„์œจ (threshold)

threshold

๊ต์ฐจ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์œ„ํ•œ ๊ต์ฐจ ๋น„์œจ์„ number ํ˜น์€ number[]๋กœ ์ง€์ •ํ•˜๋ฉฐ, ์š”์†Œ๋Š” 0 ~ 1 ์‚ฌ์ด์˜ ์‹ค์ˆ˜๋ฅผ ๊ฐ€์ง„๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด, 0.2๋Š” ๊ต์ฐจ๋น„์œจ์ด 20%์ผ ๊ฒฝ์šฐ ๊ต์ฐจ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

๋ฐฐ์—ด๋กœ ์ง€์ •ํ•  ๊ฒฝ์šฐ, ์ง€์ •ํ•œ ๋น„์œจ๋งˆ๋‹ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ฆ‰ [ 0.2, 0.5, 0.8 ]์ผ ๊ฒฝ์šฐ, 20%, 50%, 80% ๊ต์ฐจ ์‹œ ๊ฐ๊ฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์‹์ด๋‹ค.

React์—์„œ ์ปค์Šคํ…€ ํ›…์œผ๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ

IntersectionObserver๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋ฉด, ์ ์ ˆํ•œ ์ƒ๋ช…์ฃผ๊ธฐ์— ๋งž์ถฐ DOM์„ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ด ์ƒ๊ฐ๋ณด๋‹ค ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ปค์Šคํ…€ ํ›…์„ ํ†ตํ•ด IntersectionObserver๋ฅผ ๋”์šฑ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•ด๋ณด์ž.

TYPESCRIPT

1
2
3
4
export function useIntersectionObserver(): void
{
  //
}

์œ„์™€ ๊ฐ™์ด useIntersectionObserver๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•ด๋ณด์ž.

useIntersectionObserver๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  ์•„๋ž˜์™€ ๊ฐ™์€ ์„ธ ๊ฐ€์ง€ ์š”์†Œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

  1. ๋Œ€์ƒ DOM
  2. ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ
  3. ์˜ต์…˜

์œ„ ์„ธ ์š”์†Œ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ •์˜ํ•˜์ž. 1๋ฒˆ์˜ ๊ฒฝ์šฐ, ์ผ๋ฐ˜์ ์œผ๋กœ HTMLElement๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ, ํ•ด๋‹น ํ›…์—์„œ๋Š” HTMLElement ํƒ€์ž… ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, string์„ ๋ฐ›์•„ #id, .class์™€ ๊ฐ™์€ ์„ ํƒ์ž๋กœ ํƒœ๊ทธ๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค ๊ฒƒ์ด๋‹ค.

TYPESCRIPT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { useEffect } from "react";

export type UseIntersectionObserverCallback = (
  entry: IntersectionObserverEntry
) => void;

/**
 * IntersectionObserver ์ ์šฉ ํ›… ๋ฉ”์„œ๋“œ
 *
 * @param {Element | string | null} ref: Element
 * @param {UseIntersectionObserverCallback} callback: ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ
 * @param {IntersectionObserverInit} options: ์˜ต์…˜
 */
export function useIntersectionObserver(
  ref: Element | string | null,
  callback: UseIntersectionObserverCallback,
  options?: IntersectionObserverInit
): void
{
  //
}

ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์ •์˜๋Š” ์œ„์™€ ๊ฐ™๋‹ค. ์ดํ›„ IntersectionObserver์„ ์„ ์–ธํ•˜๊ณ  ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ์™€ ์˜ต์…˜์„ ํ• ๋‹นํ•œ๋‹ค.

TYPESCRIPT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { useEffect } from "react";

export type UseIntersectionObserverCallback = (
  entry: IntersectionObserverEntry
) => void;

/**
 * IntersectionObserver ์ ์šฉ ํ›… ๋ฉ”์„œ๋“œ
 *
 * @param {Element | string | null} ref: Element
 * @param {UseIntersectionObserverCallback} callback: ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ
 * @param {IntersectionObserverInit} options: ์˜ต์…˜
 */
export function useIntersectionObserver(
  ref: Element | string | null,
  callback: UseIntersectionObserverCallback,
  options?: IntersectionObserverInit
): void
{
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(callback);
    }, options);
  }, [ref, callback, options]);
}

์œ„์™€ ๊ฐ™์ด IntersectionObserver์„ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ io ๋ณ€์ˆ˜๋กœ ํ• ๋‹นํ•œ๋‹ค.

์ดํ›„ ref๋กœ ์ง€์ •ํ•œ DOM์„ ํ• ๋‹นํ•œ๋‹ค.

ref๋Š” ์„ธ ๊ฐ€์ง€ ์ƒํƒœ์— ๋”ฐ๋ผ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ถ„๊ธฐ๋ฅผ ๊ฑฐ์นœ๋‹ค.

  • null์ผ ๊ฒฝ์šฐ -> ํŒจ์Šคํ•œ๋‹ค.
  • string์ผ ๊ฒฝ์šฐ -> document.querySelector ๋ฉ”์„œ๋“œ๋กœ ํƒœ๊ทธ๋ฅผ ์„ ํƒํ•œ ๋’ค, ํ•ด๋‹น ํƒœ๊ทธ๋ฅผ ๋“ฑ๋กํ•œ๋‹ค.
  • HTMLElement์ผ ๊ฒฝ์šฐ -> ์ด๋ฏธ Element์ด๋ฏ€๋กœ, ์ฆ‰์‹œ ๋“ฑ๋กํ•œ๋‹ค.

typeof ref === "string" ๊ตฌ๋ฌธ์„ ํ†ตํ•ด ref๊ฐ€ ๋ฌธ์ž์—ด์ธ์ง€๋ฅผ ํŒ๋ณ„ํ•˜์—ฌ ๊ตฌํ˜„ํ–ˆ๋‹ค.

io.observe() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํƒœ๊ทธ๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.

TYPESCRIPT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { useEffect } from "react";

export type UseIntersectionObserverCallback = (
  entry: IntersectionObserverEntry
) => void;

/**
 * IntersectionObserver ์ ์šฉ ํ›… ๋ฉ”์„œ๋“œ
 *
 * @param {Element | string | null} ref: Element
 * @param {UseIntersectionObserverCallback} callback: ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ
 * @param {IntersectionObserverInit} options: ์˜ต์…˜
 */
export function useIntersectionObserver(
  ref: Element | string | null,
  callback: UseIntersectionObserverCallback,
  options?: IntersectionObserverInit
): void
{
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(callback);
    }, options);

    // DOM์ด ์œ ํšจํ•  ๊ฒฝ์šฐ
    if (ref) {
      // ref๊ฐ€ ๋ฌธ์ž์—ด์ผ ๊ฒฝ์šฐ
      if (typeof ref === "string") {
        const tag = document.querySelector(ref);

        // ํƒœ๊ทธ๊ฐ€ ์œ ํšจํ•  ๊ฒฝ์šฐ
        if (tag) {
          io.observe(tag);
        }
      }

      // DOM์ผ ๊ฒฝ์šฐ
      else {
        io.observe(ref);
      }
    }
  }, [ref, callback, options]);
}

๋งˆ์ง€๋ง‰์œผ๋กœ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค IntersectionObserver์˜ ๋“ฑ๋ก์ด ์ค‘์ฒฉ๋˜์ง€ ์•Š๋„๋ก, ์ดˆ๊ธฐํ™” ์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.

io.disconnect() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด IntersectionObserver๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

์ „์ฒด ์ฝ”๋“œ

TYPESCRIPT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { useEffect } from "react";

export type UseIntersectionObserverCallback = (
  entry: IntersectionObserverEntry
) => void;

/**
 * IntersectionObserver ์ ์šฉ ํ›… ๋ฉ”์„œ๋“œ
 *
 * @param {Element | string | null} ref: Element
 * @param {UseIntersectionObserverCallback} callback: ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ
 * @param {IntersectionObserverInit} options: ์˜ต์…˜
 */
export function useIntersectionObserver(
  ref: Element | string | null,
  callback: UseIntersectionObserverCallback,
  options?: IntersectionObserverInit
): void
{
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(callback);
    }, options);

    // DOM์ด ์œ ํšจํ•  ๊ฒฝ์šฐ
    if (ref) {
      // ref๊ฐ€ ๋ฌธ์ž์—ด์ผ ๊ฒฝ์šฐ
      if (typeof ref === "string") {
        const tag = document.querySelector(ref);

        // ํƒœ๊ทธ๊ฐ€ ์œ ํšจํ•  ๊ฒฝ์šฐ
        if (tag) {
          io.observe(tag);
        }
      }

      // DOM์ผ ๊ฒฝ์šฐ
      else {
        io.observe(ref);
      }
    }

    return () => {
      io.disconnect();
    };
  }, [ref, callback, options]);
}

์ „์ฒด ์ฝ”๋“œ๋Š” ์œ„์™€ ๊ฐ™๋‹ค.

CodeSandbox๋ฅผ ํ†ตํ•œ ์˜ˆ์‹œ

CodeSandbox๋กœ ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค. CodeSandbox์˜ ๋ Œ๋”๋ง ๋ฐฉ์‹ ๋•Œ๋ฌธ์ธ์ง€, rootMargin์€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๋“ฏํ•˜๋‹ค.

๋งˆ์น˜๋ฉฐ

์ด์™€ ๊ฐ™์ด IntersectionObserver๋ฅผ ํ™œ์šฉํ•˜๋ฉด DOM์˜ ๋ทฐํฌํŠธ ๊ด€๋ จ ์š”์†Œ๋ฅผ ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.

์ด API๋Š” ์ธํ”ผ๋‹ˆํ‹ฐ ์Šคํฌ๋กค, ์• ๋‹ˆ๋งค์ด์…˜ ๋™์ž‘ ํŠธ๋ฆฌ๊ฑฐ ๋“ฑ, ๊ธฐ์กด์˜ Event Driven์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์„ ์‰ฝ๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ ์žฅ์—์„  ResizeObserver์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณด์ž.


๐Ÿท๏ธ ํƒœ๊ทธ
# JavaScript
# TypeScript
# React
# Observer API
# IntersectionObserver

์ฝ์–ด์ฃผ์…”์„œ ๊ณ ๋งˆ์›Œ์š”!

๋„์›€์ด ๋˜์…จ๋‹ค๋ฉด, ๊ณต๊ฐ์ด๋‚˜ ๋Œ“๊ธ€์„ ๋‹ฌ์•„์ฃผ์‹œ๋Š” ๊ฑด ์–ด๋–ค๊ฐ€์š”?

๋ธ”๋กœ๊ทธ ์šด์˜์— ํฐ ํž˜์ด ๋ฉ๋‹ˆ๋‹ค.

https://hits.seeyoufarm.com/api/count/incr/badge.svg?count_bg=%23484848&icon=react.svg&icon_color=dodgerblue&title=view&title_bg=%23242424&url=https%3A%2F%2Fblog.itcode.dev%2Fposts%2F2024%2F06%2F14%2Fobserver-api-2