createElement
[Vanilla Javascript] ๋ฌดํ•œ ์Šคํฌ๋กค(infinite scroll) ๊ตฌํ˜„ํ•˜๊ธฐ
createElement
createElement
createElement
์ „์ฒด
์˜ค๋Š˜
์–ด์ œ
  • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (14)
    • Javascript (7)
    • React (1)
    • Algorithm (5)
    • Web (1)
    • CS (0)
    • Webpack (0)
    • Error (0)
    • ํšŒ๊ณ  (0)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ํ™ˆ
  • ํƒœ๊ทธ
  • ๋ฐฉ๋ช…๋ก

๊ณต์ง€์‚ฌํ•ญ

์ธ๊ธฐ ๊ธ€

ํƒœ๊ทธ

  • ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
  • sessionStorage
  • 13699
  • infinite scroll
  • 11652
  • Intersection Observer
  • ํ”„๋กœํ† ํƒ€์ž…
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
  • ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ด๋‹
  • ์ฝ”๋“œ
  • ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ
  • prototype
  • documentFragment
  • javascript
  • ๋ฐฑ์ค€
  • ๋ฌธ์ œํ•ด์„ค
  • ์ธ๊ฐ€ ์ฝ”๋“œ
  • React
  • ๋ฐ๋ธŒ์ฝ”์Šค
  • ์ฝ”ํ…Œ
  • 18428
  • prototype chaining
  • ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ตฌํ˜„
  • useRef
  • ์†Œ์…œ ๋กœ๊ทธ์ธ
  • prototype chain
  • js
  • ๊ฐ์ฒด
  • ์ •๋‹ต
  • netlify

์ตœ๊ทผ ๋Œ“๊ธ€

์ตœ๊ทผ ๊ธ€

hELLO ยท Designed By ์ •์ƒ์šฐ.
Javascript

[Vanilla Javascript] ๋ฌดํ•œ ์Šคํฌ๋กค(infinite scroll) ๊ตฌํ˜„ํ•˜๊ธฐ

2022. 11. 25. 02:00
๋ชฉ์ฐจ
  1. ๐Ÿค” ๋ฌดํ•œ ์Šคํฌ๋กค์ด๋ž€?
  2.  
  3. ๐Ÿช„ ๊ตฌํ˜„ ๋ฐฉ์‹
  4.  
  5. 1. scroll ์ด๋ฒคํŠธ๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•
  6. ๐Ÿ“ฃ isLoading์˜ ์ƒํƒœ ์กด์žฌ ์ด์œ 
  7. ๐Ÿ“ฃ totalCount์˜ ์กด์žฌ ์ด์œ 
  8. 2. Intersection Observer๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•
  9.  
  10. Intersection Observer ์„ค์ •

๐Ÿค” ๋ฌดํ•œ ์Šคํฌ๋กค์ด๋ž€?

์ปจํ…์ธ ๋ฅผ ํŽ˜์ด์ง•ํ•˜๋Š” ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ ์Šคํฌ๋กค์„ ์ด์šฉํ•ด
๋งจ ์•„๋ž˜๊นŒ์ง€ ๋„๋‹ฌํ•  ๋•Œ ์ƒˆ๋กœ์šด ์ปจํ…์ธ ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค.

 

๐Ÿช„ ๊ตฌํ˜„ ๋ฐฉ์‹

์Šคํฌ๋กค์„ ๋๊นŒ์ง€ ๋‚ด๋ ธ์„ ๋•Œ fetch๋œ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ์—˜๋ฆฌ๋จผํŠธ์— ๊ณ„์† ์ถ”๊ฐ€(appendChild)ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.
๊ตฌํ˜„ ๋ฐฉ์‹์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€์ด๋‹ค.

 

1. scroll ์ด๋ฒคํŠธ๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•

- ์ „ํ†ต์ ์ธ ๋ฐฉ์‹

- window์˜ scroll ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚  ๋•Œ๋งˆ๋‹ค ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์˜ ๋†’์ด, ์Šคํฌ๋กค๋ฐ”์˜ ์œ„์น˜๋ฅผ ์ด์šฉํ•ด body(์ปจํ…์ธ )์˜ ๋๊นŒ์ง€ ๋‹ค๋‹ค๋ž์œผ๋ฉด ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค.

 

- window.innerHeight : ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ณด์—ฌ์ง€๋Š” ํ™”๋ฉด ์ค‘ ํƒญ, url ์ฃผ์†Œ์ฐฝ, ๋ถ๋งˆํฌ ํƒญ์„ ์ œ์™ธํ•œ ๋ธŒ๋ผ์šฐ์ €์˜ ๋†’์ด

- window.scrollY : ํ˜„์žฌ ์Šคํฌ๋กค๋ฐ” ์œ„์น˜

