[TIL] 210927

Lee Syongยท2021๋…„ 9์›” 27์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
40/204
post-thumbnail

๐Ÿ“ ์˜ค๋Š˜ ํ•œ ๊ฒƒ

  1. ์‹ค์Šต: ํ† ๋ผ๋ฅผ ์ฐพ์•„๋ผ, ์ขŒํ‘œ ์ฐพ์•„ 007 '์„ฑ๋Šฅ ๊ฐœ์„ ', ์‡ผํ•‘ ๋ชฉ๋ก ์•ฑ ๋งŒ๋“ค๊ธฐ

  2. DOM / CCSOM / Render Tree / Critical rendering path / ์„ฑ๋Šฅ ๊ฐœ์„  / CSS ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ ๊ทธ๋ผ๋ฐ์ด์…˜ / ํ…Œ๋‘๋ฆฌ ๊ทธ๋ฆผ์ž / ๋“ค์—ฌ์“ฐ๊ธฐ&๋‚ด์–ด์“ฐ๊ธฐ / ENTER ํ‚ค ์ด๋ฒคํŠธ


๐Ÿ“– ํ•™์Šต ์ž๋ฃŒ

  1. ๋“œ๋ฆผ์ฝ”๋”ฉ 'ํ”„๋ก ํŠธ์—”๋“œ ํ•„์ˆ˜ ๋ธŒ๋ผ์šฐ์ € 101' ๊ฐ•์˜

๐Ÿ“š ๋ฐฐ์šด ๊ฒƒ

1. WEB APIs

1) ํ† ๋ผ๋ฅผ ์ฐพ์•„๋ผ

  • scrollIntoView ์‚ฌ์šฉ ์‹ค์Šต
<html>
  <head>
    <style>
      body {
        background-color: black;
      }

      button {
        display: block;
        margin: 0 auto;
        margin-bottom: 40px;
        background-color: lightcoral;
        color: white;
        border-style: none;
        border-radius: 5px;
        padding: 10px 10px;
        font-size: 20px;
        cursor: pointer;
      }

      .find-rabbit {
        display: inline;
        width: 20px;
        vertical-align: middle;
      }

      img {
        display: block;
        margin: 0 auto;
        width: 150px;
      }
    </style>
  </head>
  <body>
    <button>Find a rabbit&nbsp<img src="img/rabbit.png" class="find-rabbit" alt="ํ† ๋ผ๋ฅผ ์ฐพ์•„๋ผ"></button>
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/rabbit.png" class = "rabbit" alt="ํ† ๋ผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">
      <img src="img/carrot.png" alt="๋‹น๊ทผ">

    <script>
      const button = document.querySelector('button');
      const rabbit = document.querySelector('.rabbit');

      button.addEventListener('click', () => {
        rabbit.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'});
      });
    </script>
  </body>
</html>

2. DOM, CCSOM, Render Tree, Critical rendering path

1) ํ•„๊ธฐ

2) ์‹ค์Šต

๐Ÿ“Œ WEB APIs ์‹ค์Šต(์ขŒํ‘œ ์ฐพ์•„ 007) '์„ฑ๋Šฅ ๊ฐœ์„ '

๐Ÿ’ก ์›๋ž˜ ์ฝ”๋“œ

const circle = document.querySelector('.circle');
const horizon = document.querySelector('.horizon');
const vertical = document.querySelector('.vertical');
const coord = document.querySelector('.coord');

