Skip to content

๐Ÿ ๋งˆ์šฐ์Šค ์ƒ๋Œ€์œ„์น˜ ๊ณ„์‚ฐ์€ ์ด์ƒํ•ด

Soobeen Yoon edited this page Dec 18, 2022 · 3 revisions

๋งˆ์šฐ์Šค๋ฅผ ๋”ฐ๋ผ๋‹ค๋‹ˆ๋Š” ๋งํ’์„ ์„ ๋งŒ๋“ค์ž!

image

  • ์˜๋„

    • ์œ„ ๋””์ž์ธ๊ณผ ๊ฐ™์ด, svg ํŒจ์Šค์— ๋งˆ์šฐ์Šค๋ฅผ ํ˜ธ๋ฒ„ํ•˜๋ฉด, ๊ด€๋ จ๋œ ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€๊ฐ€ ๋งํ’์„ ์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋งŒ๋“ค๊ณ ์ž ํ–ˆ๋‹ค!
    • ํŒจ์Šค๋ผ๋ฆฌ ์„œ๋กœ ๊ฒน์น  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํŒจ์Šค ์œ„์˜ ๊ณ ์ •๋œ ์œ„์น˜์— ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค,
      ๋ฉ”์‹œ์ง€๊ฐ€ ๋งˆ์šฐ์Šค๋ฅผ ๋”ฐ๋ผ๋‹ค๋‹ˆ๋„๋ก ํ•ด์„œ ์ƒ๋Œ€์ ์œผ๋กœ ์ž์œ ๋กญ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ๋””์ž์ธํ•œ ์ผ€์ด์Šค์ด๋‹ค.
  • ์ ‘๊ทผ

    • onMouseEnter์™€ onMouseLeave๋กœ ๋งˆ์šฐ์Šค ํ˜ธ๋ฒ„๋ฅผ ์ธ์‹ํ•ด ์ƒํƒœ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.
    • ๋งˆ์šฐ์Šค ์œ„์น˜๋ฅผ ์ƒํƒœ๋กœ ๋ณด๊ด€ํ•˜๊ณ  onMouseEvent๋ฅผ ํ†ตํ•ด ๋งˆ์šฐ์Šค ์œ„์น˜๋ฅผ ๊ฐฑ์‹ ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

MouseEvent์˜ ๋งˆ์šฐ์Šค ์œ„์น˜ ์ •๋ณด๋“ค

  • MouseEvent๋Š” ์ •๋ง ๋‹ค์–‘ํ•œ ๋งˆ์šฐ์Šค ์œ„์น˜ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
    • event.clientX, Y : ํ˜„์žฌ ๋ธŒ๋ผ์šฐ์ €์— ํ‘œ์‹œ๋˜๊ณ  ์žˆ๋Š” ํ™”๋ฉด์„ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์ขŒํ‘œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค
    • event.offsetX, Y : event.target์„ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์ขŒํ‘œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
    • event.pageX, Y : ์ „์ฒด ํŽ˜์ด์ง€(document)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์ขŒํ‘œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
    • event.screenX, Y : ์‚ฌ์šฉ์ž์˜ ๋ชจ๋‹ˆํ„ฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์ขŒํ‘œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

image

  • ์ด๋ ‡๊ฒŒ ๋‹ค์–‘ํ•œ ์œ„์น˜์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ, ๋ชจ๋‘ ํŠน์ •ํ•œ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์ƒ๋Œ€๊ฐ’์„ ์‰ฝ๊ฒŒ ๊ตฌํ•˜๊ธฐ์—๋Š” ๋ฏธ๋ฌ˜ํ•œ ํŠน์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

๋ฌธ์ œ: offsetX, Y์˜ ๋™์ž‘์ด ์ด์ƒํ•˜๋‹ค!

  • ์ง๊ด€์ ์œผ๋กœ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„๋ฐฉ๋ฒ•์€ offsetX, Y๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์—ฌ ๋ฐ”๋กœ ์‹คํ–‰ํ–ˆ๋‹ค.
  • ํ˜ธ๋ฒ„์˜ ๋Œ€์ƒ์ด ๋˜๋Š” ํŒจ์Šค๋“ค์ด DOM๊ตฌ์กฐ์ƒ ์ตœํ•˜์œ„์— ์œ„์น˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— target ์˜ค์ธ์œผ๋กœ ์ธํ•œ ๋ฒ„๊ทธ๋„ ์—†์„ ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒํ–ˆ๋‹ค.
  • ๋‹จ, React์—์„œ๋Š” offsetX, Y์— ์กฐ๊ธˆ ํŠน์ดํ•˜๊ฒŒ ์ ‘๊ทผํ•œ๋‹ค.
    • ๋‹ค๋ฅธ ๋งˆ์šฐ์Šค ์œ„์น˜ ํ”„๋กœํผํ‹ฐ๋“ค๊ณผ ๋‹ฌ๋ฆฌ event.offsetX๊ฐ€ ์•„๋‹ˆ๋ผ event.nativeEvent.offsetX๋กœ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค.
  const onMouseLeave = (event: React.MouseEvent): void => {
    setIsHovered(false);
  };
  const onMouseEnter = (event: React.MouseEvent): void => {
    setMousePos(() => ({ x: event.nativeEvent.offsetX, y: event.nativeEvent.offsetY }));
    console.log(event.target);
    console.log({ x: event.nativeEvent.offsetX, y: event.nativeEvent.offsetY });
    setIsHovered(true);
  };
  const onMouseMove = (event: React.MouseEvent): void => {
    if (isHovered) {
      setMousePos(() => ({ x: event.nativeEvent.offsetX, y: event.nativeEvent.offsetY }));
      console.log(event.target);
      console.log({ x: event.nativeEvent.offsetX, y: event.nativeEvent.offsetY });
    }
  };
  • ๋ฌธ์ œ: ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„์„ ํ•˜๋”๋ผ๋„... onMouseEnter์‹œ์— ์žกํžˆ๋Š” ๊ฐ’๊ณผ onMouseMove์‹œ์— ์žกํžˆ๋Š” ๊ฐ’์ด ๋‹ค๋ฅด๋‹ค....

    mousePos_Bug1

    • ์œ„์™€ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค!
    • event.target์€ ๋ถ„๋ช… ๋™์ผํ•œ๋ฐ, onMouseEnter์™€ onMouseMove์‹œ์— ์žกํžˆ๋Š” offsetX,Y๊ฐ’์ด ๋‹ค๋ฅด๊ฒŒ ๋‚˜ํƒ€๋‚˜๊ณ ,
      ์ด๊ฒŒ ๋ฐ˜์˜๋˜์–ด ๋งํ’์„ ์ด ๋ถ€์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์›€์ง์ด๋Š” ํ˜„์ƒ์ด ์ผ์–ด๋‚œ๋‹ค.