- document.body.offsetHeight : body์˜ height

- window.innerHeight + window.scrollY : (ํƒญ, url ์ฃผ์†Œ์ฐฝ, ๋ถ๋งˆํฌ ํƒญ์„ ์ œ์™ธํ•œ)๋ธŒ๋ผ์šฐ์ €์˜ ๋†’์ด + ์‚ฌ์šฉ์ž์˜ ์Šคํฌ๋กค Y ๊ฐ’

- window.innerHeight + window.scrollY ๊ฐ’์ด ํ˜„์žฌ body์˜ ๋†’์ด ๊ฐ’๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํฐ ๊ฒฝ์šฐ ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

window.addEventListener("scroll", () => {
  // 100์„ ๋”ํ•˜๋ฉด ์Šคํฌ๋กค์„ ๋๊นŒ์ง€ ๋‚ด๋ฆฌ๊ธฐ 100px ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
  const isScrollEnded =
    window.innerHeight + window.scrollY + 100 >= document.body.offsetHeight;

  // totalCount : api์˜ ๋ฐ์ดํ„ฐ์˜ ์ „์ฒด ๊ธธ์ด
  // photos.length: ํ˜„์žฌ ๋žœ๋”๋ง๋œ ๋ฐ์ดํ„ฐ์˜ ๊ธธ์ด
  const { photos, totalCount, isLoading } = this.state;
  if (isScrollEnded && !isLoading && photos.length < totalCount) {
    onScrollEnded();
  }
});

 

 

๐Ÿ“ฃ isLoading์˜ ์ƒํƒœ ์กด์žฌ ์ด์œ 

๋ฐ์ดํ„ฐ๋ฅผ ์ด๋ฏธ ์š”์ฒญํ–ˆ์Œ์—๋„ ๊ณ„์† ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

์ด ๊ฒฝ์šฐ isLoading ์ƒํƒœ๋ฅผ ๋‘์–ด ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต๋ฐ›๊ธฐ ์ „๊นŒ์ง€๋Š” ์žฌ์š”์ฒญ์„ ํ•˜์ง€ ์•Š๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๐Ÿ“ฃ totalCount์˜ ์กด์žฌ ์ด์œ 

์ด๋ฏธ api์˜ ๋งˆ์ง€๋ง‰ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ๋ชจ๋‘ ๊ฐ€์ ธ์™”์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  1) ์Šคํฌ๋กค์„ ๋งจ ์•„๋ž˜ ๋‚ด๋ฆฐ ์ƒํƒœ, 2) isLoading์ด false์ธ ๊ฒฝ์šฐ, ์ด ๋‘ ๊ฐ€์ง€๊ฐ€ ์ฐธ์ผ ๋•Œ ๊ณ„์† ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•œ๋‹ค.

์ด ๊ฒฝ์šฐ api์˜ ๋ฐ์ดํ„ฐ ์ „์ฒด ๊ฐœ์ˆ˜(totalCount)์™€ ํ˜„์žฌ๊นŒ์ง€ ๋žœ๋”๋ง๋œ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐœ์ˆ˜(photos.length)๋ฅผ ๋น„๊ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.



 

 

2. Intersection Observer๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•

- ์ตœ๊ทผ์— ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹

- observe, unobserve๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•œ๋‹ค.

- threshold ๊ฐ’์œผ๋กœ observe ๋Œ€์ƒ์ด ์–ผ๋งˆ๋‚˜ ๋…ธ์ถœ๋˜์—ˆ๋Š”์ง€์— ๋”ฐ๋ผ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Intersection Observer ์„ค์ •

์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜, ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ observer์˜ ์„ค์ • ์‚ฌํ•ญ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

- root: ๊ด€์ฐฐ ๋Œ€์ƒ์ด ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์— ๋“ค์–ด์™”์Œ์„ ๊ฐ์ง€ํ•˜๋Š” ์˜์—ญ์ด๋‹ค.

- rootMargin: ๊ด€์ฐฐ ๋Œ€์ƒ์„ ๊ฐ์ง€ํ•˜๋Š” ์˜์—ญ์„ margin์„ ์ด์šฉํ•ด ๋ฒ”์œ„๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ '0px 0px 0px 0px'์ด๋ฉฐ, ๋ฐ˜๋“œ์‹œ ๋ฌธ์ž์—ด๋กœ ๋‹จ์œ„์™€ ํ•จ๊ป˜ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

- threshold: ๊ด€์ฐฐ ๋Œ€์ƒ์ด ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด ๋‚ด์— ์–ผ๋งˆ๋‚˜ ๋ณด์˜€์„ ๋•Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ฐ’์„ ๋งํ•œ๋‹ค.

