Skip to content

Latest commit

ย 

History

History
309 lines (221 loc) ยท 6.95 KB

File metadata and controls

309 lines (221 loc) ยท 6.95 KB

Get better at JavaScript with just JavaScript

Intersection Observer

ํ•œ ์š”์†Œ๊ฐ€ ํ™”๋ฉด ์•ˆ์œผ๋กœ ๋“ค์–ด์™”๋Š”์ง€ ํ™•์ธํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

  • ์Šคํฌ๋กค ์‹œ ์š”์†Œ์— ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋„ฃ๊ธฐ
  • ์Šคํฌ๋กค ์‹œ ๋น„๋””์˜ค ์žฌ์ƒ
  • ์ด๋ฏธ์ง€ ์ง€์—ฐ๋กœ๋”ฉ
  • ๊ด‘๊ณ  ๋…ธ์ถœ์ˆ˜ ์„ธ๊ธฐ
  • ์Šคํ‹ฐํ‚ค ํ—ค๋”

๋“ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

1. ์˜ต์…˜ ์„ค์ •

const options = {
  root: document.querySelector(".scrollingDiv"),
  rootMargin: "100px",
  // ํ™”๋ฉด์— ์—†์„ ๋•Œ, ๋ฐ˜๋งŒ, ์™„์ „ํžˆ ๋“ค์–ด์™”์„ ๋•Œ ์•Œ๋ ค์คŒ
  threshold: [0, 0.5, 1.0]
};

2. ๋นˆ Observer ์ƒ์„ฑ

const observer = new IntersectionObserver(callback, options);

3. ์ฝœ๋ฐฑ ์ „๋‹ฌํ•˜๊ธฐ

const callback = (entries, observer) => {
  entries.forEach(entry => {
    console.log(entry);
    // threshold๊ฐ€ 1์ผ ๋•Œ(์š”์†Œ๊ฐ€ ์™„์ „ํžˆ ๋“ค์–ด์™”์„ ๋•Œ)๋งŒ ๋ณด์ด๊ฒŒ ํ•˜๊ธฐ
    if (entry.isIntersecting && entry.intersectionRatio >= 1) {
      entry.target.classList.add("visible");
    } else {
      entry.target.classList.remove("visible");
    }
    observer.unobserve(entry.target);
  });
};

4. ๊ด€์ฐฐ ์‹œ์ž‘

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => observer.observe(box));

Resize Observer

์š”์†Œ์˜ ํฌ๊ธฐ ๋ณ€๊ฒฝ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ๋ณธ ์˜ˆ์ œ

const callback = (entries, observer) => {
  entries[0].target.innerHTML = `
    <pre>
      ${JSON.stringify(entries[0].contentRect, null, " ")}
    </pre>
  `;
};

const observer = new ResizeObserver(callback);

const element = document.querySelector(".resize");
observer.observe(element);

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

const callback = (entries, observer) => {
  const { width } = entries[0].contentRect;
  if (width > 400) {
    size = "large";
  } else if (width > 300) {
    size = "medium";
  } else {
    size = "small";
  }

  entries[0].target.classList.remove("small", "medium", "large");
  entires[0].target.classList.add(size);
};

const observer = new ResizeObserver(callback);
const element = document.querySelector(".videos__list");
observer.observe(element);

DOM Element Methods

1. .closest()

์ž…๋ ฅ๋ฐ›์€ ์„ ํƒ์ž์— ์ผ์น˜ํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์กฐ์ƒ์š”์†Œ๋ฅผ ์ฐพ๋Š”๋‹ค.

<div class="cards">
  <div class="card">
    <p>I'm a Card</p>
    <button>Delete</button>
  </div>
  <div class="card">
    <p>I'm a Card</p>
    <button>Delete</button>
  </div>
</div>

2๊ฐœ์˜ ์นด๋“œ๊ฐ€ ์žˆ๋Š” div์š”์†Œ๊ฐ€ ์žˆ๊ณ  ๊ฐ ์นด๋“œ๋Š” ์‚ญ์ œ ๋ฒ„ํŠผ์ด ์žˆ๋‹ค.

document.querySelectorAll(".card button").forEach(button => {
  button.addEventListener("click", e => {
    e.currentTarget.closest(".card").remove();
  });
});

closest ๋ฉ”์„œ๋“œ๋กœ ๋ฒ„ํŠผ์˜ ์กฐ์ƒ์ธ .card div๋ฅผ ์ฐพ์•„์„œ ์‚ญ์ œํ•œ๋‹ค.

const p = document.querySelector("p");

document.addEventListener("click", e => {
  const isOutsize = !e.target.closest(".modal-inner");
  p.textContent = `You Clicked ${isOutsize ? "Outsize" : "Insize"}!`;
});

์š”์†Œ ๋ฐ–์„ ํด๋ฆญํ–ˆ๋Š”์ง€ ์•ˆ์„ ํด๋ฆญํ–ˆ๋Š”์ง€ ํ™•์ธํ•  ๋•Œ๋„ ์œ ์šฉํ•˜๋‹ค.

2. .matches()

ํ•œ ์š”์†Œ๊ฐ€ ์„ ํƒ์ž์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