ํ•ด๊ฒฐ: getElementBoundingBox๋ฅผ ์‚ฌ์šฉํ•˜์ž

  • ref์— wrapper ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ €์žฅํ•œ๋‹ค.
  • clientX, Y๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.
  • getBoundingClientRect()๋ฅผ ์ด์šฉํ•ด wrapper ์—˜๋ฆฌ๋จผํŠธ์˜ ์œ„์น˜๋งŒํผ์„ ๋นผ์„œ ์ง์ ‘ ๊ณ„์‚ฐํ•œ๋‹ค.
  const onMouseLeave = (event: React.MouseEvent): void => {
    setIsHovered(false);
  };
  const onMouseEnter = (event: React.MouseEvent): void => {
    setMousePos(() => ({
      x: event.clientX - (domRef.current?.getBoundingClientRect().left as number),
      y: event.clientY - (domRef.current?.getBoundingClientRect().top as number),
    }));
    setIsHovered(true);
  };
  const onMouseMove = (event: React.MouseEvent): void => {
    if (isHovered) {
      setMousePos(() => ({
        x: event.clientX - (domRef.current?.getBoundingClientRect().left as number),
        y: event.clientY - (domRef.current?.getBoundingClientRect().top as number),
      }));
    }
  };

mousePos_Sol1

  • ํ•ด๊ฒฐ! ์ด๋ ‡๊ฒŒ ํ•˜๊ณ ๋‚˜๋‹ˆ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋งํ’์„ ์ด ์ž˜ ๋ Œ๋”๋˜์—ˆ๋‹ค.
    • https://github.com/facebook/react/issues/4431 ๊ตฌํ˜„์„ ํ•˜๋‹ค ์ฐธ๊ณ ํ•˜๋ฉฐ ์ฝ์€ ์ด ๊ธ€์—์„œ๋Š” offsetX, Y๋Š” getBoundingClientRect๋กœ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋™์ž‘์„ ํ•œ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ์™œ ์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ง€๋Š” ๋ฏธ์ง€์ˆ˜์ด๋‹ค...
    • target ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ์ธ์‹๋˜๋Š” ๊ฒƒ์ด ๋ฌธ์ œ์ธ๊ฐ€ ์‹ถ์—ˆ์œผ๋‚˜, ์‹ค์ œ๋กœ ๋กœ๊ทธ์— ์ฐํžˆ๋Š” ํƒ€๊ฒŸ์€ ์™„์ „ํžˆ ๋™์ผํ–ˆ๋‹ค.
    • ์•„์ง ์›์ธ์„ ๋ช…ํ™•ํžˆ ์•Œ ์ˆ˜ ์—†์œผ๋‚˜, ์•ž์œผ๋กœ ๋งˆ์šฐ์Šค ์ƒ๋Œ€์œ„์น˜๋ฅผ ๊ตฌํ•  ์ผ์ด ์žˆ๋‹ค๋ฉด ํ•ญ์ƒ ์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Œ์„ ์—ผ๋‘์— ๋‘๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

๐Ÿ’Š ๋น„ํƒ€500

๐Ÿ“Œ ํ”„๋กœ์ ํŠธ

๐Ÿพ ๊ฐœ๋ฐœ ์ผ์ง€

๐Ÿฅ‘ ๊ทธ๋ฃนํ™œ๋™

๐ŸŒด ๋ฉ˜ํ† ๋ง
๐Ÿฅ• ๋ฐ์ผ๋ฆฌ ์Šคํฌ๋Ÿผ
๐Ÿ’ ๋ฐ์ผ๋ฆฌ ๊ฐœ์ธ ํšŒ๊ณ 
๐Ÿฅ ์ฃผ๊ฐ„ ํšŒ๊ณ 
๐Ÿ‘ฏ ๋ฐœํ‘œ ์ž๋ฃŒ
Clone this wiki locally