๐Ÿ“ŒLanguage/JavaScript

[Deep Dive] DOM๊ณผ ๋…ธ๋“œ

hellohailie 2022. 12. 15. 15:45

โœ”๏ธ ์ด๋ฒˆ ์ •๋…์„ ํ†ตํ•ด ์•Œ๊ฒŒ ๋œ ๊ฒƒ
DOM์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?
innerHTML์˜ ๋‹จ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

 

<๋‹ต ๋ฏธ๋ฆฌ๋ณด๊ธฐ>

๐Ÿค” DOM์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

๐Ÿค“ HTML ๋ฌธ์„œ์˜ ๊ณ„์ธต์  ๊ตฌ์กฐ์™€ ์ •๋ณด๋ฅผ ํ‘œํ˜„ํ•˜๋ฉฐ ์ด๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” API, ์ฆ‰ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.

 

๐Ÿค” innerHTML์˜ ๋‹จ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

๐Ÿค“ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ innerHTML ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์€ XSS(ํฌ๋กœ์Šค ์‚ฌ์ดํŠธ ์Šคํฌ๋ฆฝํŒ… ๊ณต๊ฒฉ)์— ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์š”์†Œ ๋…ธ๋“œ์˜ ๊ธฐ์กด ์ž์‹ ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ํ• ๋‹นํ•œ HTML ๋งˆํฌ์—… ๋ฌธ์ž์—ด์„ ํŒŒ์‹ฑํ•˜์—ฌ DOM์„ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

 


โœ”๏ธ DOM์ด๋ž€?

Document Object Model์€ HTML ๋ฌธ์„œ์˜ ๊ณ„์ธต์  ๊ตฌ์กฐ์™€ ์ •๋ณด๋ฅผ ํ‘œํ˜„ํ•˜๋ฉฐ ์ด๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” API, ์ฆ‰ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.

 

HTML ์š”์†Œ๋Š” ๋ Œ๋”๋ง ์—”์ง„์— ์˜ํ•ด ํŒŒ์‹ฑ๋˜์–ด DOM์„ ๊ตฌ์„ฑํ•˜๋Š” ์š”์†Œ ๋…ธ๋“œ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜๋œ๋‹ค. 

 

ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ์™€ ์ž์‹ ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋˜์–ด ๋…ธ๋“œ ๊ฐ„์˜ ๊ณ„์ธต์  ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค. 

์ตœ์ƒ์œ„ ๋…ธ๋“œ๋Š” ๋ฃจํŠธ ๋…ธ๋“œ๋ผ๊ณ  ํ•˜๋ฉฐ ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ์—†๋‹ค. ๋ฃจํŠธ ๋…ธ๋“œ๋Š” 0๊ฐœ ์ด์ƒ์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ–๋Š”๋‹ค. ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์—†๋Š” ๋…ธ๋“œ๋ฅผ ๋ฆฌํ”„ ๋…ธ๋“œ๋ผ๊ณ  ํ•œ๋‹ค. 

 

๋…ธ๋“œ ๊ฐ์ฒด๋“ค๋กœ ๊ตฌ์„ฑ๋œ ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ DOM์ด๋ผ๊ณ  ํ•œ๋‹ค. 

 

โœ”๏ธ ๋…ธ๋“œ ํƒ€์ž…

โ–  ๋ฌธ์„œ ๋…ธ๋“œ :

DOM ํŠธ๋ฆฌ์˜ ์ตœ์ƒ์œ„์— ์กด์žฌํ•˜๋Š” ๋ฃจํŠธ ๋…ธ๋“œ๋กœ์„œ document ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. HTML ๋ฌธ์„œ๋‹น document ๊ฐ์ฒด๋Š” ์œ ์ผํ•˜๋‹ค. 

์š”์†Œ ๋…ธ๋“œ, ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ๋…ธ๋“œ, ํ…์ŠคํŠธ ๋…ธ๋“œ)

 

โ–  ์š”์†Œ ๋…ธ๋“œ :

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

 

โ–  ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ๋…ธ๋“œ :

HTML ์š”์†Œ์˜ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด๋‹ค. ์š”์†Œ ๋…ธ๋“œ์—๋งŒ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค. 

โ–  ํ…์ŠคํŠธ ๋…ธ๋“œ :

HTML ์š”์†Œ์˜ ํ…์ŠคํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด๋‹ค. ์š”์†Œ ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ์ด๋ฉฐ, ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†๋Š” ๋ฆฌํ”„ ๋…ธ๋“œ์ด๋‹ค. 

 