button.addEventListener("click", e => {
  if (e.currentTarget.matches(".available[data-price]")) {
    // .. ์ฒ˜๋ฆฌ
  }
});

๋ฒ„ํŠผ์ด data-price ๋ผ๋Š” ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

// list๋Š” JS๋กœ ์•„์ดํ…œ์„ ์ถ”๊ฐ€/์‚ญ์ œํ•˜๋Š” ๋นˆ ์š”์†Œ์ž„
list.addEventListener("click", e => {
  if (e.target.matches("button")) {
    deleteItem(parseFloat(e.target.value));
  }
});

Event Delegation์—๋„ ์‚ฌ์šฉํ•œ๋‹ค.

๋ชจ๋“  ๋ฆฌ์ŠคํŠธ ๋‚ด์˜ ์•„์ดํ…œ์— ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋ถ™์ผ ํ•„์š”๊ฐ€ ์—†๋‹ค.

3. .contains()

const modal = document.querySelector(".modal");
modal.contains(button); // true

modal.querySelector("button"); // <button></button>
// contains ๋ฉ”์„œ๋“œ์™€ ๊ฐ™์Œ
!!modal.querySelector("button"); // true

Bling.js

๋ฐ”๋‹๋ผ JS์•ฑ์„ ๋งŒ๋“ค ๋•Œ ์žˆ์œผ๋ฉด ์œ ์šฉํ•œ 11์ค„์งœ๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

window.$ = document.querySelector.bind(document);
window.$$ = document.querySelectorAll.bind(document);

Node.prototype.on = window.on = function(name, fn) {
  this.addEventListener(name, fn);
};

NodeList.prototype.__proto__ = Array.prototype;

NodeList.prototype.on = function(name, fn) {
  this.forEach(function(elem, i) {
    elem.on(name, fn);
  });
};

์ž…๋ ฅํ•˜๊ธฐ ํž˜๋“  document.querySelector๋ฅผ $ ํ•œ ๋ฌธ์ž๋กœ ์ค„์ž„

NodeList์—์„œ Array์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ


๋ฐ์ดํ„ฐ ๋‹ค๋ฃจ๊ธฐ

1. Array.from()

Array.from({ length: 3 });
// => [undefined, undefined, undefined]

Array.from({ length: 3 }, () => `๐Ÿ’ฐ`);
// => ["๐Ÿ’ฐ", "๐Ÿ’ฐ", "๐Ÿ’ฐ"]

iterable์„ array๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

Array.from({ length: 3 }, (_, i) => `day-${i + 1}`);
// => [ "day-1", "day-2", "day-3" ]

ํ•˜๋“œ์ฝ”๋”ฉ์„ ํ”ผํ•˜๊ณ  ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ด๊ธด ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค.

Array.from({ length: 12 }, (x, index) =>
  new Date(0, index + 1, 0).toLocaleDateString("en-US", { month: "short" })
);
// => [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

Array.from({ length: 12 }, (x, index) =>
  new Date(0, index + 1, 0).toLocaleDateString("ko-KR", { month: "short" })
);

// => [ "1์›”", "2์›”", "3์›”", "4์›”", "5์›”", "6์›”", "7์›”", "8์›”", "9์›”", "10์›”", "11์›”", "12์›”"]

๋‹ฌ ์ด๋ฆ„ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


์ค‘๋ณต ์š”์†Œ ์ œ๊ฑฐํ•˜๊ธฐ

const values = [1, 2, 3, 1, 2]

Array.from(new Set(values)) // [1, 2, 3]

[...new Set(values)] // [1, 2, 3]

...spread and ...rest

// 1:1 ๋ณต์‚ฌ
const copyOfHuman = { ...human };

// ๋ณต์‚ฌ ํ›„ ๋ฎ์–ด์“ฐ๊ธฐ
const copyNewId = {
  ...human,
  id: "das-vader"
};

// id๋ฅผ ๋บ€ ๋ชจ๋“  ๊ฒƒ
const { id, ...withoutId } = human;

๊ฐ์ฒด ๋‹ค๋ฃจ๊ธฐ

// ๊ธฐ์กด ๋ฐฐ์—ด๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋ฐฐ์—ด ๋’ค์ง‘๊ธฐ
const reversed = [...names].reverse();

์—๋Ÿฌ ํ•ธ๋“ค๋ง

process.on("unhandledRejection", error => {
  console.log("unhandledRejection", error);
});

๊ทผ๋ฐ ์œ„์™€ ๊ฐ™์ด ์—๋Ÿฌ๋ฅผ ๋ฌด์‹œํ•  ๋ฐ”์—” unhandledRejection ๋ฐœ์ƒ ์‹œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋Š”๊ฒŒ ๋‚ซ๋‹ค๊ณ  ๋…ธ๋“œ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค์— ๋‚˜์™€์žˆ๋‹ค.


Web ์Œ์„ฑ์ธ์‹

SpeechRecognition API๋กœ ์Œ์„ฑ์ธ์‹์ด ๊ฐ€๋Šฅํ•˜๋‹ค.


Shape Detection

์–ผ๊ตด, ๋ฐ”์ฝ”๋“œ, ํ…์ŠคํŠธ๋ฅผ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋‹ค.