TIL-js

๐Ÿ“™ Learn JavaScript Touch Events In 17 Minutes

์˜ˆ์ œ ๋ฐ”๋กœ๊ฐ€๊ธฐ


ํ„ฐ์น˜ ์ด๋ฒคํŠธ


ํ„ฐ์น˜ event ๊ฐ์ฒด ์ฃผ์š” ์†์„ฑ 3๊ฐ€์ง€

  1. touches : ํ˜„์žฌ ์Šคํฌ๋ฆฐ์—์„œ ํ„ฐ์น˜๋˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  ์ง€์ ์„ ๋ฐ˜ํ™˜
  2. targetTouches : ํ˜„์žฌ ํƒ€๊ฒŸ ๋‚ด์—์„œ ํ„ฐ์น˜๋˜๊ณ  ์žˆ๋Š” ์ง€์ ๋“ค์„ ๋ฐ˜ํ™˜
  3. changedTouches : ์ด์ „ ํ„ฐ์น˜ ์ด๋ฒคํŠธ์™€ ๋น„๊ตํ•˜์—ฌ ๋‹ฌ๋ผ์ง„ ํ„ฐ์น˜ ํฌ์ธํŠธ๋“ค์„ ๋ฐ˜ํ™˜
container.addEventListener("touchstart", (e) => {
  console.log("Touches", e.touches.length);
  console.log("Target Touches", e.targetTouches.length);
  console.log("Changed Touches", e.changedTouches.length);
});




๋นจ๊ฐ„์ ์œผ๋กœ ํ„ฐ์น˜ ์ง€์  ํ‘œ์‹œํ•˜๊ธฐ

1. touchstart ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ๋นจ๊ฐ„์  ์ƒ์„ฑํ•˜๊ธฐ

event ๊ฐ์ฒด์˜ changedTouches๋ฅผ ๋ฐ›์•„ spread ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•œ ํ›„(changedTouches๋Š” object์ด๊ธฐ ๋•Œ๋ฌธ์—) forEach๋ฌธ์„ ํ†ตํ•ด ์ƒˆ๋กœ์šด ํ„ฐ์น˜ ํฌ์ธํŠธ ๊ฐœ์ˆ˜๋งŒํผ ๋นจ๊ฐ„์ ์„ ์ƒ์„ฑํ•œ๋‹ค. pageX, pageY ์†์„ฑ์„ ์ด์šฉํ•˜์—ฌ ๋นจ๊ฐ„์ ์˜ ์œ„์น˜๋ฅผ ์žก์•„์ฃผ๊ณ , ํ„ฐ์น˜ํฌ์ธํŠธ ์‹๋ณ„๊ฐ’์ธ identifier ์†์„ฑ์„ ์ด์šฉํ•˜์—ฌ ๋นจ๊ฐ„์ ์˜ id๋กœ ์ง€์ •ํ•œ๋‹ค.

document.addEventListener("touchstart", (e) => {
  [...e.changedTouches].forEach((touch) => {
    // ๋นจ๊ฐ„์  ์ƒ์„ฑ
    const dot = document.createElement("div");
    dot.classList.add("dot");

    // ์œ„์น˜ ์žก๊ธฐ
    dot.style.top = `${touch.pageY}px`;
    dot.style.left = `${touch.pageX}px`;

    // id ์ง€์ •
    dot.id = touch.identifier;

    // DOM์— ์ถ”๊ฐ€
    document.body.append(dot);
  });
});

2. touchend ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ๋นจ๊ฐ„์  ์ œ๊ฑฐํ•˜๊ธฐ

ํ„ฐ์น˜๊ฐ€ ๋๋‚˜๋ฉด identifier ๊ฐ’์„ ํ™œ์šฉํ•˜์—ฌ ๋นจ๊ฐ„์ ์„ ์„ ํƒํ•˜๊ณ  DOM์—์„œ ์ œ๊ฑฐํ•œ๋‹ค.

document.addEventListener("touchend", (e) => {
  [...e.changedTouches].forEach((touch) => {
    const dot = document.getElementById(touch.identifier);
    dot.remove();
  });
});

3. touchmove ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ๋นจ๊ฐ„์  ์ด๋™์‹œํ‚ค๊ธฐ

identifier๋ฅผ ํ†ตํ•ด ๋นจ๊ฐ„์ ์„ ์„ ํƒํ•˜๊ณ , pageY, pageX ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ์ ์˜ ์œ„์น˜๋ฅผ ์กฐ์ ˆํ•œ๋‹ค.

document.addEventListener("touchmove", (e) => {
  [...e.changedTouches].forEach((touch) => {
    const dot = document.getElementById(touch.identifier);
    dot.style.top = `${touch.pageY}px`;
    dot.style.left = `${touch.pageX}px`;
  });
});

4. ํ„ฐ์น˜๊ฐ€ ์ทจ์†Œ๋  ๋•Œ ๋นจ๊ฐ„์  ์ œ๊ฑฐํ•˜๊ธฐ

๋ฒ„๊ทธ, ์˜ค๋ฅ˜ ๋“ฑ์œผ๋กœ ํ„ฐ์น˜๊ฐ€ ๋น„์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋  ๋•Œ touchcancel ์ด๋ฒคํŠธ๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

document.addEventListener("touchcancel", (e) => {
  [...e.changedTouches].forEach((touch) => {
    const dot = document.getElementById(touch.identifier);
    dot.remove();
  });
});


ํ„ฐ์น˜ ๊ธฐ๋ฐ˜ ์ œ์Šค์ฒ˜ (ํ™•๋Œ€, ์ถ•์†Œ, ํด๋ฆญ, ์Šคํฌ๋กค ๋‚ด๋ฆฌ๋ฉด ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ) ๋ฐฉ์ง€

touchstart ์ด๋ฒคํŠธ์—์„œ e.preventDefault()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ„ฐ์น˜ ๊ธฐ๋ฐ˜ ์ œ์Šค์ฒ˜๋“ค์ด ๋”์ด์ƒ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. ๋˜๋Š” CSS์—์„œ touch-action ์†์„ฑ์„ none์œผ๋กœ ์ง€์ •ํ•ด๋„ ๋™์ผํ•œ ํšจ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

container.addEventListener("touchstart", (e) => {
  e.preventDefault();
});