document.addEventListener('mousemove', (event) => {
  const clientX = event.clientX;
  const clientY = event.clientY;

  circle.style.left = `${clientX}px`;
  circle.style.top = `${clientY}px`;
  horizon.style.top = `${clientY}px`;
  vertical.style.left = `${clientX}px`;
  coord.style.left = `${clientX}px`;
  coord.style.top = `${clientY}px`;

  coord.innerHTML = `${clientX}px, ${clientY}px`;
});
  • left์™€ top๋Š” ๊ทธ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค layout๋ถ€ํ„ฐ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด paint, composition ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„์˜ ์ฝ”๋“œ๋Š” mousemove ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์ด ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์น˜๊ฒŒ ๋˜๋ฏ€๋กœ ๋น„ํšจ์œจ์ ์ด๋‹ค.

  • ๋Œ€์‹ ์— translate๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. translate๋Š” ๊ทธ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด๋„ composition ๊ณผ์ •๋ฐ–์— ์ผ์–ด๋‚˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋” ํšจ์œจ์ ์ด๋‹ค. (CSS Triggers ์ฐธ๊ณ )

  • ์‹ค์ œ๋กœ ์„ฑ๋Šฅ์ด ๊ฐœ์„ ๋˜์—ˆ๋Š”์ง€๋Š” ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ ์„ฑ๋Šฅ ํƒญ์—์„œ ๊ฒ€์‚ฌํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค. (ctrl+shift+p ๋ˆŒ๋Ÿฌ์„œ '๋ ˆ์ด์•„์›ƒ ๋ณ€๊ฒฝ ์ง€์—ญ ํ‘œ์‹œ' ์„ ํƒ ํ›„ ๋งˆ์šฐ์Šค ๋Œ๋ ค๋ณด๋ฉด ํ‘œ์‹œ๊ฐ€ ์•ˆ ๋œฌ๋‹ค.) 1 ํ”„๋ ˆ์ž„์„ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ด 16.67ms์„ ๋„˜์ง€ ์•Š๋„๋ก ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒŒ ์ข‹๋‹ค.


๐Ÿ’ก ์ˆ˜์ •ํ•œ ์ฝ”๋“œ

๐Ÿ”Ž JavaScript

const horizon = document.querySelector('.horizon');
const vertical = document.querySelector('.vertical');
const circle = document.querySelector('.circle');
const coord = document.querySelector('.coord');

const rectHalfWidth = circle.getBoundingClientRect().width / 2;
const rectHalfHeight = circle.getBoundingClientRect().height / 2;


document.addEventListener('mousemove', event => {
  const x = event.clientX;
  const y = event.clientY;

  horizon.style.transform = `translateY(${y}px)`;
  vertical.style.transform = `translateX(${x}px)`;

  circle.style.transform = `translate(${x - rectHalfWidth}px, ${y - rectHalfHeight}px)`;

  coord.style.transform = `translate(${x}px, ${y}px)`;

  coord.innerHTML = `${x}px, ${y}px`;
;});

๐Ÿ”Ž CSS

body {
  background-color: black;
  margin: 0; /* ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์˜ transform์— ์˜ํ•ด line์ด ์›€์ง์ด๋Š” ์‹œ์ž‘์ ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋ฏ€๋กœ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ margin ์ œ๊ฑฐ */
}

.line {
  background-color: white;
  position: absolute;
}

.horizon {
  width: 100%;
  height: 1px;
  /* ๊ธฐ๋ณธ ์œ„์น˜ ์„ค์ •ํ•ด์ค€ top ์ œ๊ฑฐ */
}

.vertical {
  width: 1px;
  height: 100%;
  /* ๊ธฐ๋ณธ ์œ„์น˜ ์„ค์ •ํ•ด์ค€ left ์ œ๊ฑฐ */
}

.circle {
  position: absolute;
  /* ๊ธฐ๋ณธ ์œ„์น˜ ์„ค์ •ํ•ด์ค€ left, top ์ œ๊ฑฐ */
  /* transform: translate(-50%, -50%) ์ œ๊ฑฐ (๋” ์ด์ƒ ์ ์šฉ x) */
}

.coord {
  color: white;
  position: absolute;
  font-size: 30px;
  /* ๊ธฐ๋ณธ ์œ„์น˜ ์„ค์ •ํ•ด์ค€ left, top ์ œ๊ฑฐ */
  /* transform: translate(-50%, -50%) ์ œ๊ฑฐ (๋” ์ด์ƒ ์ ์šฉ x) */
  margin: 30px;
}

๐Ÿ“Œ ์‡ผํ•‘ ๋ชฉ๋ก ์•ฑ ๋งŒ๋“ค๊ธฐ

  • CSS ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ ๊ทธ๋ผ๋ฐ์ด์…˜
background: linear-gradient(45deg, red, blue);
  • ํ…Œ๋‘๋ฆฌ ๊ทธ๋ฆผ์ž