// ์ฒซ๋ฒˆ์งธ ์ธ์ž๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜, ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š” ์„ค์ •
const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach((entry) => {
      const { photos, totalCount, isLoading } = this.state;
      // ๋กœ๋”ฉ ์ค‘์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•จ
      if (entry.isIntersecting && !isLoading) {
        if (photos.length < totalCount) {
          onScrollEnded();
        }
      }
    });
  },
  {
    // 1์ธ ๊ฒฝ์šฐ ์Šคํฌ๋กค์„ ์ด์šฉํ•ด ๊ด€์ฐฐ ๋Œ€์ƒ์ด ๋ชจ๋‘ ๋ณด์ธ ๊ฒฝ์šฐ์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
    threshold: 1,
  }
);

// ์ค‘๋žต

this.render = () => {
  // ์ค‘๋žต

  let $lastLi = null;

  // ๋‹ค์Œ ๊ด€์ฐฐ ๋Œ€์ƒ์„ ๋งˆ์ง€๋ง‰์˜ ๋ฆฌ์ŠคํŠธ ์š”์†Œ๋กœ ํ•œ๋‹ค.
  const $nextLi = $photos.querySelector("li:last-child");

  if ($nextLi !== null) {
    if ($lastLi !== null) {
      // ๋งˆ์ง€๋ง‰ ์š”์†Œ๊ฐ€ null์ธ ๊ฒฝ์šฐ์—๋Š” ๊ด€์ฐฐํ•˜์ง€ ์•Š๋Š”๋‹ค.
      observer.unobserve($lastLi);
    }

    $lastLi = $nextLi;
    observer.observe($lastLi); // ๊ด€์ฐฐ ๋Œ€์ƒ ๋“ฑ๋ก
  }
};

'Javascript' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

SessionStorage๋ฅผ ์ด์šฉํ•ด ์บ์‹œ ๊ตฌํ˜„ํ•˜๊ธฐ  (0) 2022.11.23
[JS] DocumentFragment, Template tag  (0) 2022.10.26
[JS] ํด๋กœ์ €(Closures) ์ดํ•ดํ•˜๊ธฐ  (0) 2022.10.18
spread์™€ rest ๋น„๊ตํ•˜๊ธฐ  (0) 2022.07.28
ํ”„๋กœํ† ํƒ€์ž…(Prototype) ์ดํ•ดํ•˜๊ธฐ 2  (0) 2022.07.17
  • ๐Ÿค” ๋ฌดํ•œ ์Šคํฌ๋กค์ด๋ž€?
  •  
  • ๐Ÿช„ ๊ตฌํ˜„ ๋ฐฉ์‹
  •  
  • 1. scroll ์ด๋ฒคํŠธ๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•
  • ๐Ÿ“ฃ isLoading์˜ ์ƒํƒœ ์กด์žฌ ์ด์œ 
  • ๐Ÿ“ฃ totalCount์˜ ์กด์žฌ ์ด์œ 
  • 2. Intersection Observer๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•
  •  
  • Intersection Observer ์„ค์ •
'Javascript' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • SessionStorage๋ฅผ ์ด์šฉํ•ด ์บ์‹œ ๊ตฌํ˜„ํ•˜๊ธฐ
  • [JS] DocumentFragment, Template tag
  • [JS] ํด๋กœ์ €(Closures) ์ดํ•ดํ•˜๊ธฐ
  • spread์™€ rest ๋น„๊ตํ•˜๊ธฐ
createElement
createElement
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”

๋‹จ์ถ•ํ‚ค

๋‚ด ๋ธ”๋กœ๊ทธ

๋‚ด ๋ธ”๋กœ๊ทธ - ๊ด€๋ฆฌ์ž ํ™ˆ ์ „ํ™˜
Q
Q
์ƒˆ ๊ธ€ ์“ฐ๊ธฐ
W
W

๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€

๊ธ€ ์ˆ˜์ • (๊ถŒํ•œ ์žˆ๋Š” ๊ฒฝ์šฐ)
E
E
๋Œ“๊ธ€ ์˜์—ญ์œผ๋กœ ์ด๋™
C
C

๋ชจ๋“  ์˜์—ญ

์ด ํŽ˜์ด์ง€์˜ URL ๋ณต์‚ฌ
S
S
๋งจ ์œ„๋กœ ์ด๋™
T
T
ํ‹ฐ์Šคํ† ๋ฆฌ ํ™ˆ ์ด๋™
H
H
๋‹จ์ถ•ํ‚ค ์•ˆ๋‚ด
Shift + /
โ‡ง + /

* ๋‹จ์ถ•ํ‚ค๋Š” ํ•œ๊ธ€/์˜๋ฌธ ๋Œ€์†Œ๋ฌธ์ž๋กœ ์ด์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ํ‹ฐ์Šคํ† ๋ฆฌ ๊ธฐ๋ณธ ๋„๋ฉ”์ธ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.