DOM์„ ๊ตฌ์„ฑํ•˜๋Š” ๋…ธ๋“œ ๊ฐ์ฒด๋Š” DOM API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋…ธ๋“œ ๊ฐ์ฒด๋Š” ์ž์‹ ์˜ ๋ถ€๋ชจ, ํ˜•์ œ, ์ž์‹์„ ํƒ์ƒ‰ํ•˜๊ณ  ์ž์‹ ์˜ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์™€ ํ…์ŠคํŠธ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋Š” HTML์„ DOM๊ณผ ์—ฐ๊ด€์ง€์–ด ๋ฐ”๋ผ๋ด์•ผํ•œ๋‹ค. 


โœ”๏ธ ์š”์†Œ ๋…ธ๋“œ ์ทจ๋“

์š”์†Œ ๋…ธ๋“œ๋ฅผ ์ทจ๋“ํ•˜๋Š” ๊ฑด HTML ์š”์†Œ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ์‹œ์ž‘์ ์ด๋‹ค!

 

  • id๋กœ ์š”์†Œ ๋…ธ๋“œ ์ทจ๋“ํ•˜๊ธฐ (getElementById)
document.getElementById('apple');

id ๊ฐ’์€ HTML ๋ฌธ์„œ ๋‚ด์—์„œ ์œ ์ผํ•œ ๊ฐ’์ด์–ด์•ผ ํ•œ๋‹ค. 

 

 

  • ํƒœ๊ทธ ์ด๋ฆ„์œผ๋กœ ์š”์†Œ ๋…ธ๋“œ ์ทจ๋“ํ•˜๊ธฐ (getElementsByTagName)
document.getElementsByTagName('li');

 

  • class๋กœ ์š”์†Œ ๋…ธ๋“œ ์ทจ๋“ํ•˜๊ธฐ (getElementsByClassName)
document.getElementsByClassName('fruit');

 

  • css ์„ ํƒ์ž๋กœ ์š”์†Œ ๋…ธ๋“œ ์ทจ๋“ํ•˜๊ธฐ (querySelector / querySelectorAll)
/* ์ „์ฒด ์„ ํƒ์ž: ๋ชจ๋“  ์š”์†Œ๋ฅผ ์„ ํƒ */
* { ... }
/* ํƒœ๊ทธ ์„ ํƒ์ž: ๋ชจ๋“  p ํƒœ๊ทธ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์„ ํƒ */
p { ... }
/* id ์„ ํƒ์ž: id ๊ฐ’์ด 'foo'์ธ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์„ ํƒ */
#foo { ... }
/* class ์„ ํƒ์ž: class ๊ฐ’์ด 'foo'์ธ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์„ ํƒ */
.foo { ... }
/* ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์„ ํƒ์ž: input ์š”์†Œ ์ค‘์— type ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ๊ฐ’์ด 'text'์ธ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์„ ํƒ */
input[type=text] { ... }
/* ํ›„์† ์„ ํƒ์ž: div ์š”์†Œ์˜ ํ›„์† ์š”์†Œ ์ค‘ p ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์„ ํƒ */
div p { ... }
/* ์ž์‹ ์„ ํƒ์ž: div ์š”์†Œ์˜ ์ž์‹ ์š”์†Œ ์ค‘ p ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์„ ํƒ */
div > p { ... }
/* ์ธ์ ‘ ํ˜•์ œ ์„ ํƒ์ž: p ์š”์†Œ์˜ ํ˜•์ œ ์š”์†Œ ์ค‘์— p ์š”์†Œ ๋ฐ”๋กœ ๋’ค์— ์œ„์น˜ํ•˜๋Š” ul ์š”์†Œ๋ฅผ ์„ ํƒ */
p + ul { ... }
/* ์ผ๋ฐ˜ ํ˜•์ œ ์„ ํƒ์ž: p ์š”์†Œ์˜ ํ˜•์ œ ์š”์†Œ ์ค‘์— p ์š”์†Œ ๋’ค์— ์œ„์น˜ํ•˜๋Š” ul ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์„ ํƒ */
p ~ ul { ... }
/* ๊ฐ€์ƒ ํด๋ž˜์Šค ์„ ํƒ์ž: hover ์ƒํƒœ์ธ a ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์„ ํƒ */
a:hover { ... }
/* ๊ฐ€์ƒ ์š”์†Œ ์„ ํƒ์ž: p ์š”์†Œ์˜ ์ฝ˜ํ…์ธ ์˜ ์•ž์— ์œ„์น˜ํ•˜๋Š” ๊ณต๊ฐ„์„ ์„ ํƒ
   ์ผ๋ฐ˜์ ์œผ๋กœ content ํ”„๋กœํผํ‹ฐ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋œ๋‹ค. */
