์ถ์ฒ: https://youtu.be/pws4qzGn5ak
ํ ์์๊ฐ ํ๋ฉด ์์ผ๋ก ๋ค์ด์๋์ง ํ์ธํ ๋ ์ฌ์ฉํ๋ค.
- ์คํฌ๋กค ์ ์์์ ์ ๋๋ฉ์ด์ ๋ฃ๊ธฐ
- ์คํฌ๋กค ์ ๋น๋์ค ์ฌ์
- ์ด๋ฏธ์ง ์ง์ฐ๋ก๋ฉ
- ๊ด๊ณ ๋ ธ์ถ์ ์ธ๊ธฐ
- ์คํฐํค ํค๋
๋ฑ์ ์ฌ์ฉํ ์ ์๋ค.
const options = {
root: document.querySelector(".scrollingDiv"),
rootMargin: "100px",
// ํ๋ฉด์ ์์ ๋, ๋ฐ๋ง, ์์ ํ ๋ค์ด์์ ๋ ์๋ ค์ค
threshold: [0, 0.5, 1.0]
};const observer = new IntersectionObserver(callback, options);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);
});
};const boxes = document.querySelectorAll(".box");
boxes.forEach(box => observer.observe(box));์์์ ํฌ๊ธฐ ๋ณ๊ฒฝ์ ํ์ธํ ์ ์๋ค.
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);์ ๋ ฅ๋ฐ์ ์ ํ์์ ์ผ์นํ๋ ๊ฐ์ฅ ๊ฐ๊น์ด ์กฐ์์์๋ฅผ ์ฐพ๋๋ค.
<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"}!`;
});์์ ๋ฐ์ ํด๋ฆญํ๋์ง ์์ ํด๋ฆญํ๋์ง ํ์ธํ ๋๋ ์ ์ฉํ๋ค.
ํ ์์๊ฐ ์ ํ์์ ์ผ์นํ๋์ง ํ์ธํ๋ค.
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์๋ ์ฌ์ฉํ๋ค.
๋ชจ๋ ๋ฆฌ์คํธ ๋ด์ ์์ดํ ์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ถ์ผ ํ์๊ฐ ์๋ค.
const modal = document.querySelector(".modal");
modal.contains(button); // true
modal.querySelector("button"); // <button></button>
// contains ๋ฉ์๋์ ๊ฐ์
!!modal.querySelector("button"); // true๋ฐ๋๋ผ 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์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํจ
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]// 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 ๋ฐ์ ์ ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃํ๊ณ ๋ค์ ์์ํ๋๊ฒ ๋ซ๋ค๊ณ ๋ ธ๋ ๋ฒ ์คํธ ํ๋ํฐ์ค์ ๋์์๋ค.
SpeechRecognition API๋ก ์์ฑ์ธ์์ด ๊ฐ๋ฅํ๋ค.
์ผ๊ตด, ๋ฐ์ฝ๋, ํ ์คํธ๋ฅผ ์ธ์ํ ์ ์๋ค.