box-shadow: 0 0 5px 1px gray; // ๊ฐ€๋กœ ๊ฑฐ๋ฆฌ, ์„ธ๋กœ ๊ฑฐ๋ฆฌ, ํ๋ฆผ ์ •๋„, ํผ์ง ์ •๋„, ์ƒ‰์ƒ
  • ๋“ค์—ฌ์“ฐ๊ธฐ / ๋‚ด์–ด์“ฐ๊ธฐ
text-indent: 0.5em; // ๋“ค์—ฌ์“ฐ๊ธฐ
text-indent: -0.5em; // ๋‚ด์–ด์“ฐ๊ธฐ
  • ENTER ํ‚ค ์ด๋ฒคํŠธ

    if (event.keyCode === 13) ๋˜๋Š”
    if (event.key === "Enter")


๐Ÿ’ก ์ˆ˜์ • ์ „, ์ตœ์ดˆ ๊ฒฐ๊ณผ๋ฌผ

๐Ÿ”Ž HTML

<html>
  <body>
    <section>
      <header>
        <h1>Shopping List</h1>
      </header>
      <div id="container">
        <div id="container-lists"></div>
        <input id="container-input" type="container-text">
      </div>
      <footer>
        <button><i class="fas fa-plus-circle"></i></button>
      </footer>
    </section>
  </body>
</html>

๐Ÿ”Ž CSS

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  font-family: "Gowun Batang", serif;
}

section {
  width: 450px;
  margin: 100px auto;
  border-radius: 20px;
  box-shadow: 0 0 10px gray;
}

header {
  background: linear-gradient(70deg, rgb(255, 215, 210), rgb(217, 255, 253));
  border-radius: 20px 20px 0 0;
  text-align: center;
  height: 60px;
  position: relative;
}

h1 {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  color: rgb(65, 65, 65);
}

#container {
  height: 500px;
}

#container-lists {
  height: 460px;
  background-color: rgb(252, 245, 239);
  padding: 10px 30px;
  overflow: auto;
}

#container-input {
  width: 100%;
  line-height: 40px;
  border-style: none;
  font-family: "Gowun Batang", serif;
  font-weight: bold;
  text-indent: 0.5em;
}

#container-input:focus {
  outline: none;
  box-shadow: 0.05em 0.05em 0.2em 0.1em rgb(201, 201, 201) inset;
}

footer {
  background: linear-gradient(70deg, rgb(255, 215, 210), rgb(217, 255, 253));
  border-radius: 0 0 20px 20px;
  text-align: center;
  height: 60px;
  position: relative;
}

button {
  border-style: none;
  background-color: transparent;
  cursor: pointer;
}

.fa-plus-circle {
  display: block;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 40px;
  color: rgb(65, 65, 65);
  border-radius: 50%;
}

.fa-plus-circle:hover {
  opacity: 0.7;
  transition: all 300ms;
}

๐Ÿ”Ž JavaScript

const lists = document.querySelector('#container-lists');
const input = document.querySelector('#container-input');
const button = document.querySelector('button');


function add (name) {
  if (input.value === '') {
    removeEventListener(name, this);
  } else {
    const set = document.createElement('div');

    set.style.display = 'flex';
    set.style.justifyContent = 'space-between';
    set.style.alignItems = 'center';
    set.style.margin = '15px 0';
    set.classList.add('set');

    set.innerHTML = `
    <p>${input.value}<p>
    <i class="far fa-trash-alt"></i>`;

    lists.appendChild(set);
    input.value = '';

    const sets = document.querySelectorAll('.set');
    const removeBtns = document.querySelectorAll('.far');

    for(let i = 0; i < sets.length; i++) {
      removeBtns[i].style.cursor = 'pointer';
      removeBtns[i].addEventListener('click', () => sets[i].remove());
    }
  }
}

button.addEventListener('click', add); // click ์ด๋ฒคํŠธ
input.addEventListener('keyup', e => { // keyup ์ด๋ฒคํŠธ
  if (e.keyCode === 13) {
    add('keyup');
  } else {
    removeEventListener('keyup', this);
  }
});
profile
๋Šฅ๋™์ ์œผ๋กœ ์‚ด์ž, ํ–‰๋ณตํ•˜๊ฒŒ๐Ÿ˜

0๊ฐœ์˜ ๋Œ“๊ธ€