p::before { ... }

โœ”๏ธ ์š”์†Œ ๋…ธ๋“œ์˜ ํ…์ŠคํŠธ ์กฐ์ž‘

nodeValue & textContent

<!DOCTYPE html>
<html>
  <body>
    <!-- ์š”์†Œ ๋…ธ๋“œ์˜ ์ฝ˜ํ…์ธ  ์˜์—ญ์— ๋‹ค๋ฅธ ์š”์†Œ ๋…ธ๋“œ๊ฐ€ ์—†๊ณ  ํ…์ŠคํŠธ๋งŒ ์กด์žฌ -->
    <div id="foo">Hello</div>
  </body>
  <script>
    const $foo = document.getElementById('foo');

    // ์š”์†Œ ๋…ธ๋“œ์˜ ์ฝ˜ํ…์ธ  ์˜์—ญ์— ์ž์‹ ์š”์†Œ ๋…ธ๋“œ๊ฐ€ ์—†๊ณ  ํ…์ŠคํŠธ๋งŒ ์กด์žฌํ•œ๋‹ค๋ฉด
    // firstChild.nodeValue์™€ textContent๋Š” ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    console.log($foo.textContent === $foo.firstChild.nodeValue); // true
  </script>
</html>

textContent ํ”„๋กœํผํ‹ฐ์™€ ์œ ์‚ฌํ•œ ๋™์ž‘์„ ํ•˜๋Š” innerText ํ”„๋กœํผํ‹ฐ!

ํ•˜์ง€๋งŒ innerText ํ”„๋กœํผํ‹ฐ๋Š” CSS์— ์ˆœ์ข…์ ์ด๋ผ textContent ํ”„๋กœํผํ‹ฐ๋ณด๋‹ค ๋Š๋ฆฌ๊ณ , CSS์— ์˜ํ•ด ๋น„ํ‘œ์‹œ๋˜๋Š” ์š”์†Œ ๋…ธ๋“œ์˜ ํ…์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค. 


โœ”๏ธ DOM ์กฐ์ž‘

DOM ์กฐ์ž‘์€ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ DOM์— ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ๋…ธ๋“œ๋ฅผ ์‚ญ์ œ ๋˜๋Š” ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. 

DOM ์กฐ์ž‘์— ์˜ํ•ด ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ๊ฐ€ ๋ฐœ์ƒํ•ด์„œ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ฃผ๊ฒŒ ๋œ๋‹ค. 

 

innerHTML

์š”์†Œ ๋…ธ๋“œ์˜ innerHTML ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ์š”์†Œ ๋…ธ๋“œ์˜ ์ฝ˜ํ…์ธ  ์˜์—ญ ๋‚ด์— ํฌํ•จ๋œ ๋ชจ๋“  HTML ๋งˆํฌ์—…์„ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

<!DOCTYPE html>
<html>
  <body>
    <div id="foo">Hello <span>world!</span></div>
  </body>
  <script>
    // #foo ์š”์†Œ์˜ ์ฝ˜ํ…์ธ  ์˜์—ญ ๋‚ด์˜ HTML ๋งˆํฌ์—…์„ ๋ฌธ์ž์—ด๋กœ ์ทจ๋“ํ•œ๋‹ค.
    console.log(document.getElementById('foo').innerHTML);
    // "Hello <span>world!</span>"
  </script>
</html>

โ€ป textContent๋Š” HTML ๋งˆํฌ์—…์„ ๋ฌด์‹œํ•˜๊ณ  ํ…์ŠคํŠธ๋งŒ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, innerHTML์€ HTML ๋งˆํฌ์—…์ด ํฌํ•จ๋œ ๋ฌธ์ž์—ด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

 

โ‰๏ธ innerHTML์˜ ๋‹จ์  โ‰๏ธ

1. ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ innerHTML ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์€ XSS(ํฌ๋กœ์Šค ์‚ฌ์ดํŠธ ์Šคํฌ๋ฆฝํŒ… ๊ณต๊ฒฉ)์— ์ทจ์•ฝํ•˜๋‹ค!!

2. ์š”์†Œ ๋…ธ๋“œ์˜ innerHTML ํ”„๋กœํผํ‹ฐ์— HTML ๋งˆํฌ์—… ๋ฌธ์ž์—ด์„ ํ• ๋‹นํ•˜๋Š” ๊ฒฝ์šฐ ์š”์†Œ ๋…ธ๋“œ์˜ ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ํ• ๋‹นํ•œ HTML ๋งˆํฌ์—… ๋ฌธ์ž์—ด์„ ํŒŒ์‹ฑํ•˜์—ฌ DOM์„ ๋ณ€๊ฒฝํ•œ๋‹ค. => insertAdjacentHTML์€ ๊ธฐ์กด ๋…ธ๋“œ ์‚ญ์ œ ์•ˆํ•จ(XSS ๊ณต๊ฒฉ์— ์ทจ์•ฝํ•œ๊ฑด ๋งˆ์ฐฌ๊ฐ€์ง€!!)

 


์š”์†Œ ๋…ธ๋“œ ์ƒ์„ฑ๊ณผ ์ถ”๊ฐ€

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li>Apple</li>
    </ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // 1. ์š”์†Œ ๋…ธ๋“œ ์ƒ์„ฑ
    const $li = document.createElement('li');

    // 2. ํ…์ŠคํŠธ ๋…ธ๋“œ ์ƒ์„ฑ
    const textNode = document.createTextNode('Banana');

    // 3. ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ $li ์š”์†Œ ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ๋กœ ์ถ”๊ฐ€
    $li.appendChild(textNode);

    // 4. $li ์š”์†Œ ๋…ธ๋“œ๋ฅผ #fruits ์š”์†Œ ๋…ธ๋“œ์˜ ๋งˆ์ง€๋ง‰ ์ž์‹ ๋…ธ๋“œ๋กœ ์ถ”๊ฐ€
    $fruits.appendChild($li);
  </script>
</html>

๐Ÿ‘‰ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค DOM์„ ๊ฑด๋“œ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ƒ ์ข‹์ง€ ์•Š๋‹ค. 

 

<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits"></ul>
  </body>
  <script>
    const $fruits = document.getElementById('fruits');

    // DocumentFragment ๋…ธ๋“œ ์ƒ์„ฑ
    const $fragment = document.createDocumentFragment();

    ['Apple', 'Banana', 'Orange'].forEach(text => {
      // 1. ์š”์†Œ ๋…ธ๋“œ ์ƒ์„ฑ
      const $li = document.createElement('li');

      // 2. ํ…์ŠคํŠธ ๋…ธ๋“œ ์ƒ์„ฑ
      const textNode = document.createTextNode(text);

      // 3. ํ…์ŠคํŠธ ๋…ธ๋“œ๋ฅผ $li ์š”์†Œ ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ๋กœ ์ถ”๊ฐ€
      $li.appendChild(textNode);

      // 4. $li ์š”์†Œ ๋…ธ๋“œ๋ฅผ DocumentFragment ๋…ธ๋“œ์˜ ๋งˆ์ง€๋ง‰ ์ž์‹ ๋…ธ๋“œ๋กœ ์ถ”๊ฐ€
      $fragment.appendChild($li);
    });

    // 5. DocumentFragment ๋…ธ๋“œ๋ฅผ #fruits ์š”์†Œ ๋…ธ๋“œ์˜ ๋งˆ์ง€๋ง‰ ์ž์‹ ๋…ธ๋“œ๋กœ ์ถ”๊ฐ€
    $fruits.appendChild($fragment);
  </script>
</html>

๐Ÿ‘‰ DOM์„ ํ•œ๋ฒˆ๋งŒ ํ•œ๋ฒˆ๋งŒ ๋ณ€๊ฒฝํ•ด์„œ ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ๋„ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋œ๋‹ค. 

์—ฌ๋Ÿฌ๊ฐœ์˜ ์š”์†Œ ๋…ธ๋“œ๋ฅผ DOM์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ DocumentFragment ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ž!!

 


 

๐Ÿ‘ฉ‍๐Ÿ’ป ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive๋ฅผ ์ •๋…ํ•˜๊ณ  ์ œ๊ฐ€ ์ดํ•ดํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค ๐Ÿ‘ฉ‍๐Ÿ’ป