<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>나를 제외한 천재들</title>
    <link>https://gurtn.tistory.com/</link>
    <description>안녕하세요. JavaScript를 주로 다루는 코딩 블로그입니다.</description>
    <language>ko</language>
    <pubDate>Fri, 19 Jun 2026 09:36:02 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>나를 제외한 천재들</managingEditor>
    <image>
      <title>나를 제외한 천재들</title>
      <url>https://tistory1.daumcdn.net/tistory/4182739/attach/eb98eb8944804027981dc8ed243414df</url>
      <link>https://gurtn.tistory.com</link>
    </image>
    <item>
      <title>[JS] 소수점 존재여부 확인하기</title>
      <link>https://gurtn.tistory.com/217</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZU6C5/btsmRsgA6vj/8DuwtlMOmWxHceRsohndUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZU6C5/btsmRsgA6vj/8DuwtlMOmWxHceRsohndUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZU6C5/btsmRsgA6vj/8DuwtlMOmWxHceRsohndUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZU6C5%2FbtsmRsgA6vj%2F8DuwtlMOmWxHceRsohndUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;331&quot; height=&quot;189&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1688898188572&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function hasDecimal(number) {
  return number % 1 !== 0;
}

hasDecimal(123);
// false
hasDecimal(123.45);
// true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code&quot;&gt;number % 1&lt;/span&gt;은 숫자를 1로 나눈 &lt;b&gt;나머지를 계산&lt;/b&gt;하는데, 정수가 아니면 0이 아닌 값을 반환하는 점을 이용한 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;96&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWQpCW/btsmWnlgYX2/5v96RDrPcZQ4ztnsYTooB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWQpCW/btsmWnlgYX2/5v96RDrPcZQ4ztnsYTooB1/img.png&quot; data-alt=&quot;나머지 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWQpCW/btsmWnlgYX2/5v96RDrPcZQ4ztnsYTooB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWQpCW%2FbtsmWnlgYX2%2F5v96RDrPcZQ4ztnsYTooB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;289&quot; height=&quot;138&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;96&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;나머지 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;자바스크립트에서는 문자열에 대해서 나머지 연산자를 사용해면 똑같은 0의 결과가 나오게 됩니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;오직 숫자만 판별하기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1688898311282&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function hasDecimal(number) {
  return typeof number === 'number' &amp;amp;&amp;amp; number % 1 !== 0;
}

hasDecimal('123.45');
// false
hasDecimal(123.45);
// true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자가 아닌(문자열, boolean...) 경우를 판별하기 위해서 &lt;span class=&quot;code&quot;&gt;typeof 연산자&lt;/span&gt;를 이용해서 '&lt;span class=&quot;code&quot;&gt;number' 타입&lt;/span&gt;을 판별해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/2304052/check-if-a-number-has-a-decimal-place-is-a-whole-number&quot;&gt;https://stackoverflow.com/questions/2304052/check-if-a-number-has-a-decimal-place-is-a-whole-number&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1688898573234&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Check if a number has a decimal place/is a whole number&quot; data-og-description=&quot;I am looking for an easy way in JavaScript to check if a number has a decimal place in it (in order to determine if it is an integer). For instance, 23 -&amp;gt; OK 5 -&amp;gt; OK 3.5 -&amp;gt; not OK 34.345...&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/2304052/check-if-a-number-has-a-decimal-place-is-a-whole-number&quot; data-og-url=&quot;https://stackoverflow.com/questions/2304052/check-if-a-number-has-a-decimal-place-is-a-whole-number&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c8J0x0/hyTgNrHVUi/9GkqKMk51Pj14AnWRIyaW0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/2304052/check-if-a-number-has-a-decimal-place-is-a-whole-number&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/2304052/check-if-a-number-has-a-decimal-place-is-a-whole-number&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c8J0x0/hyTgNrHVUi/9GkqKMk51Pj14AnWRIyaW0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Check if a number has a decimal place/is a whole number&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I am looking for an easy way in JavaScript to check if a number has a decimal place in it (in order to determine if it is an integer). For instance, 23 -&amp;gt; OK 5 -&amp;gt; OK 3.5 -&amp;gt; not OK 34.345...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>소수</category>
      <category>소수점</category>
      <category>자바스크립트</category>
      <category>정수</category>
      <category>존재여부</category>
      <category>체크</category>
      <category>판별</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/217</guid>
      <comments>https://gurtn.tistory.com/217#entry217comment</comments>
      <pubDate>Mon, 10 Jul 2023 02:46:28 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 영어 첫글자만 대문자로 바꾸기</title>
      <link>https://gurtn.tistory.com/216</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;asd.gif&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TTaHb/btsldQiji2T/bWHBWcc9E99HgvlLTukMd1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TTaHb/btsldQiji2T/bWHBWcc9E99HgvlLTukMd1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TTaHb/btsldQiji2T/bWHBWcc9E99HgvlLTukMd1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/TTaHb/btsldQiji2T/bWHBWcc9E99HgvlLTukMd1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;445&quot; height=&quot;296&quot; data-filename=&quot;asd.gif&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드예제&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/GRwjjqe?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;383.890625&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt; See the Pen &amp;amp;amp;lt;a href=&quot;https://codepen.io/hyukson/pen/GRwjjqe&quot;&amp;amp;amp;gt; Untitled&amp;amp;amp;lt;/a&amp;amp;amp;gt; by hyukson (&amp;amp;amp;lt;a href=&quot;https://codepen.io/hyukson&quot;&amp;amp;amp;gt;@hyukson&amp;amp;amp;lt;/a&amp;amp;amp;gt;) on &amp;amp;amp;lt;a href=&quot;https://codepen.io&quot;&amp;amp;amp;gt;CodePen&amp;amp;amp;lt;/a&amp;amp;amp;gt;. &lt;/iframe&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function toCapitalize(str) {
&amp;nbsp;&amp;nbsp;return str.replace(/\b\w/g, (match) =&amp;gt; match.toUpperCase());
}

// : 사용예시
toCapitalize('hello world');
// 'Hello World'&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드풀이&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;'ABC'.replace(/\b\w/g, '');
// 'BC'&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\b (word boundary) 단어의 시작 또는 끝에서 일치 항목 위치를 감지합니다.&lt;/li&gt;
&lt;li&gt;\w (word character) 한글, 영어, 숫자등의 문자를 의미합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;두 정규식을 같이 사용해 주면 첫 번째에 위치한 [문자]를 의미합니다.&lt;/blockquote&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;'hello world'.replace(/\b\w/g, (match) =&amp;gt; match.toUpperCase());
// 'Hello World'&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;띄어쓰기, 특수문자 등으로 구분된 첫 번째 문자를 모두 감지해 줍니다.&lt;/li&gt;
&lt;li&gt;String.toUpperCase() 메서드를 이용해서 감지한 첫 번째 문자를 대문자로 변경해 줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;제일 첫번째 단어만 대문자로 변경하길 원한다면, 정규식에서 g(global)을 제거해주시면 됩니다. [ /\b\w/, ... ]&lt;/blockquote&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>대문자</category>
      <category>바꾸기</category>
      <category>영어</category>
      <category>자바스크립트</category>
      <category>정규식</category>
      <category>첫글자</category>
      <category>첫문자</category>
      <category>첫번째</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/216</guid>
      <comments>https://gurtn.tistory.com/216#entry216comment</comments>
      <pubDate>Thu, 22 Jun 2023 03:15:04 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 길게 클릭(롱클릭) 이벤트 만들기</title>
      <link>https://gurtn.tistory.com/215</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;gasg.gif&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xQDVG/btsi2RRZEV2/xUcrdPoypFtuPmogfzX86k/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xQDVG/btsi2RRZEV2/xUcrdPoypFtuPmogfzX86k/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xQDVG/btsi2RRZEV2/xUcrdPoypFtuPmogfzX86k/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/xQDVG/btsi2RRZEV2/xUcrdPoypFtuPmogfzX86k/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;386&quot; height=&quot;290&quot; data-filename=&quot;gasg.gif&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;특정 요소를 정한 시간만큼 누르고 있는 행동을 Long-Click 또는 Long-Press라고 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/KKrKbmj?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;380&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/KKrKbmj&quot;&gt;
  Long Click&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1686154343925&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const onlongclick = ($target, duration, callback) =&amp;gt; {
  $target.onmousedown = () =&amp;gt; {
    const timer = setTimeout(callback, duration);
  
    $target.onmouseup = () =&amp;gt; {
      clearTimeout(timer);
    };
  };  
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마우스로 해당 타깃을 누르는 시점을 &lt;span class=&quot;code&quot;&gt;mousedown&lt;/span&gt; 이벤트로 감지해 주고 특정 시간만의 &lt;span class=&quot;code&quot;&gt;setTimeout&lt;/span&gt; 함수를 실행해 줍니다.&lt;/li&gt;
&lt;li&gt;만약 특정시간이 지나기 전에 마우스 클릭을 멈춘 시점을 &lt;span class=&quot;code&quot;&gt;mouseup&lt;/span&gt; 이벤트로 감지해 줍니다.&lt;/li&gt;
&lt;li&gt;시간이 모두 지날 때까지 &lt;span class=&quot;code&quot;&gt;mouseup&lt;/span&gt; 이벤트 감지가 안되면, &lt;span class=&quot;code&quot;&gt;callback 함수가&lt;/span&gt;&amp;nbsp;호출되고 아닐 시에는 해당 타이머를 종료시킵니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1686155183290&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 함수 사용예시
const $target = document.querySelector('.long-click');

onlongclick($target, 300, () =&amp;gt; {
  alert('Long Click');
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드처럼 특정요소와 duration(끝내는 시간), callback 함수를 인자 값으로 넘겨서 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;모바일 호환 문제&lt;/blockquote&gt;
&lt;pre id=&quot;code_1686154151484&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const onlongclick = ($target, duration, callback) =&amp;gt; {
  $target.onmousedown = () =&amp;gt; {
    const timer = setTimeout(callback, duration);
  
    $target.onmouseup = () =&amp;gt; {
      clearTimeout(timer);
    };
  };  
  
  $target.ontouchstart = () =&amp;gt; {
    const timer = setTimeout(callback, duration);
  
    $target.ontouchend = () =&amp;gt; {
      clearTimeout(timer);
    };
  };  
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mousedown, mouseup은 PC환경에서 사용되는 이벤트이며, 모바일에서는 touchstart, touchend 이벤트를 사용해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;모바일 환경에서는 마우스 포인터 대신에 터치라는 개념을 이용해서 클릭을 합니다.&lt;/blockquote&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>long-click</category>
      <category>press</category>
      <category>누르기</category>
      <category>롱클릭</category>
      <category>자바스크립트</category>
      <category>클릭</category>
      <category>클릭시간</category>
      <category>터치</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/215</guid>
      <comments>https://gurtn.tistory.com/215#entry215comment</comments>
      <pubDate>Thu, 8 Jun 2023 03:28:05 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 접속한 브라우저 체크하기</title>
      <link>https://gurtn.tistory.com/214</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예시코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/poxpYVL?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;400&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/poxpYVL&quot;&gt;
  Untitled&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;전체 코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1683359529919&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function getBrowser() {
  const browsers = [
    'Chrome', 'Opera',
    'WebTV', 'Whale',
    'Beonex', 'Chimera',
    'NetPositive', 'Phoenix',
    'Firefox', 'Safari',
    'SkipStone', 'Netscape', 'Mozilla',
  ];

  const userAgent = window.navigator.userAgent.toLowerCase();

  if (userAgent.includes(&quot;edg&quot;)) {
    return &quot;Edge&quot;;
  }

  if (userAgent.includes(&quot;trident&quot;) || userAgent.includes(&quot;msie&quot;)) {
    return &quot;Internet Explorer&quot;;
  }

  return browsers.find((browser) =&amp;gt; userAgent.includes(browser.toLowerCase())) || 'Other';
}

getBrowser();
// Chrome&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1683359731308&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 브라우저 모음
const browsers = [
  'Chrome', 'Opera',
  'WebTV', 'Whale',
  'Beonex', 'Chimera',
  'NetPositive', 'Phoenix',
  'Firefox', 'Safari',
  'SkipStone', 'Netscape',
  'Mozilla',
];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 이용되는 브라우저 데이터를 배열에 담아 미리 정의해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683359651092&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const userAgent = window.navigator.userAgent.toLowerCase();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code&quot;&gt;navigator.userAgent&lt;/span&gt; 정보에는 현재 접속한 브라우저에 대한 정보가 담겨있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCEF6t/btsd0vzHM0l/xBfzRnt5bMk354cPuXim51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCEF6t/btsd0vzHM0l/xBfzRnt5bMk354cPuXim51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCEF6t/btsd0vzHM0l/xBfzRnt5bMk354cPuXim51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCEF6t%2Fbtsd0vzHM0l%2FxBfzRnt5bMk354cPuXim51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;840&quot; height=&quot;49&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 정보에서 'Chrome'과 같은 특정한 단어가 포함되어 있는지를 찾는 방식을 사용해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683362014248&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (userAgent.includes(&quot;edg&quot;)) {
  return &quot;Edge&quot;;
}

if (userAgent.includes(&quot;trident&quot;) || userAgent.includes(&quot;msie&quot;)) {
  return &quot;Internet Explorer&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미리 선언해 둔 배열을 사용하기 전에, &lt;span class=&quot;code&quot;&gt;에지와&lt;/span&gt; &lt;span class=&quot;code&quot;&gt;익스플로러&lt;/span&gt;는 userAgent의 명칭과 다름으로 예외적으로 처리해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683362102418&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;return browsers.find((browser) =&amp;gt; userAgent.includes(browser.toLowerCase())) || 'Other';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저를 모아둔 배열에서 포함되어 있는 브라우저를 찾으면 해당 값을 반환해 주고, 찾지 못하면 'Other'을 반환해 줍니다.&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>Browser</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>브라우저</category>
      <category>웹</category>
      <category>자바스크립트</category>
      <category>정보</category>
      <category>종류</category>
      <category>체크</category>
      <category>확인</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/214</guid>
      <comments>https://gurtn.tistory.com/214#entry214comment</comments>
      <pubDate>Mon, 8 May 2023 04:41:35 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 숫자를 한글로 표시하기</title>
      <link>https://gurtn.tistory.com/213</link>
      <description>&lt;figure id=&quot;og_1681645496923&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다.&quot; data-og-description=&quot;한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/hyukson/hangul-util&quot; data-og-url=&quot;https://github.com/hyukson/hangul-util&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/n4oWN/hySi7Y8oNF/NCXnTdTpoTiIQxDnx8hthK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/hyukson/hangul-util&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/hyukson/hangul-util&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/n4oWN/hySi7Y8oNF/NCXnTdTpoTiIQxDnx8hthK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;'hangul-util' 라이브러리 코드를 기반으로 작성된 포스트입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681645541366&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;formatNumber(123456789);
// 1억 2345만 6789

formatNumberAll(123456789);
// 일억 이천삼백사십오만 육천칠백팔십구&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/vYVGbbO?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;400&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/vYVGbbO&quot;&gt;
  formatNumber&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4자리 대상 (전체코드)&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1681650770098&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const thousandUnits = [&quot;&quot;, &quot;만&quot;, &quot;억&quot;, &quot;조&quot;, &quot;경&quot;, &quot;해&quot;];

// 배열 쪼개기
function chunkAtEnd(value = &quot;&quot;, n = 1) {
  const result = [];

  for (let end = value.length; end &amp;gt; 0; end -= n) {
    result.push(value.substring(Math.max(0, end - n), end));
  }

  return result;
}

// 4자리씩 숫자로 변환
function formatNumber(number) {
  return chunkAtEnd(String(number), 4)
    .reduce((acc, item, index) =&amp;gt; {
      const unit = thousandUnits[index] ?? &quot;&quot;;

      if (!Number(item)) {
        return acc;
      }

      return `${Number(item)}${unit} ${acc}`;
    }, &quot;&quot;)
    .trim();
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 숫자 대상 (전체코드)&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1681650824509&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const numberUnits = [&quot;&quot;, &quot;일&quot;, &quot;이&quot;, &quot;삼&quot;, &quot;사&quot;, &quot;오&quot;, &quot;육&quot;, &quot;칠&quot;, &quot;팔&quot;, &quot;구&quot;];
const tenUnits = [&quot;&quot;, &quot;십&quot;, &quot;백&quot;, &quot;천&quot;];
const thousandUnits = [&quot;&quot;, &quot;만&quot;, &quot;억&quot;, &quot;조&quot;, &quot;경&quot;, &quot;해&quot;];

// 배열 쪼개기
function chunkAtEnd(value = &quot;&quot;, n = 1) {
  const result = [];

  for (let end = value.length; end &amp;gt; 0; end -= n) {
    result.push(value.substring(Math.max(0, end - n), end));
  }

// 모든 숫자 바꾸기
function formatNumberAll(number) {
  return chunkAtEnd(String(number), 4)
    .reduce((acc, item, index) =&amp;gt; {
      if (!Number(item)) {
        return acc;
      } 
    
      let numberUnit = &quot;&quot;;

      const zeroNum = item.padStart(4, &quot;0&quot;);

      for (let i = 0; i &amp;lt; 4; i++) {
        const number = Number(zeroNum[i]);

        if (number) {
          const unit = tenUnits[3 - i];

          numberUnit += `${unit &amp;amp;&amp;amp; number === 1 ? &quot;&quot; : numberUnits[number]}${unit}`;
        }
      }
    
      const thousandUnit = thousandUnits[index] ?? &quot;&quot;;

      return `${numberUnit}${thousandUnit} ${acc}`;
    }, &quot;&quot;)
    .trim();
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1681647768057&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 배열 쪼개기
function chunkAtEnd(value = &quot;&quot;, n = 1) {
  const result = [];

  for (let end = value.length; end &amp;gt; 0; end -= n) {
    result.push(value.substring(Math.max(0, end - n), end));
  }

  return result;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 숫자를 한글로 바꾸기 위해서는 4자리씩 나눠주는 작업이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681648428483&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chunkAtEnd('12345678', 4);
// ['5678', '1234']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;chunkAtEnd 함수를 제작하여 뒤에서부터 4자리씩 나눠줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681648278724&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const thousandUnits = [&quot;&quot;, &quot;만&quot;, &quot;억&quot;, &quot;조&quot;, &quot;경&quot;, &quot;해&quot;];

// 4자리씩 숫자로 변환
function formatNumber(number) {
  return chunkAtEnd(String(number), 4)
    .reduce((acc, item, index) =&amp;gt; {
      const unit = thousandUnits[index] ?? &quot;&quot;;

      if (!Number(item)) {
        return acc;
      }

      return `${Number(item)}${unit} ${acc}`;
    }, &quot;&quot;)
    .trim();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code&quot;&gt;chunkAtEnd()&lt;/span&gt; 함수로 4자리씩 나눔에 숫자에 차례대로 단위를 붙여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681652306044&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unit = thousandUnits[index] ?? &quot;&quot;;

if (!Number(item)) {
  return acc;
}

return `${Number(item)}${unit} ${acc}`;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4자리씩 숫자를 미리 나누었기 때문에 '', '만', '억', '조'... 단위가 될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;값이 0일 때는 뒤에 단위를 붙여주지 않습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;모든 숫자 대상&lt;/blockquote&gt;
&lt;pre id=&quot;code_1681652508541&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const numberUnits = [&quot;&quot;, &quot;일&quot;, &quot;이&quot;, &quot;삼&quot;, &quot;사&quot;, &quot;오&quot;, &quot;육&quot;, &quot;칠&quot;, &quot;팔&quot;, &quot;구&quot;];
const tenUnits = [&quot;&quot;, &quot;십&quot;, &quot;백&quot;, &quot;천&quot;];
const thousandUnits = [&quot;&quot;, &quot;만&quot;, &quot;억&quot;, &quot;조&quot;, &quot;경&quot;, &quot;해&quot;];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 숫자를 한글로 대체해야 하기에 한글 텍스트 배열을 미리 정의해 둡니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681652788873&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 모든 숫자 바꾸기
function formatNumberAll(number) {
  return chunkAtEnd(String(number), 4)
    .reduce((acc, item, index) =&amp;gt; {
      if (!Number(item)) {
        return acc;
      } 
    
      const zeroNum = item.padStart(4, &quot;0&quot;);
      let numberUnit = &quot;&quot;;

      for (let i = 0; i &amp;lt; 4; i++) {
        const number = Number(zeroNum[i]);

        if (number) {
          const unit = tenUnits[3 - i];

          numberUnit += `${
            unit &amp;amp;&amp;amp; number === 1 ? &quot;&quot; : numberUnits[number]
          }${unit}`;
        }
      }
    
      const thousandUnit = thousandUnits[index] ?? &quot;&quot;;

      return `${numberUnit}${thousandUnit} ${acc}`;
    }, &quot;&quot;)
    .trim();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4자리씩 나눈 숫자를 모두 한글로 바꾸기 위해서 다시 한번 반복문을 돌려줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681653293460&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const zeroNum = item.padStart(4, &quot;0&quot;);
let numberUnit = &quot;&quot;;

for (let i = 0; i &amp;lt; 4; i++) {
  const number = Number(zeroNum[i]);

  if (number) {
    const unit = tenUnits[3 - i];

    numberUnit += `${
      unit &amp;amp;&amp;amp; number === 1 ? &quot;&quot; : numberUnits[number]
    }${unit}`;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4개의 숫자를 잘라서 numberUnits 배열에 담긴 index에 맞게 한글을 매칭해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;padStart() 메서드를 통해서 무조건 4자리 숫자로 형식을 맞춰줍니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1682183235158&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const thousandUnit = thousandUnits[index] ?? &quot;&quot;;

return `${numberUnit}${thousandUnit} ${acc}`;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 숫자에 맞게 한글로 바꿔주고, 문자뒤에 알맞은 단위를 붙여주는 작업을 반복해 줍니다.&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>Hangul</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>Number</category>
      <category>금액</category>
      <category>바꾸기</category>
      <category>변환하기</category>
      <category>숫자</category>
      <category>자바스크립트</category>
      <category>한글로</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/213</guid>
      <comments>https://gurtn.tistory.com/213#entry213comment</comments>
      <pubDate>Mon, 24 Apr 2023 03:08:43 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 검색어 자동완성 기능</title>
      <link>https://gurtn.tistory.com/212</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;sdgsdg.gif&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7hmGG/btsagPistbW/AaK2ZTekzUikQwjVsAxY7k/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7hmGG/btsagPistbW/AaK2ZTekzUikQwjVsAxY7k/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7hmGG/btsagPistbW/AaK2ZTekzUikQwjVsAxY7k/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/7hmGG/btsagPistbW/AaK2ZTekzUikQwjVsAxY7k/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;526&quot; height=&quot;328&quot; data-filename=&quot;sdgsdg.gif&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;위와 같은 자동완성 기능은 우리가 흔히 접할 수 있는 UI 요소입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 초성검색 적용 버전 코드도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/ExRwpQB?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;410&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/ExRwpQB&quot;&gt;
  JS Autocomplete&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;HTML 태그 사용하기&lt;/blockquote&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;input type=&quot;text&quot; list=&quot;color-list&quot;&amp;gt;

&amp;lt;datalist id=&quot;color-list&quot;&amp;gt;
  &amp;lt;option value=&quot;빨간색&quot;&amp;gt;
  &amp;lt;option value=&quot;파란색&quot;&amp;gt;
  &amp;lt;option value=&quot;노란색&quot;&amp;gt;
  &amp;lt;option value=&quot;검정색&quot;&amp;gt;
&amp;lt;/datalist&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML에는 Input 자동완성 기능을 이용할 수 있도록 해주는, &lt;b&gt;datalist 태그와 list 속성&lt;/b&gt;이 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;하지만, 다양한 이벤트 설정이 어렵고 커스텀이 힘들다는 단점을 보완하기 위해서 자바스크립트로 구현해 보았습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1681136275771&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- 검색어 입력 폼 --&amp;gt;
&amp;lt;input type=&quot;text&quot; id=&quot;search&quot;&amp;gt;
&amp;lt;!-- 자동완성 단어 리스트 --&amp;gt;
&amp;lt;div class=&quot;autocomplete&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 검색어를 입력받을 Input 요소와 자동완성을 시켜줄 리스트 요소를 하나 생성해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681572610164&quot; class=&quot;css&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* active 클래스를 가진 요소에 대해 */
.autocomplete &amp;gt; div.active {
  background: #333;
  color: #eee;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선택된 요소에(active 클래스를 가진 요소) 선택 표시를 해주기 위해서 CSS 스타일을 추가해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681572602193&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 검색어 리스트
const dataList = [ &quot;빨간색&quot;, &quot;파란색&quot;, &quot;노란색&quot;, &quot;검정색&quot; ];

// 검색 입력 요소
const $search = document.querySelector(&quot;#search&quot;);
// 검색어 리스트 요소
const $autoComplete = document.querySelector(&quot;.autocomplete&quot;);

// 현재 가르키고 있는 검색어 순번
let nowIndex = 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동완성을 구현하기 위해서 필요 데이터를 선언해 줍니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;자동완성에 사용될 &lt;span class=&quot;code&quot;&gt;검색 단어 리스트&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;code&quot;&gt;입력 요소가&lt;/span&gt; 검색어를 보여줄 &lt;span class=&quot;code&quot;&gt;리스트 요소&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;리스트에서 커서를 가르쳐줄 &lt;span class=&quot;code&quot;&gt;현재 검색어 순번&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681574534186&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 단어 입력이 완료되었을 때
$search.onkeyup = (event) =&amp;gt; {
  const value = $search.value.trim();

  // 리스트 필터링
  const matchDataList = value
    ? dataList.filter((label) =&amp;gt; label.includes(value))
    : [];

  switch (event.keyCode) {
    // UP KEY
    case 38:
      nowIndex = Math.max(nowIndex - 1, 0);
      break;

    // DOWN KEY
    case 40:
      nowIndex = Math.min(nowIndex + 1, matchDataList.length - 1);
      break;

    // ENTER KEY
    case 13:
      document.querySelector(&quot;#search&quot;).value = matchDataList[nowIndex] || &quot;&quot;;
      // 초기화
      nowIndex = 0;
      matchDataList.length = 0;
      break;

    // 그외 다시 초기화
    default:
      nowIndex = 0;
      break;
  }
  
  // 리스트 보여주기
  showList(matchDataList, value, nowIndex);
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;keyup 이벤트를 통해서 입력값이 변했을 때 또는 &lt;span class=&quot;code&quot;&gt;Up&lt;/span&gt; &lt;span class=&quot;code&quot;&gt;Down&lt;/span&gt; &lt;span class=&quot;code&quot;&gt;Enter&lt;/span&gt; 키를 감지해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;자동완성 된 검색어를 선택하는 용도로 Up, Down, Enter키를 감지해 줍니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;tor.gif&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kJom6/btsak30H5IC/NdRcDWD2qfCx5ZFcK6W4U1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kJom6/btsak30H5IC/NdRcDWD2qfCx5ZFcK6W4U1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kJom6/btsak30H5IC/NdRcDWD2qfCx5ZFcK6W4U1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/kJom6/btsak30H5IC/NdRcDWD2qfCx5ZFcK6W4U1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;332&quot; data-filename=&quot;tor.gif&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681576657480&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 검색어 입력값
const value = $search.value.trim();

// 리스트 필터링
const matchDataList = value
  ? dataList.filter((label) =&amp;gt; label.includes(value))
  : [];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색어 데이터를 가져와주고 검색어에 해당하는 리스트로 필터링해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681576740905&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; switch (event.keyCode) {
    // UP KEY
    case 38:
      nowIndex = Math.max(nowIndex - 1, 0);
      break;

    // DOWN KEY
    case 40:
      nowIndex = Math.min(nowIndex + 1, matchDataList.length - 1);
      break;

    // ENTER KEY
    case 13:
      document.querySelector(&quot;#search&quot;).value = matchDataList[nowIndex] || &quot;&quot;;

      // 초기화
      nowIndex = 0;
      matchDataList.length = 0;
      break;
      
    // 그외 입력은 초기화
    default:
      nowIndex = 0;
      break;
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 키보드 이벤트에서 위쪽 화살표 키 또는 아래쪽 화살표 키를 눌렀음이 판별되면 아래와 같은 동작을 수행해 줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Up - &lt;span class=&quot;code&quot;&gt;nowIndex - 1&lt;/span&gt; 수식을 적용하지만 0보다 작아진다면 0으로 지정&lt;/li&gt;
&lt;li&gt;Down - &lt;span class=&quot;code&quot;&gt;nowIndex + 1&lt;/span&gt; 수식을 적용하지만 보여줄 리스트 개수를 넘으면 안 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681580631376&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    // ENTER KEY
    case 13:
      document.querySelector(&quot;#search&quot;).value = matchDataList[nowIndex] || &quot;&quot;;

      // 초기화
      nowIndex = 0;
      matchDataList.length = 0;
      break;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Enter키를 눌렀을 때는 선택한 검색어로 대체되도록 &lt;span class=&quot;code&quot;&gt;matchDataList&lt;/span&gt;배열에서 선택한 단어를 지정해 대체해 주고 기존 데이터는 초기화해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681577613154&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 리스트 보여주기
showList(matchDataList, value, nowIndex);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 작업이 끝나면 보여줄 리스트와 검색어, 현재 이동한 위치 인덱스를 인자값으로 보내줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681577857104&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const showList = (data, value, nowIndex) =&amp;gt; {
  // 정규식으로 변환
  const regex = new RegExp(`(${value})`, &quot;g&quot;);
  
  $autoComplete.innerHTML = data
    .map(
      (label, index) =&amp;gt; `
        &amp;lt;div class='${nowIndex === index ? &quot;active&quot; : &quot;&quot;}'&amp;gt;
          ${label.replace(regex, &quot;&amp;lt;mark&amp;gt;$1&amp;lt;/mark&amp;gt;&quot;)}
        &amp;lt;/div&amp;gt;
      `
    )
    .join(&quot;&quot;);
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 필터링된 데이터를 표시해 주는 작업만 남았습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;반복문을 돌려 현재 &lt;span class=&quot;code&quot;&gt;index&lt;/span&gt;가 &lt;span class=&quot;code&quot;&gt;nowIndex&lt;/span&gt;와 같으면 &quot;active&quot; 클래스를 부여해서 선택되었음을 표시해 줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681578676523&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;'빨간색'.replace(/(빨)/g, '&amp;lt;mark&amp;gt;$1&amp;lt;/mark&amp;gt;');
// &amp;lt;mark&amp;gt;빨&amp;lt;/mark&amp;gt;간색&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 label을 표시해 주는 과정에서 변환시켜 준 정규식을 사용하면 특정 부분에 마커 표시를 해줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;초성검색 적용 예시 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/poxyLex?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;415&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/poxyLex&quot;&gt;
  JS Autocomplete By ChoSung&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;초성검색 적용&lt;/blockquote&gt;
&lt;figure id=&quot;og_1681579775888&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JS] 초성검색 구현하기&quot; data-og-description=&quot;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다. 한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub. github.com 'ha&quot; data-og-host=&quot;gurtn.tistory.com&quot; data-og-source-url=&quot;https://gurtn.tistory.com/209&quot; data-og-url=&quot;https://gurtn.tistory.com/209&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/MptiT/hyShGV08NH/ZtSY0qpRSvGvb9vPDf5s4k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bmyX2j/hySi24dxZf/n428mmTFPXpRHLLBwM8Bbk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/209&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gurtn.tistory.com/209&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/MptiT/hyShGV08NH/ZtSY0qpRSvGvb9vPDf5s4k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bmyX2j/hySi24dxZf/n428mmTFPXpRHLLBwM8Bbk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JS] 초성검색 구현하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다. 한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub. github.com 'ha&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gurtn.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;위 포스트를 참고하여 'hangul-util' 라이브러리 또는 공유드린 모든 코드가 존재하는 상태여야 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초성검색을 위한 코드가 준비되었다면, &lt;b&gt;변경할 코드는 총 두 군데가&lt;/b&gt; 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681579853427&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 자동완성 필터링
const matchDataList = value
  ? dataList.filter((label) =&amp;gt; includeByCho(value, label))
  : [];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 keyup 이벤트를 적용시킨 코드에서 자동완성 필터링 코드를 &lt;span class=&quot;code&quot;&gt;includes()&lt;/span&gt; 대신에 &lt;span class=&quot;code&quot;&gt;incldueByCho()&lt;/span&gt; 함수로 대체해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681579991938&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const showList = (data, value, nowIndex) =&amp;gt; {
  // 초성 정규식으로 변환
  const regex = makeRegexByCho(value);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 두 번째로 정규식으로 바꿔주는 부분을 &lt;span class=&quot;code&quot;&gt;makeRegexByCho()&lt;/span&gt; 함수로 대체시켜 주면 초성검색을 적용시킨 자동완성 기능을 만들 수 있습니다.&lt;/p&gt;</description>
      <category>JavaScript/제작</category>
      <category>HTML</category>
      <category>input</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>검색</category>
      <category>검색어</category>
      <category>자동완성</category>
      <category>자바스크립트</category>
      <category>초성검색</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/212</guid>
      <comments>https://gurtn.tistory.com/212#entry212comment</comments>
      <pubDate>Mon, 17 Apr 2023 03:35:06 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 초성검색 구현하기</title>
      <link>https://gurtn.tistory.com/209</link>
      <description>&lt;figure id=&quot;og_1681139962808&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다.&quot; data-og-description=&quot;한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/hyukson/hangul-util&quot; data-og-url=&quot;https://github.com/hyukson/hangul-util&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhjLbd/hySeUFsmDj/SSKeIKBRlZdDI3Zu21jjE0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/hyukson/hangul-util&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/hyukson/hangul-util&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhjLbd/hySeUFsmDj/SSKeIKBRlZdDI3Zu21jjE0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;'hangul-util' 코드와 '한글 초성, 중성, 종성 구하기' 포스트를 기반으로 작성된 글입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681226288711&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;includeByCho('ㄱ', '귤')
// true

includeByCho('ㅅ과', '사과')
// true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 예시&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/BaqNdOp?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;458&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/BaqNdOp&quot;&gt;
  includeByCho&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1681142097153&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const CHO_HANGUL = [
  'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ',
  'ㄹ', 'ㅁ', 'ㅂ','ㅃ', 'ㅅ',
  'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ',
  'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ',
];

const HANGUL_START_CHARCODE = &quot;가&quot;.charCodeAt();

const CHO_PERIOD = Math.floor(&quot;까&quot;.charCodeAt() - &quot;가&quot;.charCodeAt());
const JUNG_PERIOD = Math.floor(&quot;개&quot;.charCodeAt() - &quot;가&quot;.charCodeAt());

function combine(cho, jung, jong) {
  return String.fromCharCode(
    HANGUL_START_CHARCODE + cho * CHO_PERIOD + jung * JUNG_PERIOD + jong
  );
}

function makeRegexByCho(search = &quot;&quot;) {
  const regex = CHO_HANGUL.reduce(
    (acc, cho, index) =&amp;gt;
      acc.replace(
        new RegExp(cho, &quot;g&quot;),
        `[${combine(index, 0, 0)}-${combine(index + 1, 0, -1)}]`
      ),
    search
  );

  return new RegExp(`(${regex})`, &quot;g&quot;);
}

function includeByCho(search, targetWord) {
  return makeRegexByCho(search).test(targetWord);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1681142181158&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;includeByCho('가ㅂ', '가방');
// true

includeByCho('ㅅ방', '가방');
// false

includeByCho('ㅂ', '가방');
// true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1681224621063&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 초성배열
const CHO_HANGUL = [
  'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ',
  'ㄹ', 'ㅁ', 'ㅂ','ㅃ', 'ㅅ',
  'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ',
  'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ',
];

// 한글 시작 유니코드
const HANGUL_START_CHARCODE = &quot;가&quot;.charCodeAt();

// 초성, 종성 주기
const CHO_PERIOD = Math.floor(&quot;까&quot;.charCodeAt() - &quot;가&quot;.charCodeAt());
const JUNG_PERIOD = Math.floor(&quot;개&quot;.charCodeAt() - &quot;가&quot;.charCodeAt());

// 한글 결합 함수
function combine(cho, jung, jong) {
  return String.fromCharCode(
    HANGUL_START_CHARCODE + cho * CHO_PERIOD + jung * JUNG_PERIOD + jong
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초성검색을 구현하기 위한 최소한의 정보와 함수를 선언해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681224732209&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 초성검색
function makeRegexByCho(search = &quot;&quot;) {
  const regex = CHO_HANGUL.reduce(
    (acc, cho, index) =&amp;gt;
      acc.replace(
        new RegExp(cho, &quot;g&quot;),
        `[${combine(index, 0, 0)}-${combine(index + 1, 0, -1)}]` // [시작-끝] -&amp;gt; [가-깋]
      ),
    search
  );

  return new RegExp(`(${regex})`, &quot;g&quot;);
}

makeRegexByCho('ㄱ');
// /[가-깋]/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초성검색을&amp;nbsp;위해서는&amp;nbsp;'ㅅㄱ'를&amp;nbsp;&lt;span class=&quot;not-font code&quot;&gt;'/[사-싷][가-깋]/'&lt;/span&gt;&amp;nbsp;형태의&amp;nbsp;정규식을&amp;nbsp;생성해&amp;nbsp;주는&amp;nbsp;작업이&amp;nbsp;필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;각 초성의 시작 글자과 끝은 정해져 있으며, 예시로 초성 &amp;lsquo;ㄱ&amp;rsquo; 은 (&lt;span class=&quot;not-font&quot;&gt;가~깋&lt;/span&gt;)까지의 모든 범위에 해당하며, /[&lt;span class=&quot;not-font&quot;&gt;가-깋&lt;/span&gt;]/ 정규식으로 탐색할 수 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;makeRegexByCho() 상세풀이&lt;/blockquote&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1681225244223&quot; class=&quot;awk&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;'ㄱ밥'.replace(/ㄱ/g, '[가-깋]');
// '[가-깋]밥'

'김ㅂ'.replace(/ㅂ/g, '[바-빟]');
// '김[바-빟]'

'ㅅ방ㅅ'.replace(/ㅅ/g, '[사-싷]');
// '[사-싷]방[사-싷]'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;replace() 메서드를 이용하면, 특정 초성을 모두 /[글자 시작 - 글자 끝]/ 정규식으로 바꿀 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681225255896&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const regex = CHO_HANGUL.reduce(
  (acc, cho, index) =&amp;gt;
    acc.replace(
      new RegExp(cho, &quot;g&quot;),
      `[${combine(index, 0, 0)}-${combine(index + 1, 0, -1)}]`
    ),
  search
);

return new RegExp(`(${regex})`, &quot;g&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reduce() 메서드를 이용해서 초기값을 검색어로 지정해 주고, 초성배열(CHO_HANGUL)을 순회하여 ㄱ~ㅎ까지의 모든 초성을 검색어에서 찾아 문자조합 범위 정규식( /[시작-끝]/ )으로 변환시켜 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;combine() 함수로 다음초성에서 - 1은 초성 끝 글자. (&amp;rsquo;다&amp;rsquo; - 1 &amp;rarr; &amp;lsquo;&lt;span class=&quot;not-font&quot;&gt;닣&lt;/span&gt;&amp;rsquo;)&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681225456917&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 초성검색 (검색어, 비교할 단어)
function includeByCho(search, targetWord) {
  return makeRegexByCho(search).test(targetWord);
}

includeByCho('ㄱ', '귤');
// true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정규식을 이용해서 문자가 조건에 일치한 지 검증하는 과정만이 남았습니다. 이는 구현된 정규식에 &lt;span class=&quot;code&quot;&gt;regex.test()&lt;/span&gt; 메서드를 사용한다면, 초성검색 기능을 완성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/207&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gurtn.tistory.com/207&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1681226000606&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JS] 한글 초성, 중성, 종성 구하기&quot; data-og-description=&quot;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다. 한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub. github.com 'ha&quot; data-og-host=&quot;gurtn.tistory.com&quot; data-og-source-url=&quot;https://gurtn.tistory.com/207&quot; data-og-url=&quot;https://gurtn.tistory.com/207&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gePh3/hySe76X9Ig/d3LUburPGCjVh5J7BQcND0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bDTr6I/hySeY9ZCkK/VZVGaaEP4xMVqCkXoi5w51/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/207&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gurtn.tistory.com/207&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gePh3/hySe76X9Ig/d3LUburPGCjVh5J7BQcND0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bDTr6I/hySeY9ZCkK/VZVGaaEP4xMVqCkXoi5w51/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JS] 한글 초성, 중성, 종성 구하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다. 한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub. github.com 'ha&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gurtn.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>검색</category>
      <category>자동완성</category>
      <category>자바스크립트</category>
      <category>초성</category>
      <category>초성검색</category>
      <category>포함</category>
      <category>한글</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/209</guid>
      <comments>https://gurtn.tistory.com/209#entry209comment</comments>
      <pubDate>Wed, 12 Apr 2023 04:04:26 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 배열 순서 바꾸기 (맞교환)</title>
      <link>https://gurtn.tistory.com/208</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;splice() 메서드에 대해서&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678546641956&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Array.splice(시작위치, 삭제할 아이템 개수, 추가할 아이템)

const array = [1, 2, 3];

array.splice(0, 1);
// [1]

array.splice(0, 0, 5);
// []

console.log(array);
// [5, 2, 3]&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;splice() 메서드의&lt;span&gt;&amp;nbsp;&lt;/span&gt;두 번째&lt;span&gt;&amp;nbsp;&lt;/span&gt;인자는&lt;span&gt;&amp;nbsp;&lt;/span&gt;삭제할&lt;span&gt;&amp;nbsp;&lt;/span&gt;개수입니다. (1은 fromIndex 위치의 value 값)&lt;/li&gt;
&lt;li&gt;두 번째&lt;span&gt;&amp;nbsp;&lt;/span&gt;인자의 값이 0일 시, value 값이 제거되지 않습니다.&lt;/li&gt;
&lt;li&gt;세 번째&lt;span&gt;&amp;nbsp;&lt;/span&gt;인자 값에는 배열에 추가할 요소입니다. (없을 시 제거만 진행)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Array.splice() 메서드는 원본배열에 직접적인 관여를 합니다. (참조)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;위치 이동하기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678545971350&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function moveValue(array, fromIndex, toIndex) {
  const item = array.splice(fromIndex, 1)[0];
  array.splice(toIndex, 0, item);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code&quot;&gt;fromIndex&lt;/span&gt;의 위치의 값을 제거해 주고, &lt;span class=&quot;code&quot;&gt;toIndex&lt;/span&gt;위치에 새로운 값을 추가해 주는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678546609416&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [0, '!', 2, 3, 4];

moveValue(array, 1, 3);

console.log(array);
// [0, 2, 3, '!', 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;맞교환 (서로 이동)&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678545579317&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function switchValues(arr, index1, index2) {
  [arr[index1], arr[index2]] = [arr[index2], arr[index1]];
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열에서 index1, index2 값을 추출하고 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;구조 분해 할당 구문을 사용하여&lt;span&gt; &lt;span style=&quot;background-color: #f7f7f8; color: #374151; text-align: start;&quot;&gt; 두 인덱스의 값을 역순으로 새 배열에 할당해 줍니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678546058211&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function switchValues(arr, index1, index2) {
  const tmp = arr[index1];
  arr[index1] = arr[index2];
  arr[index2] = tmp;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 기능을 하는 코드이지만, 구조 분해 할당 구문을 사용하지 않고 구현한 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678545668166&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [0, '!', 2, 3, '?'];

switchValues(array, 1, 4);

console.log(array);
// [0, '?', 2, 3, '!']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678546476558&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Array.prototype.splice() - JavaScript | MDN&quot; data-og-description=&quot;splice() 메서드는 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경합니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bMSLhP/hyRTR3Ul9p/0ti85P7uMbEGYTSiT8KgWk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bMSLhP/hyRTR3Ul9p/0ti85P7uMbEGYTSiT8KgWk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Array.prototype.splice() - JavaScript | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;splice() 메서드는 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678546490981&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;구조 분해 할당 - JavaScript | MDN&quot; data-og-description=&quot;구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/g9Dol/hyRTSaNzRD/IjmKVGOdKQClJRBlyqsMnK/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/g9Dol/hyRTSaNzRD/IjmKVGOdKQClJRBlyqsMnK/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;구조 분해 할당 - JavaScript | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>array</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>바꾸기</category>
      <category>배열</category>
      <category>변경</category>
      <category>순서</category>
      <category>위치</category>
      <category>이동</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/208</guid>
      <comments>https://gurtn.tistory.com/208#entry208comment</comments>
      <pubDate>Tue, 11 Apr 2023 03:56:02 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 한글 초성, 중성, 종성 구하기</title>
      <link>https://gurtn.tistory.com/207</link>
      <description>&lt;figure id=&quot;og_1681132857957&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다.&quot; data-og-description=&quot;한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/hyukson/hangul-util&quot; data-og-url=&quot;https://github.com/hyukson/hangul-util&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhjLbd/hySeUFsmDj/SSKeIKBRlZdDI3Zu21jjE0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/hyukson/hangul-util&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/hyukson/hangul-util&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhjLbd/hySeUFsmDj/SSKeIKBRlZdDI3Zu21jjE0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;'hangul-util' 라이브러리 코드를 기반으로 작성된 포스트입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681046108552&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;divideHangul('사과')
// ['ㅅ', 'ㅏ', 'ㄱ', 'ㅗ', 'ㅏ']

divideHangul(&quot;값싼&quot;);
// ['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ', 'ㅆ', 'ㅏ', 'ㄴ']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 예시&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/qBJEGjZ?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;360&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/qBJEGjZ&quot;&gt;
  Untitled&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(전체코드 67줄)&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1681046674223&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const CHO_HANGUL = [
  'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ',
  'ㄹ', 'ㅁ', 'ㅂ','ㅃ', 'ㅅ',
  'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ',
  'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ',
];
const JUNG_HANGUL = [
  'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 
  'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 
  'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 
  'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ',
];
const JONG_HANGUL = [
  '', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 
  'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 
  'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 
  'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ','ㅎ',
];

const CHO_PERIOD = Math.floor(&quot;까&quot;.charCodeAt(0) - &quot;가&quot;.charCodeAt(0)); // 588 ( 28 * 21 )
const JUNG_PERIOD = Math.floor(&quot;개&quot;.charCodeAt(0) - &quot;가&quot;.charCodeAt(0)); // 28

const HANGUL_START_CHARCODE = &quot;가&quot;.charCodeAt(0);
const HANGUL_END_CHARCODE = &quot;힣&quot;.charCodeAt(0);

function isHangul(charCode) {
  return HANGUL_START_CHARCODE &amp;lt;= charCode &amp;amp;&amp;amp; charCode &amp;lt;= HANGUL_END_CHARCODE;
}

function divideHangul(letter) {
  const letterCode = letter.charCodeAt(0);

  if (!isHangul(letterCode)) {
    return letter;
  }

  const charCode = letterCode - HANGUL_START_CHARCODE;

  const choIndex = Math.floor(charCode / CHO_PERIOD);
  const jungIndex = Math.floor((charCode % CHO_PERIOD) / JUNG_PERIOD);
  const jongIndex = charCode % JUNG_PERIOD;

  return {
    cho: CHO_HANGUL[choIndex],
    jung: JUNG_HANGUL[jungIndex],
    jong: JONG_HANGUL[jongIndex],
  };
}

function combine(cho, jung, jong) {
  const hangulCode =
    HANGUL_START_CHARCODE + cho * CHO_PERIOD + jung * JUNG_PERIOD + jong;

  if (!isHangul(hangulCode)) {
    return &quot;&quot;;
  }

  return String.fromCharCode(hangulCode);
}

function combineHangul(cho = &quot;&quot;, jung = &quot;&quot;, jong = &quot;&quot;) {
  const choIndex = CHO_HANGUL.indexOf(cho);
  const jungIndex = JUNG_HANGUL.indexOf(jung);
  const jongIndex = JONG_HANGUL.indexOf(jong);

  return combine(choIndex, jungIndex, jongIndex);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한글의 초성(19), 중성(21), 종성(28) 조합의 배열을 미리 정의해 줍니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// 초성(19개)
const CHO_HANGUL = [
  'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ',
  'ㄹ', 'ㅁ', 'ㅂ','ㅃ', 'ㅅ',
  'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ',
  'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ',
];
// 중성(21개)
const JUNG_HANGUL = [
  'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 
  'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 
  'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 
  'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ',
];
// 종성(28개)
const JONG_HANGUL = [
  '', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 
  'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 
  'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 
  'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ','ㅎ',
];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니코드 한글은 44032부터 초성 19개, 중성 21개, 종성 28개로 이루어지고 이를 조합한 &lt;b&gt;11,172개의 문자&lt;/b&gt;가 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 미리 초성, 중성, 종성으로 구성된 배열을 만드는 이유는 유니코드만으로는 초성, 중성, 종성을 구분하기 어렵기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;유니코드는 초성, 중성 순서가 아닌 자음, 모음 순서로 구성되어 있기 때문입니다. (ㄱ, ㄲ, ㄴ) X, (ㄱ, ㄲ, ㄳ) O&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;(유니코드 확인해 보기)&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1681045363916&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const charCode = 'ㄱ'.charCodeAt(); // 12593

// 원하는 데이터(초성) [ ㄱ, ㄲ, ㄴ, ㄷ, ㄸ ]
// 실제 데이터(종성) [ ㄱ, ㄲ, ㄳ, ㄴ, ㄵ ]

String.fromCharCode(charCode); 
// ㄱ

String.fromCharCode(charCode + 1); 
// ㄲ

String.fromCharCode(charCode + 2);
// ㄳ

String.fromCharCode(charCode + 3); 
// ㄴ

String.fromCharCode(charCode + 4);
// ㄵ&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const CHO_PERIOD = Math.floor('까'.charCodeAt(0) - '가'.charCodeAt(0)); // 588 ( 28 * 21 )
const JUNG_PERIOD = Math.floor('개'.charCodeAt(0) - '가'.charCodeAt(0)); // 28&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 글자를 분리하기 위해서, 한글 유니코드의 패턴을 먼저 알아야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 초성 규칙&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초성 위치는 첫 조합 문자 &amp;lsquo;가&amp;rsquo;의 위치부터 &lt;b&gt;589 간격&lt;/b&gt;마다 다음 초성으로 조합한 문자가 위치합니다. (가 + 589 &amp;rarr; 나)&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. 중성 규칙&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중성은 각 초성 조합에 &lt;b&gt;29개의 모음&lt;/b&gt; 값이 존재합니다. 초성 조합이 바뀔 때마다 다시 처음부터 반복되기 때문에 초성 값을 빼줘야 합니다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. 종성 규칙&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;종성은 &amp;lsquo;ㄱ&amp;rsquo;의 위치부터 &amp;lsquo;ㅎ&amp;rsquo;까지, 종성이 없는 경우를 포함해 총 &lt;b&gt;28개 값&lt;/b&gt;이 존재합니다. (초성은 19개)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;한글 검증 코드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const HANGUL_START_CHARCODE = '가'.charCodeAt(0);
const HANGUL_END_CHARCODE = '힣'.charCodeAt(0);

// 조합 된 글자인지 체크 (가 ~ 힣 사이)
function isHangul(charCode) { 
  return HANGUL_START_CHARCODE &amp;lt;= charCode &amp;amp;&amp;amp; charCode &amp;lt;= HANGUL_END_CHARCODE;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 제작할 분리, 조합 함수에서 사용할 isHangul 함수는 &amp;lsquo;가&amp;rsquo;(첫 글자) ~ &amp;lsquo;힣&amp;rsquo;(끝글자) 범위 안에 존재하는지 체크하는 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lsquo;ㄱ&amp;rsquo;와 &amp;lsquo;가&amp;rsquo;의 유니코드 시작 위치가 전혀 다르고, 초성구간은 위 수식규칙이 다르기에 예외처리를 따로 해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;글자 분리&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function divideHangul(letter) {
  const letterCode = letter.charCodeAt(0);

  if (!isHangul(letterCode)) {
    return letter;
  }

  const charCode = letterCode - HANGUL_START_CHARCODE;

  const choIndex = Math.floor(charCode / CHO_PERIOD);
  const jungIndex = Math.floor((charCode % CHO_PERIOD) / JUNG_PERIOD);
  const jongIndex = charCode % JUNG_PERIOD;

  return {
    cho: CHO_HANGUL[choIndex],
    jung: JUNG_HANGUL[jungIndex],
    jong: JONG_HANGUL[jongIndex],
  };
}

console.log(divideHangul(&quot;김&quot;));
// { &quot;cho&quot;: &quot;ㄱ&quot;, &quot;jung&quot;: &quot;ㅣ&quot;, &quot;jong&quot;: &quot;ㅁ&quot; }

console.log(divideHangul(&quot;ㄱ&quot;));
// ㄱ&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미리 만들어둔 각 조합의 배열에서 문자를 구하기 위한 Index를 구해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 초성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초성은 589의 간격으로 초성 조합이 바뀝니다. 그러므로 588을 나눠준 값으로 순번을 구해줍니다. (588 나누기)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 중성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중성은 초성 조합이 바뀔 때마다 29개의 모음이 존재하니, 초성 위치를 제외한 상태에서 28을 나눠 순번을 구해줍니다. (28 나누기)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 종성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종성은 단순히 &amp;lsquo;ㄱ&amp;rsquo;와 &amp;lsquo;ㅎ&amp;rsquo;(28개) 위치 사이의 값이므로, 순번을 28의 간격의 나머지로 구해줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;글자 결합&lt;/blockquote&gt;
&lt;pre id=&quot;code_1681044466481&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 44032(가) + ((초성 &amp;times; 21) + 중성) &amp;times; 28 + 종성
function combine(cho, jung, jong) {
  const hangulCode = HANGUL_START_CHARCODE + cho * CHO_PERIOD + jung * JUNG_PERIOD + jong;
	
  if (!isHangul(hangulCode)) {
    return '';
  }

  return String.fromCharCode(hangulCode);
}

console.log(combine(0, 20, 16));
// 김

console.log(combine(-1, 20, 16));
// ''&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 초성, 중성, 종성을 구한 방식을 반대로 한 수식으로 위치를 구해주면 문자를 합칠 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(초성의 순번 * 초성 주기) + (중성의 순번 * 중성의 주기) + 종성 순번 의 수식을 &amp;lsquo;가&amp;rsquo;의 위치에 더해주면 합쳐진 문자의 위치를 구할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function combineHangul(cho = '', jung = '', jong = '') {
  const choIndex = CHO_HANGUL.indexOf(cho);
  const jungIndex = JUNG_HANGUL.indexOf(jung);
  const jongIndex = JONG_HANGUL.indexOf(jong);

  return combine(choIndex, jungIndex, jongIndex);
}

const hangul = { cho: 'ㄱ', jung: 'ㅣ', jong: 'ㅁ' };
// const hangul = divideHangul('김');

console.log(combineHangul(hangul.cho, hangul.jung, hangul.jong));
// 김&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 미리 선언해 둔 &lt;b&gt;초성, 중성, 종성 배열을 이용해서 순번&lt;/b&gt;을 각각 찾아서 assemble() 함수에 넘겨주면, Index가 아닌 문자 결합 기능을 구현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;단어 분해, 결합&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// 단어 분해
const divideLetter = &quot;수박&quot;
  .split(&quot;&quot;)
  .map((letter) =&amp;gt; divideHangul(letter));

console.log(divideLetter);
/* 
  [ 
    { &quot;cho&quot;: &quot;ㅅ&quot;, &quot;jung&quot;: &quot;ㅜ&quot;, &quot;jong&quot;: &quot;&quot; },
    { &quot;cho&quot;: &quot;ㅂ&quot;, &quot;jung&quot;: &quot;ㅏ&quot;, &quot;jong&quot;: &quot;ㄱ&quot; }
  ]
*/

// 단어 결합
const combineLetter = divideLetter
  .map((hangul) =&amp;gt; combineHangul(hangul.cho, hangul.jung, hangul.jong))
  .join(&quot;&quot;);

console.log(combineLetter);
// 수박&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 제작한 함수들은 모두 &amp;lsquo;한 글자&amp;rsquo;만 파싱 되도록 구현됐습니다. 단어 또는 문장을 파싱 하기 위해서는 문자를 쪼개서 하나씩 바꿔주는 방법을 사용해 줍니다.&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>Hangul</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>분리</category>
      <category>자바스크립트</category>
      <category>종성</category>
      <category>중성</category>
      <category>초성</category>
      <category>한글</category>
      <category>합치기</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/207</guid>
      <comments>https://gurtn.tistory.com/207#entry207comment</comments>
      <pubDate>Mon, 10 Apr 2023 03:37:12 +0900</pubDate>
    </item>
    <item>
      <title>[JS] Form Submit 동작 막기 (ft. Button Submit)</title>
      <link>https://gurtn.tistory.com/206</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;주로 submit 동작에는 Form 데이터를 서버에 전송하고, &amp;lt;a href=&amp;rdquo;&amp;rdquo;&amp;gt;와 같이 페이지 이동이 발생합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/jOvLgLQ?default-tab=html%2Cresult&quot; width=&quot;100%;&quot; height=&quot;370&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/jOvLgLQ&quot;&gt;
  Stop form Submission&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;HTML 코드 (Basic)&lt;/blockquote&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;form id=&quot;form&quot;&amp;gt;
  &amp;lt;input type=&quot;text&quot; name=&quot;name&quot; id=&quot;name&quot; /&amp;gt;

  &amp;lt;button&amp;gt;로그인&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1. 모든 submit 동작 막기 (JavaScript)&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const $form = document.querySelecotr('form');

$form.addEventListener(&quot;submit&quot;, (event) =&amp;gt; {
  // 동작(이벤트)을 실행하지 못하게 막는 메서드입니다.
  event.preventDefault();

  console.log(event.target);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;event.preventDefault()&amp;rdquo;는 브라우저에 동작하는 이벤트를 실행하지 못하게 막아주는 메서드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;해당 메서드로 submit 이벤트 감지는 되지만, Form을 전송하는 등의 동작은 멈추게 됩니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;2. button submit 동작만 막기 (HTML)&lt;/blockquote&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;&amp;lt;button type=&quot;button&quot;&amp;gt;로그인&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;button의 기본 type은 &amp;ldquo;submit&amp;rdquo;입니다. 폼 태그 안에 존재하는 버튼은 클릭 시 폼 데이터를 전송하는 시작점 역할을 가집니다. (Enter 등...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 해당 방법은 &amp;ldquo;Enter&amp;rdquo;와 같은 기타 submit 동작은 방지하지 못합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678192766318&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Event.preventDefault() - Web APIs | MDN&quot; data-og-description=&quot;The preventDefault() method of the Event interface tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault&quot; data-og-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bkKlcH/hyRRHmL929/XBgDkifoS8A2P8HO6CNdJ1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bkKlcH/hyRRHmL929/XBgDkifoS8A2P8HO6CNdJ1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Event.preventDefault() - Web APIs | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The preventDefault() method of the Event interface tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>JavaScript/코드</category>
      <category>form</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>submit</category>
      <category>금지</category>
      <category>동작</category>
      <category>막기</category>
      <category>자바스크립트</category>
      <category>전송</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/206</guid>
      <comments>https://gurtn.tistory.com/206#entry206comment</comments>
      <pubDate>Fri, 10 Mar 2023 02:49:58 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 객체 value 값으로 정렬 시키기</title>
      <link>https://gurtn.tistory.com/205</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;객체를 value 값을 기준으로 sort() 시켜 줄 수 있게 데이터를 변환시켜 주는 과정이 필요합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const fruits = {
  Apple: 4000,
  Banana: 10000,
  Cherry: 800,
  Kiwi: 7000,
};

const object = Object.fromEntries(
  Object.entries(fruits).sort((a, b) =&amp;gt; a[1] - b[1])
);

console.log(object);
// { &quot;Apple&quot;: 4000, &quot;Banana&quot;: 10000, &quot;Cherry&quot;: 800, &quot;Kiwi&quot;: 7000 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sort() 메서드를 이용하기 위해서 배열로 변환시킨 후, 다시 객체로 만들어 주는 방법을 거쳐줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678191911257&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const fruits = {
  Apple: 4000,
  Banana: 10000,
};

// 객체 -&amp;gt; 배열로 [key, value]
const entries = Object.entries(fruits)
// [ ['Apple', 4000], ['Banana', 10000] ];


// 1. 
const object = Object.fromEntries(entries);

// 2.
const object = array.reduce((acc, value, index) =&amp;gt; {
  return { ...acc, [value[0]]: value[1] };
}, {});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 &lt;b&gt;sort() 메서드를 사용하기 위해서 풀어준 배열 데이터&lt;/b&gt;를 다시 객체로 만들어주는 방법을 사용해 원래 형식으로 돌려줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;key 값을 기준으로 정렬&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678369320487&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const name = {
  홍씨: 4000,
  김씨: 10000,
  창씨: 800,
  박씨: 7000,
};

const object = Object.fromEntries(
  // 첫번째 값은 Key, 두번째 값은 Value
  Object.entries(name).sort((a, b) =&amp;gt; a[0] &amp;gt; b[0] ? 1 : -1)
);

console.log(object);
// { &quot;김씨&quot;: 10000, &quot;박씨&quot;: 7000, &quot;창씨&quot;: 800, &quot;홍씨&quot;: 4000 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;key 값을 기준으로 정렬하기 위해서는 첫번째 값(key)을 기준으로 비교해주는 코드로 정렬 시켜줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/204&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gurtn.tistory.com/204&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678368946122&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JS] 배열을 객체로 변환 (Array to Object)&quot; data-og-description=&quot;Object.fromEntries() 메서드 const entries = [ ['first', 'apple'], ['second', 7], ]; const object = Object.fromEntries(entries); console.log(object); // {'first': 'apple', 'second': 7} 다음과 같이 key-value 형식으로 갖추어진 배열은 Object&quot; data-og-host=&quot;gurtn.tistory.com&quot; data-og-source-url=&quot;https://gurtn.tistory.com/204&quot; data-og-url=&quot;https://gurtn.tistory.com/204&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DZL4L/hyRSGBytdM/HlChHOJTPenajqaff6Mqck/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cZpOad/hyRSQYuhTz/qYj3w2uzQ5QO5KzUQUjKJK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/204&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gurtn.tistory.com/204&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DZL4L/hyRSGBytdM/HlChHOJTPenajqaff6Mqck/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cZpOad/hyRSQYuhTz/qYj3w2uzQ5QO5KzUQUjKJK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JS] 배열을 객체로 변환 (Array to Object)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Object.fromEntries() 메서드 const entries = [ ['first', 'apple'], ['second', 7], ]; const object = Object.fromEntries(entries); console.log(object); // {'first': 'apple', 'second': 7} 다음과 같이 key-value 형식으로 갖추어진 배열은 Object&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gurtn.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>object</category>
      <category>react</category>
      <category>sort</category>
      <category>Value</category>
      <category>값</category>
      <category>객체</category>
      <category>자바스크립트</category>
      <category>정렬</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/205</guid>
      <comments>https://gurtn.tistory.com/205#entry205comment</comments>
      <pubDate>Thu, 9 Mar 2023 03:32:18 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 배열을 객체로 변환 (Array to Object)</title>
      <link>https://gurtn.tistory.com/204</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Object.fromEntries() 메서드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const entries = [
  ['first', 'apple'],
  ['second', 7],
];

const object = Object.fromEntries(entries);

console.log(object);
// {'first': 'apple', 'second': 7}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 key-value 형식으로 갖추어진 배열은 Object.fromEntries() 메서드를 사용하면 객체로 변환하여 반환해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;forEach(), reduce() 메서드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const array = ['apple', 'banana', 'mango'];

// 1.
const object = {};

array.forEach((value, index) =&amp;gt; {
  object[index] = value;
});

console.log(object);
// {'0': 'apple', '1': 'banana', '2': 'mango'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 key-value 형식이 아닌 value 값만 존재한다면 임시의 객체를 하나 선언해 주고, 반복문을 통해서 객체를 채워나가는 식으로 변환해 줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678187416980&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 2.
const object = array.reduce((acc, value, index) =&amp;gt;
  ({ ...acc, [index]: value })
, {});

console.log(object);
// {'0': 'apple', '1': 'banana', '2': 'mango'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Array.reduce() 메서드를 사용하면, 동일한 위 기능 코드를 축약할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;응용 코드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const array = ['apple', 'banana', 'mango'];

const object = Object.fromEntries(
  array.map((value, index) =&amp;gt; [index, value])
);

console.log(object);
// {'0': 'apple', '1': 'banana', '2': 'mango'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 소개한 방식인 map() 메서드로 key-value 형식으로 만들어주고 Object.fromEntries()로 변환시켜 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678186973303&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Object.fromEntries() - JavaScript | MDN&quot; data-og-description=&quot;The Object.fromEntries() static method transforms a list of key-value pairs into an object.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries&quot; data-og-url=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dXUPME/hyRRDYTw0o/ZksBGtAiwZpQVc9BRnhnTk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dXUPME/hyRRDYTw0o/ZksBGtAiwZpQVc9BRnhnTk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Object.fromEntries() - JavaScript | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Object.fromEntries() static method transforms a list of key-value pairs into an object.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>array</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>object</category>
      <category>react</category>
      <category>객체</category>
      <category>바꾸기</category>
      <category>배열</category>
      <category>변환</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/204</guid>
      <comments>https://gurtn.tistory.com/204#entry204comment</comments>
      <pubDate>Wed, 8 Mar 2023 03:06:07 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 특정 영역 밖을 클릭 했을 때 감지하기</title>
      <link>https://gurtn.tistory.com/203</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/poOwBrX?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;470&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/poOwBrX&quot;&gt;
  JS OutsideClick&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678023827051&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class useOutsideClick {
  ref = null;
  onClickOutside = null;
  
  constructor(ref, onClickOutside) {
    this.ref = ref;
    this.onClickOutside = onClickOutside;

    document.addEventListener('mouseup', this.handleClickOutside);
  }

  handleClickOutside = (event) =&amp;gt; {
    if (this.ref &amp;amp;&amp;amp; !this.ref?.contains?.(event.target)) {
      this.onClickOutside(this);
    }
  }

  removeClickListener = () =&amp;gt; {
    document.removeEventListener('mouseup', this.handleClickOutside);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기에는 특정 요소와 외부 영역을 클릭했을 때 실행할 callback 함수가 필요로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.contains() 메서드는 노드 자체, 직계 자식(childrens) 중 하나이거나, 자식의 직계 자식 등의 여부를 판단해 줍니다. 즉 클릭한 타깃이 초기에 지정한 요소가 맞는지를 판단해 주는 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;만약 ref 요소와 일치하지 않으면, 외부 요소를 클릭했다 판단하고 callback을 호출해 줍니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678024014045&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const $aside = document.querySelector('aside');

const outsideClick = new useOutsideClick($aside, () =&amp;gt; {
  console.log('Click!');
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 useOutsideClick 클래스를 인스턴스화시켜 주고, 요소와 클릭 콜백 함수를 지정해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;[React] custom hook&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678080338588&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const useOutsideClick = ({ onClickOutside }) =&amp;gt; {
  const ref = useRef(null);

  const handleClickOutside = useCallback(
    (event) =&amp;gt; {
      const inside = ref.current?.contains?.(event.target);
      if (ref.current &amp;amp;&amp;amp; !inside) {
        onClickOutside();
      }
    },
    [onClickOutside, ref]
  );

  useEffect(() =&amp;gt; {
    document.addEventListener(&quot;mouseup&quot;, handleClickOutside);

    return () =&amp;gt; {
      document.removeEventListener(&quot;mouseup&quot;, handleClickOutside);
    };
  }, [handleClick]);

  return ref;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 React 코드에 맞게 변형시킨 코드입니다. ref.current에 요소를 지정해 주면 요소 외부 영역을 클릭을 감지하고, 콜백 함수를 호출합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678080372812&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const App = () =&amp;gt; {
  const outsideRef = useOutsideClick(() =&amp;gt; console.log('Click!'));

  return &amp;lt;div&amp;gt;
    &amp;lt;div ref={outsideRef}&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 useOutsideClick()으로 외부 영역 클릭을 감지할 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Node/contains&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/API/Node/contains&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678079410452&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Node.contains() - Web APIs | MDN&quot; data-og-description=&quot;The contains() method of the Node interface returns a boolean value indicating whether a node is a descendant of a given node, that is the node itself, one of its direct children (childNodes), one of the children's direct children, and so on.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Node/contains&quot; data-og-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Node/contains&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xR4kS/hyRQqZ8BcO/zuuT8olrGmpi85284scZ30/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Node/contains&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Node/contains&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xR4kS/hyRQqZ8BcO/zuuT8olrGmpi85284scZ30/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Node.contains() - Web APIs | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The contains() method of the Node interface returns a boolean value indicating whether a node is a descendant of a given node, that is the node itself, one of its direct children (childNodes), one of the children's direct children, and so on.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>감지</category>
      <category>밖 클릭</category>
      <category>외부</category>
      <category>이벤트</category>
      <category>자바스크립트</category>
      <category>클릭</category>
      <category>특정 영역</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/203</guid>
      <comments>https://gurtn.tistory.com/203#entry203comment</comments>
      <pubDate>Tue, 7 Mar 2023 03:30:46 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 배열 초기화 시키기 (빈 배열)</title>
      <link>https://gurtn.tistory.com/202</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;3가지 방법 모두, 원본 배열에서 값을 제거하는 참조 방식을 사용합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;length 속성&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678013503316&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [1, 2, 3, 4, 5];

array.length = 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 길이를 수정하면 해당 길이만큼 배열의 크기가 바꿔지며 0으로 지정하면 배열은 초기화됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;splice() 메서드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678020928622&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [1, 2, 3, 4, 5];

array.splice(0); // 2번째 인자가 없으면 모든 값을 제거&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222;&quot;&gt;splice(0)을 사용하면 처음부터 끝까지 원본 배열에서 잘라 반환하기에 초기화를 시켜줄 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;pop() 메서드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1678020935649&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [1, 2, 3, 4, 5];

while(array.length) array.pop();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pop() 메서드는 배열의 마지막에 존재하는 요소를 제거한 뒤 반환해 주는 메서드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666;&quot;&gt;※ &lt;/span&gt;배열의 길이만큼 pop() 메서드로 하나씩 제거해 주면 초기화되는 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;하지만 length 방식보다 배열의 길이가 클수록 시간이 많이 걸리는 단점이 존재합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript&quot;&gt;https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678012900917&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;How do I empty an array in JavaScript?&quot; data-og-description=&quot;Is there a way to empty an array and if so possibly with .remove()? For instance, A = [1,2,3,4]; How can I empty that?&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript&quot; data-og-url=&quot;https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/6oPO9/hyRQhH4cXJ/3DuBDxBerxfFb12FLx3Ft0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/6oPO9/hyRQhH4cXJ/3DuBDxBerxfFb12FLx3Ft0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;How do I empty an array in JavaScript?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Is there a way to empty an array and if so possibly with .remove()? For instance, A = [1,2,3,4]; How can I empty that?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>array</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>배열</category>
      <category>비우기</category>
      <category>빈 배열</category>
      <category>자바스크립트</category>
      <category>제거</category>
      <category>초기화</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/202</guid>
      <comments>https://gurtn.tistory.com/202#entry202comment</comments>
      <pubDate>Mon, 6 Mar 2023 02:43:14 +0900</pubDate>
    </item>
    <item>
      <title>[JS] Textarea 높이 자동 조절</title>
      <link>https://gurtn.tistory.com/201</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/mdGWeyw?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;430&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/mdGWeyw&quot;&gt;
  Textarea Auto  Height&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1677731558281&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;textarea id=&quot;textarea&quot;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;높이를 조절할 textarea 요소를 준비해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677731580031&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;textarea {
  width: 240px;
  height: 30px;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;textarea의 기본 Height를 지정해주고, 이 크기는 JavaScript 코드에서도 사용하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677731625520&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const DEFAULT_HEIGHT = 30; // textarea 기본 height

const $textarea = document.querySelector('#textarea');&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CSS에서 지정한 Height를 'DEFAULT_HEIGHT' 변수에 저장시켜줍니다.&lt;/li&gt;
&lt;li&gt;document.querySelector() 선택자로 textarea 요소를 가져와줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677731797292&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Textarea 자동 높이 조절
$textarea.oninput = (event) =&amp;gt; {
  const $target = event.target;

  $target.style.height = 0;
  $target.style.height = DEFAULT_HEIGHT + $target.scrollHeight + 'px';
};&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;oninput 이벤트로 입력 되는 시점을 감지해줍니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이때, 해당 textarea의 height를 0으로 변경해주고 &lt;/span&gt;&lt;b&gt;scrollHeight&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;속성으로 스크롤을 포함한 요소의 높이를 적용해줍니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;먼저 height를 초기화 해주지 않으면, scrollHeight 속성이 기존 스타일 높이까지 누적되어 적용되게 됩니다.&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>input</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>textarea</category>
      <category>높이</category>
      <category>자동</category>
      <category>자동 높이</category>
      <category>자동 줄바꿈</category>
      <category>자바스크립트</category>
      <category>조절</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/201</guid>
      <comments>https://gurtn.tistory.com/201#entry201comment</comments>
      <pubDate>Fri, 3 Mar 2023 01:04:08 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 객체에 특정 KEY값이 존재하는지 확인하기</title>
      <link>https://gurtn.tistory.com/200</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;includes() 사용&lt;/blockquote&gt;
&lt;pre id=&quot;code_1677674303499&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const obj = {a: false, b: true, c: null};

Object.keys(obj).includes('a');
// true

Object.keys(obj).includes('abc');
// false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Object.keys() 메서드로 객체의 모든 키값을 담은 배열을 생성해 주고, includes() 메서드로 해당 키가 존재하는지 판별해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;in 연산자 사용&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const obj = {a: false, b: true, c: null};

'c' in obj
// true

'abc' in obj
// false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;in 연산자를 사용하면 간단한 코드로 key가 존재하는지 간단하게 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677674838436&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;obj.prototype.test = false;

'test' in obj
// true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 프로퍼티도 같이 체크해 버린다는 문제점이 존재합니다. 해결을 위해서는 includes() 방법 또는 아래 방법을 사용해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;hasOwnProperty 메서드 사용&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const obj = {a: false, b: true, c: null};

obj.hasOwnProperty('a');
// true

obj.hasOwnProperty('abc');
// false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hasOwnProperty 메서드는 스스로 정의한 프로퍼티에 한해서 특정 키의 소유 여부를 반환해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677674916116&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;obj.prototype.test = true;

obj.hasOwnProperty('test');
// false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 메서드를 사용하면 직접적인 속성만을 검사할 수 있기에 in 연산자에서 발생한 프로퍼티도 체크하는 문제도 해결 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/455338/how-do-i-check-if-an-object-has-a-key-in-javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/455338/how-do-i-check-if-an-object-has-a-key-in-javascript&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677674772690&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;How do I check if an object has a key in JavaScript?&quot; data-og-description=&quot;Which is the right thing to do? if (myObj['key'] == undefined) or if (myObj['key'] == null) or if (myObj['key'])&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/455338/how-do-i-check-if-an-object-has-a-key-in-javascript&quot; data-og-url=&quot;https://stackoverflow.com/questions/455338/how-do-i-check-if-an-object-has-a-key-in-javascript&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bsoOMw/hyRNGHYrpm/QicwZs8lBmogv7Rk5L2TYK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/455338/how-do-i-check-if-an-object-has-a-key-in-javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/455338/how-do-i-check-if-an-object-has-a-key-in-javascript&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bsoOMw/hyRNGHYrpm/QicwZs8lBmogv7Rk5L2TYK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;How do I check if an object has a key in JavaScript?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Which is the right thing to do? if (myObj['key'] == undefined) or if (myObj['key'] == null) or if (myObj['key'])&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/how-to-check-if-an-object-has-a-key-in-javascript/&quot;&gt;https://www.freecodecamp.org/news/how-to-check-if-an-object-has-a-key-in-javascript/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677674738378&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;JavaScript Key in Object &amp;ndash; How to Check if an Object has a Key in JS&quot; data-og-description=&quot;Objects in JavaScript are non-primitive data types that hold an unordered collection of key-value pairs. As you can see in the image above, the key is the property, and each object value must have a key. When interacting with objects, situations might aris&quot; data-og-host=&quot;www.freecodecamp.org&quot; data-og-source-url=&quot;https://www.freecodecamp.org/news/how-to-check-if-an-object-has-a-key-in-javascript/&quot; data-og-url=&quot;https://www.freecodecamp.org/news/how-to-check-if-an-object-has-a-key-in-javascript/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bYiOhf/hyRNRW1wev/NKeXT5Mkx7MFHFfHVKFRU0/img.jpg?width=1600&amp;amp;height=900&amp;amp;face=0_0_1600_900,https://scrap.kakaocdn.net/dn/bZMyRN/hyRNI6RBdf/U2LpyaQakCxCW2p4X9BkK1/img.jpg?width=1600&amp;amp;height=900&amp;amp;face=0_0_1600_900,https://scrap.kakaocdn.net/dn/byXpQS/hyRNHmz8ek/e1nwiY6EvFyUMnhpn1kF1k/img.jpg?width=1600&amp;amp;height=900&amp;amp;face=0_0_1600_900&quot;&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/how-to-check-if-an-object-has-a-key-in-javascript/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.freecodecamp.org/news/how-to-check-if-an-object-has-a-key-in-javascript/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bYiOhf/hyRNRW1wev/NKeXT5Mkx7MFHFfHVKFRU0/img.jpg?width=1600&amp;amp;height=900&amp;amp;face=0_0_1600_900,https://scrap.kakaocdn.net/dn/bZMyRN/hyRNI6RBdf/U2LpyaQakCxCW2p4X9BkK1/img.jpg?width=1600&amp;amp;height=900&amp;amp;face=0_0_1600_900,https://scrap.kakaocdn.net/dn/byXpQS/hyRNHmz8ek/e1nwiY6EvFyUMnhpn1kF1k/img.jpg?width=1600&amp;amp;height=900&amp;amp;face=0_0_1600_900');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript Key in Object &amp;ndash; How to Check if an Object has a Key in JS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Objects in JavaScript are non-primitive data types that hold an unordered collection of key-value pairs. As you can see in the image above, the key is the property, and each object value must have a key. When interacting with objects, situations might aris&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.freecodecamp.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>key</category>
      <category>react</category>
      <category>객체</category>
      <category>자바스크립트</category>
      <category>존재하는지</category>
      <category>체크</category>
      <category>포함</category>
      <category>확인</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/200</guid>
      <comments>https://gurtn.tistory.com/200#entry200comment</comments>
      <pubDate>Thu, 2 Mar 2023 01:44:41 +0900</pubDate>
    </item>
    <item>
      <title>[JS] forEach(), map() break 시키기</title>
      <link>https://gurtn.tistory.com/199</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;일반적인 방법으로는 forEach(), map()를 break 시킬 수 없습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;try {
  [1, 2, 3, 4, 5, 6, 7].forEach((value) =&amp;gt; {
    console.log(value);
    if (value === 2) {
      throw value;
    }
  });
} catch (e) {
  console.log(&quot;Stop! &quot; + e);
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;forEach, map 메서드에서는 break를 걸 수 없습니다.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;return false&amp;rdquo;를 사용하라는 방법이 소개되곤 반복이 멈추지는 않습니다.&lt;/li&gt;
&lt;li&gt;forEach, map 메서드에서는&lt;b&gt; try, catch 문법에서 강제로 에러를 일으켜 루프문을 벗어나게 하는 방법&lt;/b&gt;을 사용합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;some, every 메서드 사용하기&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;some(), every() 메서드는 반환값이 조건에 충족하지 못하면, 그 즉시 반복을 중지하는 구조를 가진 메서드입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;some 메서드는 하나라도 &lt;b&gt;true가 반환&lt;/b&gt;되면 반복을 중지합니다.&lt;/li&gt;
&lt;li&gt;every 메서드는 하나라도 &lt;b&gt;false가 반환&lt;/b&gt;되면 반복을 중지합니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;forEach() 메서드와 some(), every() 메서드의 사용방법이 다른 이유는 해당 메서드를 코드로 구현하면 아래와 같이 구현되기 때문입니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function some(array, callback) {
  for (let i = 0; i &amp;lt; array.length; i++) {
    if (callback(array[i], i, array)) {
      return true;
    }
  }

  return false;
}
some([0, 0, 1, 0, 0], (value) =&amp;gt; value);
// false

function every(array, callback) {
  for (let i = 0; i &amp;lt; array.length; i++) {
    if (!callback(array[i], i, array)) {
      return false;
    }
  }

  return true;
}
every([1, 2, 0, 2, 1], (value) =&amp;gt; value);
// false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;break 문을 사용해야 할 상황에는 되도록 for loop를 사용하도록 합시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;/span&gt;&lt;a href=&quot;https://davidwalsh.name/javascript-array-tricks-3&quot;&gt;https://davidwalsh.name/javascript-array-tricks-3&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675524250864&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Break a forEach Loop with JavaScript&quot; data-og-description=&quot;I've written a number of blog posts about JavaScript tricks: Promise tricks, type conversion tricks, spread tricks, and a host of other JavaScript tricks.&quot; data-og-host=&quot;davidwalsh.name&quot; data-og-source-url=&quot;https://davidwalsh.name/javascript-array-tricks-3&quot; data-og-url=&quot;https://davidwalsh.name/javascript-array-tricks-3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jxTTm/hyRvawGP0j/BLe0cf1iu2nvoXMwNRMzdk/img.png?width=250&amp;amp;height=194&amp;amp;face=0_0_250_194,https://scrap.kakaocdn.net/dn/yjUwl/hyRvptSdYw/N3RtxGa9hPkGkD7WUuHKB1/img.png?width=250&amp;amp;height=194&amp;amp;face=0_0_250_194&quot;&gt;&lt;a href=&quot;https://davidwalsh.name/javascript-array-tricks-3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://davidwalsh.name/javascript-array-tricks-3&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jxTTm/hyRvawGP0j/BLe0cf1iu2nvoXMwNRMzdk/img.png?width=250&amp;amp;height=194&amp;amp;face=0_0_250_194,https://scrap.kakaocdn.net/dn/yjUwl/hyRvptSdYw/N3RtxGa9hPkGkD7WUuHKB1/img.png?width=250&amp;amp;height=194&amp;amp;face=0_0_250_194');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Break a forEach Loop with JavaScript&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I've written a number of blog posts about JavaScript tricks: Promise tricks, type conversion tricks, spread tricks, and a host of other JavaScript tricks.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;davidwalsh.name&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>break</category>
      <category>for break</category>
      <category>foreach</category>
      <category>foreach break</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>map break</category>
      <category>멈추기</category>
      <category>반복문</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/199</guid>
      <comments>https://gurtn.tistory.com/199#entry199comment</comments>
      <pubDate>Thu, 2 Mar 2023 01:33:32 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 소수점 계산 오차 해결</title>
      <link>https://gurtn.tistory.com/198</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;198&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xbLj2/btrX18f3eOy/BsYuBXGrJT3GEVJCtpre01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xbLj2/btrX18f3eOy/BsYuBXGrJT3GEVJCtpre01/img.png&quot; data-alt=&quot;오류 상황&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xbLj2/btrX18f3eOy/BsYuBXGrJT3GEVJCtpre01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxbLj2%2FbtrX18f3eOy%2FBsYuBXGrJT3GEVJCtpre01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;198&quot; height=&quot;139&quot; data-origin-width=&quot;198&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오류 상황&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;원인&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;컴퓨터에서 계산을 할 때는 10진수 대신에 0과 1만을 사용하는 2진수로 계산합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0과 1만을 사용하여 계산하기에 10 진수를 2진수로 바꾸는 변환과정이 필요합니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;이때 컴퓨터 메모리에 존재하는 한계로 인해서 연산 중 발생한 무한소수의 중간을 잘라서 유한 소수로 저장해 버립니다.&lt;/li&gt;
&lt;li&gt;이 과정에서 미세한 오차가 발생하는 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;첫 번째 방법&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;Number((0.2 + 0.4).toFixed(1))
// 0.6

Math.round((0.2 + 0.4) * 10) / 10;
// 0.6&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Number.toFixed(n) &amp;rarr; 소수점 n자리까지 반올림&lt;/li&gt;
&lt;li&gt;Math.round((a + b) * 10) / 10 &amp;rarr; 소수점 첫째 자리까지 반올림&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;toFixed() 메서드는 문자열로 반환되기에 Number로 감싸서 숫자형으로 바꿔줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;두 번째 방법&lt;/blockquote&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;(0.2 * 10 + 0.4 * 10) / 10;
// 0.6
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10의 거듭제곱을 곱해서 소수를 정수로 만들어 계산 후, 다시 나눠주는 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소수점 연산에 문제가 있으니 정수로 만들어 계산해 주는 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// 1. toFxied 사용
function decimalPlus(a, b, n = 1) {
  return Number((a + b).toFixed(n));
}

// 2. 정수로 계산
function decimalPlus(a, b, n = 1) {
  const unit = Math.pow(10, n);

  return (a * unit + b * unit) / unit;
}

decimalPlus(0.02, 0.04, 2);
// 0.06&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 소개한 방법으로 다음과 같이 함수로 제작하여 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://joonpyo-hong.tistory.com/entry/JS-소수점-계산-오류-해결하는-법-부동-소수점&quot;&gt;https://joonpyo-hong.tistory.com/entry/JS-소수점-계산-오류-해결하는-법-부동-소수점&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675438913657&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JS] 소수점 계산 오류 해결법 (부동 소수점)&quot; data-og-description=&quot;자바스크립트(javaScript)의 소수점 연산에서 오류가 발생했다. var a = 0.1; var b = 0.2; console.log(a + b); // 0.30000000000000004 0.3을 예상했지만 0.30000000000000004가 출력됬다. 원인 자바스크립트(javaScript)뿐만 &quot; data-og-host=&quot;joonpyo-hong.tistory.com&quot; data-og-source-url=&quot;https://joonpyo-hong.tistory.com/entry/JS-소수점-계산-오류-해결하는-법-부동-소수점&quot; data-og-url=&quot;https://joonpyo-hong.tistory.com/entry/JS-%EC%86%8C%EC%88%98%EC%A0%90-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94-%EB%B2%95-%EB%B6%80%EB%8F%99-%EC%86%8C%EC%88%98%EC%A0%90&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/yN3Qp/hyRtYcAAr7/T3apI2nmFKzktDJ4P91JzK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cNN1pE/hyRtXdF4n2/F0LRMFPzokrvcXhFguSAV1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://joonpyo-hong.tistory.com/entry/JS-소수점-계산-오류-해결하는-법-부동-소수점&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://joonpyo-hong.tistory.com/entry/JS-소수점-계산-오류-해결하는-법-부동-소수점&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/yN3Qp/hyRtYcAAr7/T3apI2nmFKzktDJ4P91JzK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cNN1pE/hyRtXdF4n2/F0LRMFPzokrvcXhFguSAV1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JS] 소수점 계산 오류 해결법 (부동 소수점)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트(javaScript)의 소수점 연산에서 오류가 발생했다. var a = 0.1; var b = 0.2; console.log(a + b); // 0.30000000000000004 0.3을 예상했지만 0.30000000000000004가 출력됬다. 원인 자바스크립트(javaScript)뿐만&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;joonpyo-hong.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675439075022&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Javascript 소수점 오류 원인, 해결방안&quot; data-og-description=&quot;자바스크립트에서 소수점 숫자 연산을 하면, 생각지도 못한 오류가 발생한다. 아래처럼 콘솔창에 0.1 + 0.2를 입력하면, 0.3이 아니라 0.30000000000000004 가 나오는 걸 확인해볼 수 있다. 이렇게 소수점&quot; data-og-host=&quot;joooing.tistory.com&quot; data-og-source-url=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot; data-og-url=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/e1mk2/hyRtZvNlCO/5kRbXNRgkmrxgCfkiKue11/img.png?width=800&amp;amp;height=798&amp;amp;face=0_0_800_798,https://scrap.kakaocdn.net/dn/cDavxW/hyRt5JAtn7/vZg1EeyBLxR63n0yHMjteK/img.png?width=800&amp;amp;height=798&amp;amp;face=0_0_800_798,https://scrap.kakaocdn.net/dn/bzmHM0/hyRvaWLWzK/djxwnR6wKBVjbsaGjCNaY1/img.png?width=1198&amp;amp;height=209&amp;amp;face=0_0_1198_209&quot;&gt;&lt;a href=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/e1mk2/hyRtZvNlCO/5kRbXNRgkmrxgCfkiKue11/img.png?width=800&amp;amp;height=798&amp;amp;face=0_0_800_798,https://scrap.kakaocdn.net/dn/cDavxW/hyRt5JAtn7/vZg1EeyBLxR63n0yHMjteK/img.png?width=800&amp;amp;height=798&amp;amp;face=0_0_800_798,https://scrap.kakaocdn.net/dn/bzmHM0/hyRvaWLWzK/djxwnR6wKBVjbsaGjCNaY1/img.png?width=1198&amp;amp;height=209&amp;amp;face=0_0_1198_209');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Javascript 소수점 오류 원인, 해결방안&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 소수점 숫자 연산을 하면, 생각지도 못한 오류가 발생한다. 아래처럼 콘솔창에 0.1 + 0.2를 입력하면, 0.3이 아니라 0.30000000000000004 가 나오는 걸 확인해볼 수 있다. 이렇게 소수점&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;joooing.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>계산</category>
      <category>버리기</category>
      <category>소수</category>
      <category>소수점</category>
      <category>숫자</category>
      <category>오류</category>
      <category>오차</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/198</guid>
      <comments>https://gurtn.tistory.com/198#entry198comment</comments>
      <pubDate>Tue, 7 Feb 2023 01:49:45 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 코드 실행 지연 시키기 (delay)</title>
      <link>https://gurtn.tistory.com/197</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;흔히 알려진 시간을 지연시키는 방법으로는 setTimeout() 함수가 있습니다.&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문제점&lt;/blockquote&gt;
&lt;pre id=&quot;code_1675438405986&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function delayTest() {
  console.log(&quot;__코드 시작__&quot;);

  setTimeout(() =&amp;gt; {
    // 5초 후 실행
    console.log(&quot;실행! 1&quot;);

    setTimeout(() =&amp;gt; {
      // 3+5초 후 실행
      console.log(&quot;실행! 2&quot;);
    }, 5000);
  }, 3000);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 쉽게 시간을 지연시킬 수 있지만, 다음과 같은 상황에서는 사용하기에 어려움이 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중첩해서 5초 후에 코드 실행과 3초 후에 코드 실행이 되어야 하는 상황입니다.&lt;/li&gt;
&lt;li&gt;위 코드와 같이 setTimeout callback 안에 setTimeout을 넣어줘야 하는 문제점이 발생합니다.&lt;/li&gt;
&lt;li&gt;계속 함수가 늘어나게 되면, 가독성에 문제가 생깁니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function delay(ms = 1000) {
  return new Promise((resolve) =&amp;gt; setTimeout(resolve, ms));
}

async function delayTest() {
  console.log(&quot;__코드 시작__&quot;);

  // 3초 지연
  await delay(3000);

  // 3초 후 실행
  console.log(&quot;실행! 1&quot;);

  // 5초 지연
  await delay(5000);

  // 3+5초 후 실행
  console.log(&quot;실행! 2&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;javascript에 존재하는 Promise 개념과 async/await 문법을 이용해서 지연을 시킬 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;await 키워드를 사용할 함수 앞에 async 키워드를 작성해 줍니다.&lt;/li&gt;
&lt;li&gt;delay 함수 앞에 await 키워드를 붙여주는 것이 끝입니다.&lt;/li&gt;
&lt;li&gt;await 키워드가 붙은 함수(delay)가 반환될 때까지 해당 지점에서 멈추게 될 것입니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>JavaScript/코드</category>
      <category>await</category>
      <category>delay</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>promise</category>
      <category>settimeout</category>
      <category>늦추기</category>
      <category>실행 지연</category>
      <category>자바스크립트</category>
      <category>지연</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/197</guid>
      <comments>https://gurtn.tistory.com/197#entry197comment</comments>
      <pubDate>Mon, 6 Feb 2023 01:36:09 +0900</pubDate>
    </item>
    <item>
      <title>[HTML] 제곱, 화학식 표현하기</title>
      <link>https://gurtn.tistory.com/196</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 예제&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/KKBGaEz?default-tab=html%2Cresult&quot; width=&quot;100%;&quot; height=&quot;525&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/KKBGaEz&quot;&gt;
  HTML sup, sub Tag&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 붙여서 표현하는 &amp;lt;sup&amp;gt;, 태그 아래에 붙여서 나타나는 &amp;lt;sub&amp;gt; 태그가 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; =64

5&amp;lt;sup&amp;gt;th&amp;lt;/sup&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lt;sup&amp;gt; 태그&lt;/b&gt;를 사용해면 일반 텍스트보다 작은 글자가 위에 표시됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;x&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; ... x&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;

5&amp;lt;s&amp;gt;n+2&amp;lt;/sub&amp;gt;

H&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;
O&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;
H&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;O&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lt;sub&amp;gt; 태그&lt;/b&gt;를 사용해면 일반 텍스트보다 작은 글자가 아래에 표시됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;타이포그래피적인 이유에 맞춰서만 사용해야 하며, 그 외는 vertical-align: (super, sub) 속성으로 대신할 수 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sup&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sup&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675178949835&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;&amp;lt;sup&amp;gt;: 위 첨자 요소 - HTML: Hypertext Markup Language | MDN&quot; data-og-description=&quot;HTML &amp;lt;sup&amp;gt; 요소는 활자 배치를 위 첨자로 해야 하는 인라인 텍스트를 지정합니다. 위 첨자는 보통 더 작은 글씨 크기를 가지고, 기준선을 위로 올려 렌더링 합니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sup&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sup&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmrBnq/hyRsmw6pEe/dEU7KMKWyKza9NsR9QBkr0/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sup&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sup&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmrBnq/hyRsmw6pEe/dEU7KMKWyKza9NsR9QBkr0/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lt;sup&amp;gt;: 위 첨자 요소 - HTML: Hypertext Markup Language | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;HTML &amp;lt;sup&amp;gt; 요소는 활자 배치를 위 첨자로 해야 하는 인라인 텍스트를 지정합니다. 위 첨자는 보통 더 작은 글씨 크기를 가지고, 기준선을 위로 올려 렌더링 합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sub&quot;&gt;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sub&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675178951151&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;&amp;lt;sub&amp;gt;: 아래 첨자 요소 - HTML: Hypertext Markup Language | MDN&quot; data-og-description=&quot;HTML &amp;lt;sub&amp;gt; 요소는 활자 배치를 아래 첨자로 해야 하는 인라인 텍스트를 지정합니다. 아래 첨자는 보통 더 작은 글씨 크기를 가지고, 기준선을 아래로 내려 렌더링 합니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sub&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sub&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cqolaJ/hyRsp8qlQR/eC3Ihzsb3iSukwUvyV7K80/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sub&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/sub&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cqolaJ/hyRsp8qlQR/eC3Ihzsb3iSukwUvyV7K80/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lt;sub&amp;gt;: 아래 첨자 요소 - HTML: Hypertext Markup Language | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;HTML &amp;lt;sub&amp;gt; 요소는 활자 배치를 아래 첨자로 해야 하는 인라인 텍스트를 지정합니다. 아래 첨자는 보통 더 작은 글씨 크기를 가지고, 기준선을 아래로 내려 렌더링 합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>HTML, CSS/코드</category>
      <category>CSS</category>
      <category>HTML</category>
      <category>JS</category>
      <category>나타내기</category>
      <category>숫자</category>
      <category>제곱</category>
      <category>지수</category>
      <category>첨자</category>
      <category>태그</category>
      <category>화학식</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/196</guid>
      <comments>https://gurtn.tistory.com/196#entry196comment</comments>
      <pubDate>Thu, 2 Feb 2023 01:48:58 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 눈 내리는 효과 만들기</title>
      <link>https://gurtn.tistory.com/195</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;완성 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/abjjWGp?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;536&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/abjjWGp&quot;&gt;
  Canvas Snow&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;전체코드(보기)&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1675175627546&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const $canvas = document.querySelector(&quot;canvas&quot;);
const ctx = $canvas.getContext(&quot;2d&quot;);

const getRandomRadius = () =&amp;gt; Math.random() * 1 + 0.5;
const getRandomSpeed = () =&amp;gt; Math.random() * 0.3 + 0.1;
const getRandomDir = () =&amp;gt; [-1, 1][Math.floor(Math.random() * 2)];

const Snow = {
  data: [],
  canvasWidth: $canvas.clientWidth,
  canvasHeight: $canvas.clientHeight,

  init() {
    Snow.make();
    Snow.loop();
  },

  loop() {
    Snow.move();
    Snow.draw();

    window.requestAnimationFrame(Snow.loop);
  },

  make() {
    const data = [];

    // 랜덤한 데이터 200개 생성
    for (let i = 0; i &amp;lt; 200; i++) {
      const x = Math.random() * Snow.canvasWidth;
      const y = Math.random() * Snow.canvasHeight;

      const size = getRandomRadius();
      const speed = getRandomSpeed();
      const dir = getRandomDir();

      data.push({ x, y, size, speed, dir });
    }

    // Snow 객체에 데이터 저장
    Snow.data = data;
  },

  move() {
    Snow.data = Snow.data.map((item) =&amp;gt; {
      // 방향에 맞게 이동
      item.x += item.dir * item.speed;
      item.y += item.speed;

      // 캔버스를 벗어났는지 판단
      const isMinOverPositionX = -item.size &amp;gt; item.x;
      const isMaxOverPositionX = item.x &amp;gt; Snow.canvasWidth;
      const isOverPositionY = item.y &amp;gt; Snow.canvasHeight;

      // 벗어나면 반대방향, 맨 위로
      if (isMinOverPositionX || isMaxOverPositionX) {
        item.dir *= -1;
      }
      if (isOverPositionY) {
        item.y = -item.size;
      }

      return item;
    });
  },

  draw() {
    ctx.clearRect(0, 0, Snow.canvasWidth, Snow.canvasHeight);

    ctx.fillStyle = &quot;#0f1018&quot;;
    ctx.fillRect(0, 0, Snow.canvasWidth, Snow.canvasHeight);

    Snow.data.forEach((item) =&amp;gt; {
      ctx.beginPath();
      ctx.fillStyle = &quot;rgba(255, 255, 255, .6)&quot;;
      ctx.arc(item.x, item.y, item.size, 0, Math.PI * 2);
      ctx.fill();
      ctx.closePath();
    });
  },
};

Snow.init();

window.onresize = () =&amp;gt; {
  Snow.canvasWidth = $canvas.clientWidth;
  Snow.canvasHeight = $canvas.clientHeight;

  Snow.make();
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;canvas width=&quot;460&quot; height=&quot;460&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 내리는 눈을 그려줄 캔버스 요소를 만들어줍니다. (예시로 460 사이즈 지정)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const $canvas = document.querySelector(&quot;canvas&quot;);
const ctx = $canvas.getContext(&quot;2d&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그려줄 캔버스 DOM을 찾아서 변수에 저장해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// 크기
const getRandomRadius = () =&amp;gt; Math.random() * 1 + 0.5;
// 속도
const getRandomSpeed = () =&amp;gt; Math.random() * 0.3 + 0.1;
// 방향
const getRandomDir = () =&amp;gt; [-1, 1][Math.floor(Math.random() * 2)];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;눈의 크기, 움직이는 속도, 방향을 랜덤 하게 가져오는 함수를 미리 선언해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const Snow = {
  data: [],
  canvasWidth: $canvas.clientWidth,
  canvasHeight: $canvas.clientHeight,

  init() {
  },

  loop() {
  },

  make() {
  },

  move() {
  },

  draw() {
  },
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;눈이 내리는 효과를 만들기 위해서 필요한 함수 총 5개와 캔버스 크기를 미리 세팅해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;make() {
  const data = [];

  // 랜덤한 데이터 200개 생성
  for (let i = 0; i &amp;lt; 200; i++) {
    const x = Math.random() * Snow.canvasWidth;
    const y = Math.random() * Snow.canvasHeight;

    const size = getRandomRadius();
    const speed = getRandomSpeed();
    const dir = getRandomDir();

    data.push({ x, y, size, speed, dir });
  }

  // Snow 객체에 데이터 저장
  Snow.data = data;
},&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;make() 함수는 눈 데이터를 만드는 함수입니다.&lt;/li&gt;
&lt;li&gt;반복문을 돌려 시작 x, y 위치와 위에서 선언한 함수(크기, 속도, 방향)로 데이터를 만들어줍니다. ( 총 200개 )&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;move() {
  Snow.data = Snow.data.map((item) =&amp;gt; {
    // 방향에 맞게 이동
    item.x += item.dir * item.speed;
    item.y += item.speed;

    // 캔버스를 벗어났는지 판단
    const isMinOverPositionX = -item.size &amp;gt; item.x;
    const isMaxOverPositionX = item.x &amp;gt; Snow.canvasWidth;
    const isOverPositionY = item.y &amp;gt; Snow.canvasHeight;

    // 벗어나면 반대방향, 맨 위로
    if (isMinOverPositionX || isMaxOverPositionX) {
      item.dir *= -1;
    }
    if (isOverPositionY) {
      item.y = -item.size;
    }

    return item;
  });
},&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 반복문을 돌려서 각 아이템마다 가진 speed 만큼 더해서 누산 시켜줍니다.&lt;/li&gt;
&lt;li&gt;이때 현재 x, y 위치 값이 캔버스를 벗어나면 반대방향으로 바꿔주거나 맨 위로 올려주는 조건을 거칩니다.&lt;/li&gt;
&lt;li&gt;이후 Snow.Loop()가 반복되면서 speed 만큼 더해진 데이터를 다시 그려주게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;draw() {
  ctx.clearRect(0, 0, Snow.canvasWidth, Snow.canvasHeight);

  ctx.fillStyle = &quot;#0f1018&quot;;
  ctx.fillRect(0, 0, Snow.canvasWidth, Snow.canvasHeight);

  Snow.data.forEach((item) =&amp;gt; {
    ctx.beginPath();
    ctx.fillStyle = &quot;rgba(255, 255, 255, .6)&quot;;
    ctx.arc(item.x, item.y, item.size, 0, Math.PI * 2);
    ctx.fill();
    ctx.closePath();
  });
},&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전에 그려진 캔버스를 지워주고, 검은 배경으로 채워줍니다.&lt;/li&gt;
&lt;li&gt;move로 이동된 모든 눈 데이터를 ctx.arc() 메서드를 이용해서 원으로 그려줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;ctx.arc( x, y, radius, startAngle, endAngle ) 인자를 필요로 하며, Math.PI * 2는 원의 총둘레입니다&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;loop() {
  // 눈을 이동시킨 후, 그리기
  Snow.move();
  Snow.draw();
	
  // Snow.loop() 함수를 계속 재귀함
  window.requestAnimationFrame(Snow.loop);
},&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필요한 함수를 다 제작했으니, 마지막으로 window.requestAnimationFrame()를 이용해서 재귀를 돌려줍니다.&lt;/li&gt;
&lt;li&gt;눈 데이터를 이동시켜 준 후, 그려주는 순서로 함수를 호출해 줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/requestAnimationFrame&quot;&gt;https://developer.mozilla.org/ko/docs/Web/API/Window/requestAnimationFrame&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675175594842&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;window.requestAnimationFrame() - Web API | MDN&quot; data-og-description=&quot;화면에 새로운 애니메이션을 업데이트할 준비가 될때마다 이 메소드를 호출하는것이 좋습니다. 이는 브라우저가 다음 리페인트를 수행하기전에 호출된 애니메이션 함수를 요청합니다. 콜백의 &quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/requestAnimationFrame&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/requestAnimationFrame&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c165BE/hyRssD1Ngw/nPtFu96Vyekk5BkXc4T4l1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/requestAnimationFrame&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/requestAnimationFrame&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c165BE/hyRssD1Ngw/nPtFu96Vyekk5BkXc4T4l1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;window.requestAnimationFrame() - Web API | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;화면에 새로운 애니메이션을 업데이트할 준비가 될때마다 이 메소드를 호출하는것이 좋습니다. 이는 브라우저가 다음 리페인트를 수행하기전에 호출된 애니메이션 함수를 요청합니다. 콜백의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const Snow = {
  data: [],

  init() {
    Snow.make();
    Snow.loop();
  },
	
  ....
}

// 눈 그리기 시작
Snow.init();&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마지막으로 처음에 세팅해 주는 Snow.init()에 데이터를 만들어주는 함수와 루프를 시작하는 함수를 호출해 줍니다.&lt;/li&gt;
&lt;li&gt;Snow.init() 코드로 실행해 주면 동작하게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;창 크기에 맞추기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1675176257954&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;window.onresize = () =&amp;gt; {
  Snow.canvasWidth = $canvas.clientWidth;
  Snow.canvasHeight = $canvas.clientHeight;

  Snow.make();
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;창 크기가 변할 때마다, 캔버스 가로사이즈를 창 가로사이즈로 대체해 줍니다. 그 후 바뀐 크기에 맞는 눈 데이터를 생성해 줍니다.&lt;/p&gt;</description>
      <category>JavaScript/제작</category>
      <category>CSS</category>
      <category>HTML</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>눈</category>
      <category>눈 내림</category>
      <category>애니메이션</category>
      <category>자바스크립트</category>
      <category>효과</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/195</guid>
      <comments>https://gurtn.tistory.com/195#entry195comment</comments>
      <pubDate>Wed, 1 Feb 2023 00:56:01 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 개인정보 마스킹 처리 (이름, 전화번호, 주민번호, 이메일, 계좌번호..)</title>
      <link>https://gurtn.tistory.com/194</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;정규식으로 마스킹하는 방법이 존재하지만, 익스플로러에서 호환성 문제로 동작하지 않는 이슈가 존재합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이름&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674571210036&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function maskingName(name) {
  if (name.length &amp;lt;= 2) {
    return name.replace(name.substring(0, 1), &quot;*&quot;);
  }

  return (
    name[0] +
    &quot;*&quot;.repeat(name.substring(1, name.length - 1).length) +
    name[name.length - 1]
  );
}

maskingName(&quot;홍길동&quot;);
// mask - 홍*동

maskingName(&quot;김길&quot;);
// mask - *길&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1~2글자는 첫 문자를 *로 바꿔주고 3글자부터는 가운데 글자를 *로 바꿔주는 코드입니다. &lt;span&gt;replace() 메서드 대신에 repeat() 메서드를 사용해 주었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;전화번호&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674571349089&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function maskingPhoneNumber(phoneNumber) {
  const values = phoneNumber.split(&quot;-&quot;);

  values[1] = &quot;*&quot;.repeat(values[1].length);

  return values.join(&quot;-&quot;);
}

maskingPhoneNumber(&quot;010-1111-2222&quot;);
// mask - 010-****-2222&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전화번호의 하이픈을 기준으로 쪼개서, 가운데를 *로 바꿔주는 코드입니다. 전화번호에 하이픈을 넣어주는 코드는 아래 포스팅을 참고해 주세요!.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/86&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gurtn.tistory.com/86&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674576364961&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JS] 전화번호 자동 하이픈(-) 정규식&quot; data-og-description=&quot;첫 번째 코드 const phone = '01012345678'; phone.replace(/^(\d{2,3})(\d{3,4})(\d{4})$/, &amp;#96;$1-$2-$3&amp;#96;); // '010-1234-5678' 00-000-0000 또는 000-0000-0000 같은 상황에서 (2, 3) - (3, 4) - (4) 자리에 숫자를 그룹 지어 묶어줍니다. replac&quot; data-og-host=&quot;gurtn.tistory.com&quot; data-og-source-url=&quot;https://gurtn.tistory.com/86&quot; data-og-url=&quot;https://gurtn.tistory.com/86&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Y1WEl/hyRnd8zUbL/Jqa24F9iFbAXOEAJx9Dmh0/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246,https://scrap.kakaocdn.net/dn/UaqPB/hyRmYcwgFp/XBpR7KecPmPSsekyaWrra0/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246,https://scrap.kakaocdn.net/dn/bkxBmF/hyRoG2odPl/CyWK41maphXKnfMBbV3N41/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/86&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gurtn.tistory.com/86&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Y1WEl/hyRnd8zUbL/Jqa24F9iFbAXOEAJx9Dmh0/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246,https://scrap.kakaocdn.net/dn/UaqPB/hyRmYcwgFp/XBpR7KecPmPSsekyaWrra0/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246,https://scrap.kakaocdn.net/dn/bkxBmF/hyRoG2odPl/CyWK41maphXKnfMBbV3N41/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JS] 전화번호 자동 하이픈(-) 정규식&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째 코드 const phone = '01012345678'; phone.replace(/^(\d{2,3})(\d{3,4})(\d{4})$/, `$1-$2-$3`); // '010-1234-5678' 00-000-0000 또는 000-0000-0000 같은 상황에서 (2, 3) - (3, 4) - (4) 자리에 숫자를 그룹 지어 묶어줍니다. replac&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gurtn.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이메일&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674571669021&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function maskingEmail(email) {
  const mask = &quot;*&quot;.repeat(email.split(&quot;@&quot;)[0].length - 1);

  return email[0] + mask + email.slice(mask.length + 1, email.length);
}

maskingEmail(&quot;asd123456@naver.com&quot;);
// mask - a********@naver.com&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mask 문자를 만들 때 맨 앞글자를 제외시킨 숫자만큼 마스킹 처리를 해주고 남은 문자들을 합쳐서 반환해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;주민등록번호&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674571889818&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function maskingRrn(number) {
  return number.substring(0, number.length - 6) + &quot;******&quot;;
}

maskingRrn(&quot;000203-1234567&quot;);
// mask - 000203-1******&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 주민번호 형식은 YYMMDD-GHIJKLX으로 6자리-7자리로 구성되어 있습니다. 뒷자리 6자리가 워낙 중요하기에 *로 대체해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;계좌번호&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674571913594&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function maskingAccountNumber(accountNumber) {
  const mask = &quot;*&quot;.repeat(accountNumber.split(&quot;-&quot;).at(-1).length);

  return accountNumber.substring(0, accountNumber.length - mask.length) + mask;
}

maskingAccountNumber(&quot;022-01-1111&quot;);
// 022-01-****&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행마다 계좌번호 형태가 다릅니다. 마스킹 작업을 수월하게 하기 위해서는 하이픈이 들어간 계좌번호여야 합니다.&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>mask</category>
      <category>개인정보</category>
      <category>마스킹</category>
      <category>모자이크</category>
      <category>자바스크립트</category>
      <category>정규식</category>
      <category>주민등록번호</category>
      <category>함수</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/194</guid>
      <comments>https://gurtn.tistory.com/194#entry194comment</comments>
      <pubDate>Fri, 27 Jan 2023 02:07:45 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 시작일과 종료일 사이 모든 날짜 구하기</title>
      <link>https://gurtn.tistory.com/193</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;시작일(YYYY-MM-DD) ~ 종료일(YYYY-MM-DD) 사이의 모든 [시, 일, 월, 년] 단위의 배열을 만들 수 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/bGjaVeM?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;520&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/bGjaVeM&quot;&gt;
  Untitled&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674035223046&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const getDateRange = (startDate, endDate) =&amp;gt; {
  const start = new Date(startDate);
  const end = new Date(endDate);

  const result = [];

  while (start &amp;lt;= end) {
    result.push(start.toISOString().split('T')[0]);
    start.setDate(start.getDate() + 1);
  }

  return result;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작일과 종료일을 받아주고, 시작일이 종료일을 넘을 때까지 &lt;span&gt;하루를&lt;span&gt; &lt;/span&gt;&lt;/span&gt;계속 더해주면서 날짜를 구해주는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;시간, 일, 월, 년도 단위 배열 만들기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674036448043&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const start = new Date();

// 현재 시간
start.setHours(date.getHours() + 1);
// 현재 일
start.setDate(date.getDate() + 1);
// 현재 월
start.setMonth(date.getMonth() + 1)
// 현재 년도
start.setFullYear(date.getFullYear() + 1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 예시로 사용한&lt;b&gt; 하루를 더하는 코드에서는 setDate(), getDate() 메서드&lt;/b&gt;를 사용하였습니다. 이를 다른 메서드로 대체하면 하루단위가 아닌 월, 년 간격의 날짜를 구할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1674200580862&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  // ...

  while (start &amp;lt;= end) {
    result.push(start.toISOString().split('T')[0]);
    // 예시 - 1시간 단위의 모든 날짜
    // ex) start.setHours(start.getHours() + 1);
  }
  
  ...
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setDate(getDate() + 1) 코드는 하루를 더 해줄 수 있는 코드이고, 해당 코드를 바꾸면, 다른 날짜 기준으로 더해줄 수 있습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;단, 시간 단위로 구해줄 때는 포맷해 주는 부분을 날짜와 시간도 같이 포함시켜 줘야 변화를 확인할 수 있습니다.&lt;/blockquote&gt;</description>
      <category>JavaScript/코드</category>
      <category>date</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>날짜</category>
      <category>날짜 사이</category>
      <category>모든날짜</category>
      <category>시작일</category>
      <category>자바스크립트</category>
      <category>종료일</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/193</guid>
      <comments>https://gurtn.tistory.com/193#entry193comment</comments>
      <pubDate>Thu, 26 Jan 2023 01:38:04 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 뒤로가기 막기, 뒤로가기(이전페이지) 링크 만들기</title>
      <link>https://gurtn.tistory.com/192</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;사용자가 방문한 모든 URL을 포함하는 객체로는 &lt;b&gt;history&lt;/b&gt;라는 JavaScript 객체가 존재합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;뒤로가기 링크 제작&lt;/blockquote&gt;
&lt;pre id=&quot;code_1673711967323&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;history.back();
// 이전페이지로 이동&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;History 객체에는 사용자가 방문한 모든 URL을 스택 방식으로 쌓아놓습니다. 이를 위에 코드로 사용하면 Array.pop() 같은 효과가 나오게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1673711973674&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;history.go(-1)
// 이전페이지로 이동

history.go(-2)
// 이번페이지 -2번 클릭한 것과 동일한 동작&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;가장 뒤에 있는 URL을 빼는 메서드가 존재한다면, 특정 URL을 지정하는 메서드도 존재합니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;history.go()&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드는 인자로 전달하는 수만큼 페이지를 이동합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;뒤로가기 막기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674033820331&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 스택 추가
history.pushState(null, null, location.href); 

// 뒤로라기 이벤트감지 -&amp;gt; 현재페이지로 이동
window.onpopstate = function() { 
	history.go(1); 
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히스토리&amp;nbsp;스택에&amp;nbsp;현재&amp;nbsp;페이지의&amp;nbsp;URL을&amp;nbsp;추가한&amp;nbsp;뒤,&amp;nbsp;뒤로가기를&amp;nbsp;할&amp;nbsp;경우&amp;nbsp;현재&amp;nbsp;페이지로&amp;nbsp;이동시켜서&amp;nbsp;뒤로가기를&amp;nbsp;막는&amp;nbsp;방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674033056233&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;button id=&quot;back&quot;&amp;gt;뒤로가기&amp;lt;/button&amp;gt;
&amp;lt;button id=&quot;stop&quot;&amp;gt;뒤로가기 막기&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1674033107723&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;document.querySelector('#back').onclick = function() {
  history.back();
}

document.querySelector('#stop').onclick = function() {
  history.pushState(null, null, location.href); 
  window.onpopstate = function(event) { 
	history.go(1); 
  };
}&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&quot;display: flex; align-items: center;&quot;&gt;
&lt;button onclick=&quot;pageBack()&quot; id=&quot;back&quot; style=&quot;  width: 75px;
  height: 35px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius:  4px;
  cursor: pointer;
  border: none;
  background-color: #659cf4;&quot;&gt;뒤로가기&lt;/button&gt;
  &lt;button id=&quot;back&quot; style=&quot;  width: 95px;
  height: 35px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius:  4px;
  cursor: pointer;
  border: none;
  
  margin-left: 12px;
  background-color: #febf00;&quot; onclick=&quot;pageStop()&quot;&gt;뒤로가기 막기&lt;/button&gt;
  &lt;/div&gt;

&lt;script&gt;
function pageBack() {
history.back();}
function pageStop() {
history.pushState(null, null, location.href); 
window.onpopstate = function(event) { 
	history.go(1); 
};

}
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>뒤로가기</category>
      <category>뒤로가기 막기</category>
      <category>뒤로가기 이벤트</category>
      <category>링크</category>
      <category>막기</category>
      <category>이전페이지</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/192</guid>
      <comments>https://gurtn.tistory.com/192#entry192comment</comments>
      <pubDate>Wed, 25 Jan 2023 01:35:53 +0900</pubDate>
    </item>
    <item>
      <title>[CSS] 스크롤바 없애기(숨기기)</title>
      <link>https://gurtn.tistory.com/191</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;파이어폭스와 익스플로러는 기타 브라우저와 다른 코드를 적용해줘야합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/RwBNYyZ?default-tab=css%2Cresult&quot; width=&quot;100%;&quot; height=&quot;400&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/RwBNYyZ&quot;&gt;
  Scrollbar hide&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671636526590&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* ( 크롬, 사파리, 오페라, 엣지 ) 동작 */
.scroll::-webkit-scrollbar {
  display: none;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영역::-webkit-scrollbar&lt;/b&gt;&lt;span&gt; :&lt;/span&gt;&amp;nbsp;스크롤바 영역에 대한 설정으로 display: none 속성으로 스크롤바를 없앨 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1671636636616&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.scroll {
  -ms-overflow-style: none; /* 인터넷 익스플로러 */
  scrollbar-width: none; /* 파이어폭스 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;익스플로러, 파이어폭스는 -webkit-scrollbar 코드로 동작이 되지 않으며, 스크롤바를 숨기기 위해서는 다음과 같은 코드를 작성해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;스크롤 기능 없애기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671637327018&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.scroll {
  overflow: hidden;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;overflow: hidden 속성을 해당 요소의 영역을 벗어나는 자식들을 보이지 않도록 해주는 속성입니다. 영역을 초과할 일이 없으니 스크롤바도 생기지 않고, 기능도 사라지게 됩니다.&lt;/p&gt;</description>
      <category>HTML, CSS/코드</category>
      <category>CSS</category>
      <category>HTML</category>
      <category>JS</category>
      <category>scroll</category>
      <category>숨기기</category>
      <category>스크롤</category>
      <category>스크롤 기능</category>
      <category>스크롤바</category>
      <category>스크롤바 숨기기</category>
      <category>스크롤바 없애기</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/191</guid>
      <comments>https://gurtn.tistory.com/191#entry191comment</comments>
      <pubDate>Fri, 23 Dec 2022 02:01:19 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 중복없는 특정 범위의 랜덤 숫자 배열</title>
      <link>https://gurtn.tistory.com/190</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 예제&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/poZvPdy?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;400&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/poZvPdy&quot;&gt;
  Lotto  Number&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Set 객체&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671596472066&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function getRandomNumber(max, min = 1) {
  return Math.floor(Math.random() * max) + min;
}

function getUniqueNumberList(count, max, min = 1) {
  const list = new Set();

  while (count &amp;gt; list.size) {
    list.add(getRandomNumber(max, min));
  }

  return [...list];
}

getUniqueNumberList(3, 10);
// [4, 7, 9]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Set 객체를 활용하면 중복된 값을 제거할 수 있습니다. 매번 중복된 값을 뽑아서 Set 객체에는 단 하나의 동일한 값만 존재하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max, min 값으로 랜덤으로 뽑을 숫자 범위를 지정해주고 배열 길이만큼 Set 객체가 채워질 때까지 반복해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;indexOf 활용&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671596633549&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function getRandomNumber(max, min = 1) {
  return Math.floor(Math.random() * max) + min;
}

function isUniqueNumber(list, number) {
  return list.indexOf(number) === -1;
}

function getUniqueNumberList(count, max, min = 1) {
  const list = [];

  while (count &amp;gt; list.length) {
    const randomNumber = getRandomNumber(max, min);

    if (isUniqueNumber(list, randomNumber)) {
      list.push(randomNumber);
    }
  }

  return list;
}

getUniqueNumberList(3, 10);
// [1, 6, 7]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 방식으로 구현되었지만, 다른 부분으로는 indexOf 메서드를 사용해서 중복 여부를 판단한다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 아무래도 배열로 숫자를 관리하다 보니 값이 너무 커지면 속도가 현저히 떨어진다는 문제점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>랜덤</category>
      <category>로또</category>
      <category>범위</category>
      <category>숫자 배열</category>
      <category>자바스크립트</category>
      <category>중복</category>
      <category>추첨</category>
      <category>특정 범위</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/190</guid>
      <comments>https://gurtn.tistory.com/190#entry190comment</comments>
      <pubDate>Thu, 22 Dec 2022 01:06:18 +0900</pubDate>
    </item>
    <item>
      <title>[JS] Element 크기 변화 감지 (ResizeObserver)</title>
      <link>https://gurtn.tistory.com/189</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;tistory.gif&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qZO5E/btrTSwkM2fI/X9XAobvUd5n7rKJNF8QDJk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qZO5E/btrTSwkM2fI/X9XAobvUd5n7rKJNF8QDJk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qZO5E/btrTSwkM2fI/X9XAobvUd5n7rKJNF8QDJk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/qZO5E/btrTSwkM2fI/X9XAobvUd5n7rKJNF8QDJk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;564&quot; height=&quot;373&quot; data-filename=&quot;tistory.gif&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;window창은 resize 이벤트를 이용해서 창 크기 변화를 감지할 수 있습니다. 하지만 div, p와 같은 HTML 태그들은 resize 이벤트에 해당하지 않습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;ResizeObserver API&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671372206738&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const $target = document.querySelector('div');

const observer = new ResizeObserver((entries) =&amp;gt; {
  // 관찰 중인 배열 형식의 객체 리스트
  entries.forEach((entry) =&amp;gt; {
    ...
  });
});

// 크기변화를 관찰할 요소지정
observer.observe($target);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Resize Observer API는 resize 이벤트와 다르게 설정한 요소의 크기 변화를 관찰하며, 크기가 변경될 때마다 관찰자에게 정보를 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Callback&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671372323415&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const observer = new ResizeObserver((entries, observer) =&amp;gt; {
  // 관찰 중인 배열 형식의 객체 리스트
  entries.forEach((entry) =&amp;gt; {
    ...
  });
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;observe 메서드로 등록한 요소의 크기가 변할 때, ResizeObserver Callback 함수에 값이 담겨옵니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Entries
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관찰되고 있는 ResizeObserverEntry 데이터 리스트를 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Observer
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;콜백 함수가 호출되는 ResizeObserver의 참조 객체&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Entry Object&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Entries - 객체 리스트의 각&amp;nbsp;Entry 객체는 아래와 같이 구성되어 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;contentBoxSize &lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관찰된 요소의 테두리 상자 크기 객체 (content)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;borderBoxSize &lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관찰된 요소의 테두리 상자 크기 객체 (content + padding + border)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;contentRect &lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 두 BoxSize보다 많은 정보를 담고 있는 객체입니다. 하지만 그에 따른 웹 호환성 문제로 작동하지 않을 수도 있습니다. (&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly&quot;&gt;BoxSize&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;devicePixelContentBoxSize &lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관찰된 요소의 테두리 상자 크기 객체&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;target&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관찰되는 대상 요소(Element, SVGElement)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;unobserver()&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671372584288&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;observer.unobserver($target);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 대상에 대한 크기 관찰을 해제할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;disconnect()&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671372598552&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;observer.disconnect();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 대상을 대상으로 크기 관찰이 해제됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예시 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/jOpNROX?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;400&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/jOpNROX&quot;&gt;
  Div Resize + ResizeObserver&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/JjZVKVB?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;460&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/JjZVKVB&quot;&gt;
  Sidebar + ResizeObserver&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>div 사이즈</category>
      <category>element</category>
      <category>event</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>resize</category>
      <category>width 변화</category>
      <category>자바스크립트</category>
      <category>크기 변화</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/189</guid>
      <comments>https://gurtn.tistory.com/189#entry189comment</comments>
      <pubDate>Wed, 21 Dec 2022 01:22:26 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 키보드 단축키 만들기</title>
      <link>https://gurtn.tistory.com/188</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;keydown Event에 담겨오는 다양한 키 정보를 이용해서 단축키를 생성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/yLEwPro?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;451&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/yLEwPro&quot;&gt;
  JS hotkey&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670513005102&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;document.addEventListener('keydown', (event) =&amp;gt; {
  event.preventDefault();
  
  // keyCode
  if (event.keyCode === 67 &amp;amp;&amp;amp; event.shiftKey) {
    alert('Shift + C 단축키');
    return false;
  }
  
  // key
  if (event.key === 'v' &amp;amp;&amp;amp; event.altKey &amp;amp;&amp;amp; event.ctrlKey) {
    alert('Ctrl + V + ALT 단축키');
    return false;
  }
  
  // code
  if (event.code === 'KeyD' &amp;amp;&amp;amp; event.altKey) {
    alert('ALT + D 단축키');
    return false;
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;event.preventDefault() 메서드는&amp;nbsp;기존에 존재하는 단축키(Ctrl + C - 복사하기)를 막을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축키를 지정하는 방법으로는 keydown event가 실행될 때, keyCode, key, code, altKey, shiftKey... 등의 값을 이용해서 단축키를 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;event ( keyCode, key, code )&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;keyCode
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대소문자 영향은 받지 않는다. ('C' -&amp;gt; 67, 'c' -&amp;gt; 67)&lt;/li&gt;
&lt;li&gt;한영 변환에 따른 keyCode 값이 다르다.&lt;/li&gt;
&lt;li&gt;원하는 키를 찾기 위해서 별도의 찾는 과정이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;key
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대소문자 영향을 받는다. ('S', 's')&lt;/li&gt;
&lt;li&gt;Shift를 누른 상태의 단축키를 만들려면 &lt;b&gt;'s'가 아닌 'S'로 비교해야 한다!&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;code
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;key 배열의 값을 가져오기에 대소문자, 한영 변환 영향이 없다.&lt;/li&gt;
&lt;li&gt;숫자와 같이 규칙이 없어서, 필요 키의 코드를 찾는 과정이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 조건문에 &lt;b&gt;return false;&lt;/b&gt; 코드를 추가해서 다른 단축키와 중복으로 겹치는 사태를 막았지만, 만약 여러 단축키를 동시에 가능하게 만들려면, 저 구문을 제거하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;keycode 리스트&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://gcctech.org/csc/javascript/javascript_keycodes.htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://gcctech.org/csc/javascript/javascript_keycodes.htm&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670513221449&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;JavaScript Keycodes&quot; data-og-description=&quot;JavaScript KeyCode In every browser there are three possible kinds of client-side events triggered when a keyboard key is pressed or released: keydown event keypress event keyup event The keydown event occurs when the keyboard key is pressed, and it is fol&quot; data-og-host=&quot;gcctech.org&quot; data-og-source-url=&quot;http://gcctech.org/csc/javascript/javascript_keycodes.htm&quot; data-og-url=&quot;http://gcctech.org/csc/javascript/javascript_keycodes.htm&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://gcctech.org/csc/javascript/javascript_keycodes.htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://gcctech.org/csc/javascript/javascript_keycodes.htm&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript Keycodes&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript KeyCode In every browser there are three possible kinds of client-side events triggered when a keyboard key is pressed or released: keydown event keypress event keyup event The keydown event occurs when the keyboard key is pressed, and it is fol&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gcctech.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>Hotkey</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>keydown</category>
      <category>react</category>
      <category>단축키</category>
      <category>단축키 방지</category>
      <category>자바스크립트</category>
      <category>키보드</category>
      <category>키보드 이벤트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/188</guid>
      <comments>https://gurtn.tistory.com/188#entry188comment</comments>
      <pubDate>Fri, 9 Dec 2022 01:17:30 +0900</pubDate>
    </item>
    <item>
      <title>[JS] Sort(), 다중 조건 정렬</title>
      <link>https://gurtn.tistory.com/187</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;단일 조건&lt;/blockquote&gt;
&lt;pre id=&quot;code_1668955938791&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const data = [
  { age: 19, name: '김씨' }, 
  { age: 25, name: '박씨' }, 
  { age: 18, name: '김씨' }, 
  { age: 19, name: '나씨' },
];

data.sort((a, b) =&amp;gt; a.age - b.age);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 데이터에서 정렬을 시켜주면, age(나이)가 같은 값은 정렬이 되지 않습니다. 이를 해결하기 위해선 다중 조건으로 정렬을 해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;다중 조건&lt;/blockquote&gt;
&lt;pre id=&quot;code_1668955828792&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const data = [
  { age: 19, name: '김씨' }, 
  { age: 25, name: '박씨' }, 
  { age: 18, name: '김씨' }, 
  { age: 19, name: '나씨' },
];

data.sort((a, b) =&amp;gt; a.age - b.age || a.name.localeCompare(b.name));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;age(나이) 값이&lt;b&gt; 같은 경우&lt;/b&gt;에는 이름순으로 정렬하는 코드, 즉 다중 조건으로 정렬시키는 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞부분 조건이 음수, 양수가 아닌 0(서로 같다)의 결과가 나오게 되면 &lt;b&gt;OR연산자에 의해서 두 번째 조건&lt;/b&gt;으로 판단하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1668955833853&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data.sort((a, b) =&amp;gt; 첫번째 조건 || 두번째 조건);
// 0, 음수, 양수&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0, 음수, 양수의 값이 나오는 조건만을 이용해서 정렬을 시킬 수 있다면 다음과 같은 코드로 구현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1668955838815&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;console.log(-1 || 'test');
// -1

console.log(0 || 'test');
// 'test'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OR 연산자는 앞부분이 참일 경우, 앞부분을 그 외에는 뒷부분을 반환해주는 연산자입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/184&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gurtn.tistory.com/184&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668956303858&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JS] 문자열 배열 정렬 (영어,한글)&quot; data-og-description=&quot;자바스크립트에는 배열 데이터를 정렬시켜주는 sort 메서드가 존재합니다. Array.sort() 메서드 const data = ['a가가', '나나', 'ac', '가가', 'aa']; data.sort(); console.log(data); // ['aa', 'ac', 'a가가', '가가', '나나&quot; data-og-host=&quot;gurtn.tistory.com&quot; data-og-source-url=&quot;https://gurtn.tistory.com/184&quot; data-og-url=&quot;https://gurtn.tistory.com/184&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DZvxG/hyQDAWZZv0/LlUcgDNrP0C7bipgMz30P1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/7VrSr/hyQDvg2VFj/MhIO4nEbpmiWcdrN6az9vK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/184&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gurtn.tistory.com/184&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DZvxG/hyQDAWZZv0/LlUcgDNrP0C7bipgMz30P1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/7VrSr/hyQDvg2VFj/MhIO4nEbpmiWcdrN6az9vK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JS] 문자열 배열 정렬 (영어,한글)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트에는 배열 데이터를 정렬시켜주는 sort 메서드가 존재합니다. Array.sort() 메서드 const data = ['a가가', '나나', 'ac', '가가', 'aa']; data.sort(); console.log(data); // ['aa', 'ac', 'a가가', '가가', '나나&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gurtn.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>sort</category>
      <category>다중</category>
      <category>다중 조건</category>
      <category>배열</category>
      <category>우선순위</category>
      <category>자바스크립트</category>
      <category>정렬</category>
      <category>조건</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/187</guid>
      <comments>https://gurtn.tistory.com/187#entry187comment</comments>
      <pubDate>Mon, 21 Nov 2022 00:16:26 +0900</pubDate>
    </item>
    <item>
      <title>[JS] getWeek(), 특정 날짜가 몇주차인지 구하기</title>
      <link>https://gurtn.tistory.com/186</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const getWeek = (date) =&amp;gt; {
  const currentDate = date.getDate();
  const firstDay = new Date(date.setDate(1)).getDay();

  return Math.ceil((currentDate + firstDay) / 7);
};

const week = getWeek(new Date(&quot;2022-11-11&quot;));
console.log(week + &quot;주차&quot;);
// 2주차&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2022-11-11와 같은 Date 객체를 넘길 시, 해당 날짜가 위치한 주차를 구해서 반환해주는 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1668955726964&quot; class=&quot;qml&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const date = new Date('2022-11-11');

const currentDate = date.getDate();
// 11
const day = date.getDay();
// 5&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Date.getDate()
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 메서드는 주어진 날짜의 일을 반환합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Date.getDay()
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 메서드는 주어진 날짜의 요일 정보를 반환합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1668955143806&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const 당일 = date.getDate()
const 첫요일 = new Date(date.setDate(1)).getDay();

Math.ceil((당일 + 첫요일) / 7)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1주 차, 2주 차 등의 주차를 구하는 수식에는 첫 요일 정보가 추가로 필요로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요일 계산을 안 할시 아래와 같이 오차가 생기게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled-3 copy.jpg&quot; data-origin-width=&quot;701&quot; data-origin-height=&quot;295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KXJd5/btrRJO7A7jf/w9kyc7yJV7SvA9mB3Nm2Ok/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KXJd5/btrRJO7A7jf/w9kyc7yJV7SvA9mB3Nm2Ok/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KXJd5/btrRJO7A7jf/w9kyc7yJV7SvA9mB3Nm2Ok/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKXJd5%2FbtrRJO7A7jf%2Fw9kyc7yJV7SvA9mB3Nm2Ok%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;744&quot; height=&quot;313&quot; data-filename=&quot;Untitled-3 copy.jpg&quot; data-origin-width=&quot;701&quot; data-origin-height=&quot;295&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 달력의 11월 시작은 화요일입니다. 이를 무시하고 날짜를 구하게 되면 2일씩 날짜가 당겨지게 됩니다.&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>date</category>
      <category>getWeek</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>날짜</category>
      <category>몇주</category>
      <category>몇주차</category>
      <category>월주차</category>
      <category>자바스크립트</category>
      <category>주차</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/186</guid>
      <comments>https://gurtn.tistory.com/186#entry186comment</comments>
      <pubDate>Sun, 20 Nov 2022 23:47:41 +0900</pubDate>
    </item>
    <item>
      <title>[JS] HEX, RGB 색상코드 변환하기</title>
      <link>https://gurtn.tistory.com/185</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;color.gif&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xZeuY/btrRJQxz3vu/E71gjqVWnBpvm9eY6Ebwc0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xZeuY/btrRJQxz3vu/E71gjqVWnBpvm9eY6Ebwc0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xZeuY/btrRJQxz3vu/E71gjqVWnBpvm9eY6Ebwc0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/xZeuY/btrRJQxz3vu/E71gjqVWnBpvm9eY6Ebwc0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;385&quot; height=&quot;272&quot; data-filename=&quot;color.gif&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔한 웹사이트에서는 색깔을 지정하는 방법으로 HEX(FFFFFF), RGB(255,255,255) 방식의 색상 코드를 많이 사용합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;완성 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/dyerMRy?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;400&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/dyerMRy&quot;&gt;
  RGB to HEX&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HEX
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;영어 16의 줄임말로 10진수를 16진수로 변환시켜 사용하는 색깔 코드입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RGB &lt;span&gt;(red, green, blue)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 세 가지의 10진수 색상이(0~255) 조합된 색깔 코드입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 &amp;rarr; 255, 255, 255 = ( FFFFFF )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1668953884543&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const getHEX = (RGB) =&amp;gt; {  
  const colors = RGB.split(&quot;,&quot;);
  
  return colors
    .map(color =&amp;gt; Number(color)
    .toString(16)
    .padStart(2, '0'))
    .join('');
}

const HEX = getHEX('255,255,255');
// ffffff&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RGB 값을 넣으면 HEX 색상 코드가 반환되는 함수입니다. 콤마를 기준으로 문자를 나누고 &lt;b&gt;toString() 메서드를 이용해서 16진수로 바꿔줍니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1668954360541&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const getRGB = (HEX) =&amp;gt; {
  return HEX.match(/.{2}/g)?.map(replacer =&amp;gt; parseInt(replacer, 16) || 0);
}

const RGB = getRGB('FFFFFF');
// [255, 255, 255]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HEX 값을 넣으면 RGB 색생을 담은 배열이 반환되는 함수입니다. 최대 숫자인 255의 16진수(FF)를 탐지하여 &lt;b&gt;parseInt() 메서드를 이용해서 16진수를 10진수로 바꿔줍니다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>CSS</category>
      <category>HEX</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>RGB</category>
      <category>바꾸기</category>
      <category>변환</category>
      <category>색</category>
      <category>색깔</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/185</guid>
      <comments>https://gurtn.tistory.com/185#entry185comment</comments>
      <pubDate>Sun, 20 Nov 2022 23:32:47 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 문자열 배열 정렬 (영어,한글)</title>
      <link>https://gurtn.tistory.com/184</link>
      <description>&lt;figure id=&quot;og_1681132857957&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다.&quot; data-og-description=&quot;한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/hyukson/hangul-util&quot; data-og-url=&quot;https://github.com/hyukson/hangul-util&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhjLbd/hySeUFsmDj/SSKeIKBRlZdDI3Zu21jjE0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/hyukson/hangul-util&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/hyukson/hangul-util&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhjLbd/hySeUFsmDj/SSKeIKBRlZdDI3Zu21jjE0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;'hangul-util' 라이브러리 코드를 기반으로 작성된 포스트입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681046108552&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sortByASC(['멜론', '귤', '참외']);
// [ '귤', '멜론', '참외' ]

sortByGroups([&quot;대리&quot;, &quot;사원&quot;, &quot;사장&quot;, &quot;회장&quot;, &quot;부장&quot;], groups);
// [ '회장', '사장', '부장', '대리', '사원' ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Array.sort() 메서드&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const data = ['a가가', '나나', 'ac', '가가', 'aa'];

data.sort();

console.log(data);
// ['aa', 'ac', 'a가가', '가가', '나나']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 sort 메서드는 인자 값(compareFunction)을 생략하게 되면 유니코드 값에 따라 오름차순 정렬됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;비교 연산자 사용하기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1666200135811&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;'가나가' &amp;gt; '가나나' // false
'b' &amp;gt; 'a' // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트에서는 비교 연산자를 이용해서 문자열을 비교할 수 있습니다. 이를 이용해서 서로의 문자열을 비교하여 정렬시켜줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// 오름차순 (ASC)
['a가가', '나나', 'ac', '가가', 'aa'].sort((a, b) =&amp;gt; a &amp;gt; b ? 1 : -1);

// 내림차순 (DESC)
['a가가', '나나', 'ac', '가가', 'aa'].sort((a, b) =&amp;gt; a &amp;gt; b ? -1 : 1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;localeCompare 메서드 사용하기&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// 오름차순
['a가가', '나나', 'ac', '가가', 'aa'].sort((a, b) &amp;rArr; a.localeCompare(b));
// 내림차순
['a가가', '나나', 'ac', '가가', 'aa'].sort((a, b) &amp;rArr; b.localeCompare(a));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localeCompare 메서드는 문자열의 사전상 순서에서 해당 문자가 뒤에 있는지 앞에 있는지 또는 같은지를 판단하여 1, 0, -1의 반환 값을 주는 메서드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;sort 메서드는 0과 음수, 양수의 반환 값을 필요로 하기에 &lt;b&gt;localeCompare()&lt;/b&gt; 메서드로 쉽게 구현할 수 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;객체 배열 정렬&lt;/blockquote&gt;
&lt;pre id=&quot;code_1666200561087&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const data = [{ name: '노란색' }, { name: '초록색' }, { name: '검정색' }];

// 비교연산자
[...data].sort((a, b) =&amp;gt; a.name &amp;gt; b.name ? 1 : -1);

// localeCompare 메서드
[...data].sort((a, b) =&amp;gt; a.name.localeCompare(b.name));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체로 구성된 배열을 정렬시키는 방법은 정렬을 시켜주는 기준을 객체의 Value 값으로 잡아서 비교해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;특정값 정렬 기준 만들기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1666711521836&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 정렬 기준
const orderBy = ['회장', '사장', '부장', '과장', '사원'];

const data = ['사장', '사원', '회장', '부장', '과장', '사원'];

data.sort((a, b) =&amp;gt; orderBy.indexOf(a) - orderBy.indexOf(b));
// [ &quot;회장&quot;, &quot;사장&quot;, &quot;부장&quot;, &quot;과장&quot;, &quot;사원&quot;, &quot;사원&quot; ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직급 순과 같이, 가나다순 정렬이 아닌 특정한 정렬의 기준을 만들어서 정렬시켜줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1666201064101&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Array.prototype.sort() - JavaScript | MDN&quot; data-og-description=&quot;sort() 메서드는 배열의 요소를 적절한 위치에 정렬한 후 그 배열을 반환합니다. 정렬은 stable sort가 아닐 수 있습니다. 기본 정렬 순서는 문자열의 유니코드 코드 포인트를 따릅니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BatwN/hyQarrXfcf/zlagLLPdtk3XksoUlKasK1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BatwN/hyQarrXfcf/zlagLLPdtk3XksoUlKasK1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Array.prototype.sort() - JavaScript | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;sort() 메서드는 배열의 요소를 적절한 위치에 정렬한 후 그 배열을 반환합니다. 정렬은 stable sort가 아닐 수 있습니다. 기본 정렬 순서는 문자열의 유니코드 코드 포인트를 따릅니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1666201085414&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;String.prototype.localeCompare() - JavaScript | MDN&quot; data-og-description=&quot;The localeCompare() method returns a number indicating whether a reference string comes before, or after, or is the same as the given string in sort order.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmrMwz/hyQaqmgUOx/KZZkVXtwJovMNueQvJ1q9K/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmrMwz/hyQaqmgUOx/KZZkVXtwJovMNueQvJ1q9K/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;String.prototype.localeCompare() - JavaScript | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The localeCompare() method returns a number indicating whether a reference string comes before, or after, or is the same as the given string in sort order.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>sort</category>
      <category>문자 정렬</category>
      <category>배열</category>
      <category>영어</category>
      <category>자바스크립트</category>
      <category>정렬</category>
      <category>헌굴</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/184</guid>
      <comments>https://gurtn.tistory.com/184#entry184comment</comments>
      <pubDate>Thu, 20 Oct 2022 02:49:10 +0900</pubDate>
    </item>
    <item>
      <title>[JS] SVG 다운로드 (내보내기), PNG로 변환</title>
      <link>https://gurtn.tistory.com/183</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDUORe/btrLugqpQYK/HYegiIckUZ8QEkRCeUCim0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDUORe/btrLugqpQYK/HYegiIckUZ8QEkRCeUCim0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDUORe/btrLugqpQYK/HYegiIckUZ8QEkRCeUCim0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDUORe%2FbtrLugqpQYK%2FHYegiIckUZ8QEkRCeUCim0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;SVG 다운로드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1662434336286&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const $svg = document.querySelector(&quot;svg&quot;);

const data = new XMLSerializer().serializeToString($svg);
const blob = new Blob([data], {type: &quot;image/svg+xml;charset=utf-8&quot;});

const $link = document.createElement(&quot;a&quot;);
  
$link.download = &quot;export.svg&quot;;
$link.href = URL.createObjectURL(blob);
  
$link.click();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SVG의 텍스트 데이터를 추출해 Blob 객체를 만들어주고 &lt;b&gt;URL.createObjectURL 메서드&lt;/b&gt;를 이용한 다운로드 URL을 사용해 다운로드하는 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1662436073728&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// svg의 텍스트 데이터 추출
const data = new XMLSerializer().serializeToString($svg);

// 다운로드를 위한 blob 객체 생성
const blob = new Blob([data], {type: &quot;image/svg+xml;charset=utf-8&quot;});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;svg를 다운로드하기 위해서는 svg의 텍스트 데이터를 가져와야 합니다. 이때 &lt;b&gt;XMLSerializer.serializeToString() 메서드&lt;/b&gt;를 사용하면 svg의 텍스트 데이터를 추출할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그 후 다운로드 용 URL을 만들기 위해서 필요한 Blob 객체를 생성해줍니다. 생성된 Blob 객체를 이용하여 url을 생성해주고, a태그의 download 속성을 이용해서 다운로드해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1662441029829&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const $link = document.createElement(&quot;a&quot;);
  
// 다운로드 될 파일명
$link.download = &quot;export.svg&quot;;
$link.href = URL.createObjectURL(blob);
  
$link.click();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 Blob 객체를 이용해 다운로드가 가능한 URL을 생성해주고, a태그의 download 속성을 이용해서 다운로드시켜줍니다.&lt;/p&gt;

&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예시 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/gOzpRxg?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;420&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/gOzpRxg&quot;&gt;
  Untitled&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;SVG를 PNG로 변환&lt;/blockquote&gt;
&lt;pre id=&quot;code_1662434406454&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const $svg = document.querySelector(&quot;svg&quot;);

const data = new XMLSerializer().serializeToString($svg);
const blob = new Blob([data], {type: &quot;image/svg+xml;charset=utf-8&quot;});

const $canvas = document.createElement(&quot;canvas&quot;);

const {width, height} = $svg.getBoundingClientRect();

$canvas.width = width; 
$canvas.height = height;

const ctx = $canvas.getContext('2d');

const img = new Image();

img.onload = (e) =&amp;gt; {
    ctx.drawImage(e.target, 0, 0);

    const $link = document.createElement(&quot;a&quot;);

    $link.download = &quot;image.png&quot;;
    $link.href = $canvas.toDataURL(&quot;image/png&quot;);

    $link.click();
};

img.src = URL.createObjectURL(blob);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 방식은 SVG 다운로드 코드를 응용한 코드로, CanvasRenderingContext2D.drawImage 메서드를 이용해서 캔버스에 svg를 그려주고 toDataURL로 다운로드하는 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/KKRpvXj?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;430&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/KKRpvXj&quot;&gt;
  SVG Download to PNG&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;도움받은 자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codepen.io/aster_mnch/pen/qBVKoNP&quot;&gt;https://codepen.io/aster_mnch/pen/qBVKoNP&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662435887925&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Download SVG&quot; data-og-description=&quot;...&quot; data-og-host=&quot;codepen.io&quot; data-og-source-url=&quot;https://codepen.io/aster_mnch/pen/qBVKoNP&quot; data-og-url=&quot;https://codepen.io/aster_mnch/details/qBVKoNP&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bycj7r/hyPHhKTMWD/OeJahVpZzeZ6QTO1zL34GK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/3zZ3o/hyPHmSY9Nc/o387NCm684rK9YMmIwioz1/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450&quot;&gt;&lt;a href=&quot;https://codepen.io/aster_mnch/pen/qBVKoNP&quot; data-source-url=&quot;https://codepen.io/aster_mnch/pen/qBVKoNP&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bycj7r/hyPHhKTMWD/OeJahVpZzeZ6QTO1zL34GK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/3zZ3o/hyPHmSY9Nc/o387NCm684rK9YMmIwioz1/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Download SVG&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codepen.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://qiita.com/aster-mnch/items/d89f1d1be43d89a6fe70&quot;&gt;https://qiita.com/aster-mnch/items/d89f1d1be43d89a6fe70&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662435887926&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SVG イメージを JavaScript から保存する方法 - Qiita&quot; data-og-description=&quot;GitHub に Mermaid がサポートされるようになったので、マークダウン中にいい感じのグラフを描画できるようになりましたね。 しかし、 Mermaid で作成される画像は SVG 形式なので、ブラウザから&quot; data-og-host=&quot;qiita.com&quot; data-og-source-url=&quot;https://qiita.com/aster-mnch/items/d89f1d1be43d89a6fe70&quot; data-og-url=&quot;https://qiita.com/aster-mnch/items/d89f1d1be43d89a6fe70&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pAHRo/hyPHh5dj8U/7oZoRzOk1JTYBc7ovu1IkK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://qiita.com/aster-mnch/items/d89f1d1be43d89a6fe70&quot; data-source-url=&quot;https://qiita.com/aster-mnch/items/d89f1d1be43d89a6fe70&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pAHRo/hyPHh5dj8U/7oZoRzOk1JTYBc7ovu1IkK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SVG イメージを JavaScript から保存する方法 - Qiita&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;GitHub に Mermaid がサポートされるようになったので、マークダウン中にいい感じのグラフを描画できるようになりましたね。 しかし、 Mermaid で作成される画像は SVG 形式なので、ブラウザから&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;qiita.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>download</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>PNG</category>
      <category>react</category>
      <category>SVG</category>
      <category>내보내기</category>
      <category>다운로드</category>
      <category>이미지</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/183</guid>
      <comments>https://gurtn.tistory.com/183#entry183comment</comments>
      <pubDate>Tue, 6 Sep 2022 14:09:39 +0900</pubDate>
    </item>
    <item>
      <title>[CSS] 스크롤에 따라 움직이는 배경 이미지</title>
      <link>https://gurtn.tistory.com/182</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;rfet.gif&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l4Ppf/btrLr3EuU99/FzCVsFX3GL0i4kE2l9B9N0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l4Ppf/btrLr3EuU99/FzCVsFX3GL0i4kE2l9B9N0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l4Ppf/btrLr3EuU99/FzCVsFX3GL0i4kE2l9B9N0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/l4Ppf/btrLr3EuU99/FzCVsFX3GL0i4kE2l9B9N0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;898&quot; height=&quot;493&quot; data-filename=&quot;rfet.gif&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1662394407882&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;background-attachment: fixed;
/* background-image에만 적용 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;background-attachment 속성은 background-image에 적용되며, 배경 이미지를 스크롤 시에도 고정시켜서 마치 따라오는 듯한 효과를 줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- scroll(기본값) : 스크롤 시 페이지와 함께 같이 움직이는 속성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- fixed : 스크롤 시 보이는 페이지(viewport)와는 다르게 배경 이미지는 고정됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/rNvaPmp?default-tab=2Cresult&quot; width=&quot;100%;&quot; height=&quot;582&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/rNvaPmp&quot;&gt;
  CSS Background Image attachment&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre id=&quot;code_1662395025288&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;color&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;image&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;color&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배경을 채운 디자인 요소와 그 사이에 배경 이미지로 쓰일 요소를 추가해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1662395002447&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;div {
  width: 100%;
  height: 100vh;
  position: relative;
}

.image {
  background: 
    url(https://cdn.pixabay.com/photo/2022/08/23/06/55/village-7405160_960_720.jpg) 
    no-repeat;
  background-attachment: fixed;
}

.color {
  background: #000;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지를 넣어줄 클래스에 background 속성을 이용해서 이미지를 넣어주고, background-attachment 속성을 이용해서 fixed 시켜줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;도움받은 자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/background-attachment&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/CSS/background-attachment&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662394160084&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;background-attachment - CSS: Cascading Style Sheets | MDN&quot; data-og-description=&quot;CSS background-attachment 속성은 배경 이미지를 뷰포트 내에서 고정할지, 아니면 자신의 컨테이닝 블록과 함께 스크롤할지 지정합니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/background-attachment&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/background-attachment&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ow2uc/hyPHqtU9sO/Q5RsyY1arspIXYqWorJ4Fk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/background-attachment&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/background-attachment&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ow2uc/hyPHqtU9sO/Q5RsyY1arspIXYqWorJ4Fk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;background-attachment - CSS: Cascading Style Sheets | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CSS background-attachment 속성은 배경 이미지를 뷰포트 내에서 고정할지, 아니면 자신의 컨테이닝 블록과 함께 스크롤할지 지정합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>HTML, CSS/코드</category>
      <category>CSS</category>
      <category>HTML</category>
      <category>고정</category>
      <category>따라 움직임</category>
      <category>배경</category>
      <category>배경 이미지</category>
      <category>스크롤</category>
      <category>애니메이션</category>
      <category>이미지</category>
      <category>효과</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/182</guid>
      <comments>https://gurtn.tistory.com/182#entry182comment</comments>
      <pubDate>Tue, 6 Sep 2022 11:35:04 +0900</pubDate>
    </item>
    <item>
      <title>[CSS] 텍스트 세로로 표시하기</title>
      <link>https://gurtn.tistory.com/181</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;텍스트를 세로로 타이핑하는 방법으로 쉬운 방법인 CSS에 존재하는 writing-mode 속성을 소개하겠습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1662214159337&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 세로로 왼쪽 -&amp;gt; 오른쪽 */
writing-mode: vertical-lr;

/* 세로로 오른쪽 -&amp;gt; 왼쪽 */ 
writing-mode: vertical-rl;

/* 영어는 추가로 사용해야함 */
text-orientation: upright;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSS의 writing-mode 속성을 이용해서 세로로 텍스트를 표시해 줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;194&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tv4kH/btrLihP0Na5/mK2DZiikJ2KgjIDB3zak0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tv4kH/btrLihP0Na5/mK2DZiikJ2KgjIDB3zak0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tv4kH/btrLihP0Na5/mK2DZiikJ2KgjIDB3zak0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTv4kH%2FbtrLihP0Na5%2FmK2DZiikJ2KgjIDB3zak0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;332&quot; data-origin-width=&quot;194&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vertical-lr - 왼쪽에서 오른쪽&amp;nbsp;&lt;/li&gt;
&lt;li&gt;vertical-rl - 오른쪽에서 왼쪽&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &lt;b&gt;한글을 타이핑할 때는 세로&lt;/b&gt;로 보이지만, &lt;b&gt;영어로 타이핑될 때는 기존 속성으로는 90 &amp;ordm;&lt;/b&gt; 돌아간 모습으로 표시됩니다. 이를 해결하는 방법으로는 text-orientation 속성을 이용하는 방법이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/poVoBPj?default-tab=css%2Cresult&quot; width=&quot;100%;&quot; height=&quot;547&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/poVoBPj&quot;&gt;
  Vertical Text&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;도움받은 자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Learn/CSS/Building_blocks/Handling_different_text_directions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Learn/CSS/Building_blocks/Handling_different_text_directions&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662214398727&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;텍스트 표시 방향 제어하기 - Web 개발 학습하기 | MDN&quot; data-og-description=&quot;CSS 학습에서 지금까지 경험한 많은 속성과 값은 화면의 크기와 연결되어 있습니다. 예를 들어, 박스의 위, 오른쪽, 아래쪽 및 왼쪽에 테두리를 만듭니다. 이러한 실제 측정 기준은 가로로 표시되&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Learn/CSS/Building_blocks/Handling_different_text_directions&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Learn/CSS/Building_blocks/Handling_different_text_directions&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bb6ZFF/hyPF6hYT5q/xHhibhkK3Ht4gVPTotKWAk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Learn/CSS/Building_blocks/Handling_different_text_directions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Learn/CSS/Building_blocks/Handling_different_text_directions&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bb6ZFF/hyPF6hYT5q/xHhibhkK3Ht4gVPTotKWAk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;텍스트 표시 방향 제어하기 - Web 개발 학습하기 | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CSS 학습에서 지금까지 경험한 많은 속성과 값은 화면의 크기와 연결되어 있습니다. 예를 들어, 박스의 위, 오른쪽, 아래쪽 및 왼쪽에 테두리를 만듭니다. 이러한 실제 측정 기준은 가로로 표시되&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662215482658&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;writing-mode - CSS: Cascading Style Sheets | MDN&quot; data-og-description=&quot;The writing-mode CSS property sets whether lines of text are laid out horizontally or vertically, as well as the direction in which blocks progress. When set for an entire document, it should be set on the root element (html element for HTML documents).&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode&quot; data-og-url=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bepHh0/hyPFW7vWme/Wv6Mlf3vEHwgWDgSkAz4Lk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080,https://scrap.kakaocdn.net/dn/bOaz54/hyPFZJVEt6/pIaaMQb5eRsDtokGqkqXkk/img.png?width=493&amp;amp;height=508&amp;amp;face=0_0_493_508&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bepHh0/hyPFW7vWme/Wv6Mlf3vEHwgWDgSkAz4Lk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080,https://scrap.kakaocdn.net/dn/bOaz54/hyPFZJVEt6/pIaaMQb5eRsDtokGqkqXkk/img.png?width=493&amp;amp;height=508&amp;amp;face=0_0_493_508');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;writing-mode - CSS: Cascading Style Sheets | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The writing-mode CSS property sets whether lines of text are laid out horizontally or vertically, as well as the direction in which blocks progress. When set for an entire document, it should be set on the root element (html element for HTML documents).&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>HTML, CSS/코드</category>
      <category>CSS</category>
      <category>HTML</category>
      <category>text</category>
      <category>방향</category>
      <category>세로</category>
      <category>세로로</category>
      <category>줄바꿈</category>
      <category>타이핑</category>
      <category>텍스트</category>
      <category>표시</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/181</guid>
      <comments>https://gurtn.tistory.com/181#entry181comment</comments>
      <pubDate>Sun, 4 Sep 2022 00:12:20 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 룰렛 구현하기</title>
      <link>https://gurtn.tistory.com/180</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;GIF 2022-08-29 오전 2-16-30.gif&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IDYV4/btrKK9riyQj/M8FlIw4Bi2YRsota5Poz80/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IDYV4/btrKK9riyQj/M8FlIw4Bi2YRsota5Poz80/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IDYV4/btrKK9riyQj/M8FlIw4Bi2YRsota5Poz80/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/IDYV4/btrKK9riyQj/M8FlIw4Bi2YRsota5Poz80/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;465&quot; data-filename=&quot;GIF 2022-08-29 오전 2-16-30.gif&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript와 캔버스(Canvas)를 사용하여 룰렛을 구현해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/xxWNyyq?default-tab=js%2Cresult&quot; width=&quot;100%&quot; height=&quot;620&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/xxWNyyq&quot;&gt;
  Canvas Roulette&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1661705646805&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const $c = document.querySelector(&quot;canvas&quot;);
const ctx = $c.getContext(`2d`);

// 룰렛에 들어갈 항목
const product = [
  &quot;떡볶이&quot;, '돈가스', &quot;초밥&quot;, &quot;피자&quot;, &quot;냉면&quot;, &quot;치킨&quot;, '족발', &quot;피자&quot;, &quot;삼겹살&quot;,
];

// 각 항목에 해당하는 색상
const colors = [
  &quot;#dc0936&quot;, &quot;#e6471d&quot;, &quot;#f7a416&quot;, 
  &quot;#efe61f &quot;, &quot;#60b236&quot;, &quot;#209b6c&quot;, 
  &quot;#169ed8&quot;, &quot;#3f297e&quot;, &quot;#87207b&quot;, 
  &quot;#be107f&quot;, &quot;#e7167b&quot;
];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 룰렛을 그려줄 Canvas 요소와 룰렛에 추가할 상품 목록과 해당하는 색상 배열을 정의해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661707107958&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const newMake = () =&amp;gt; {
    const [cw, ch] = [$c.width / 2, $c.height / 2];
  	const arc = (2 * Math.PI) / product.length;
  
    // 룰렛 배경 그리기
    for (let i = 0; i &amp;lt; product.length; i++) {
        ctx.beginPath();
        ctx.fillStyle = colors[i % colors.length];
        ctx.moveTo(cw, ch);
        ctx.arc(cw, ch, cw - 2, arc * i - Math.PI / 2, arc * (i + 1) - Math.PI / 2);
        ctx.fill();
        ctx.closePath();
    }

    ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;newMake 함수를 정의해주고, 그려줄 캔버스의 중점 위치를 구해야 합니다. 그러기 위해서는 Canvas의 Width, Height 절반의 값을 통해서 얻을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 룰렛에 그릴 항목의 수에 따른 항목의 크기 값을 구해줍니다. 해당 값을 통해 동그란 룰렛에 각 영역을 그리는 방법은 arc 메서드를 이용하는 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;arc 메서드를 호출하기 전에, 색칠할 색상을 변경해주고, 그려줄 펜의 위치를 중점 위치로 옮겨주는 작업을 먼저 해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661707655714&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// x, y -&amp;gt; 중점, radius -&amp;gt; 반지름(x와 같은 값)
ctx.arc(x, y, radius, startAngle, endAngle);

// ctx.arc(cw, ch, cw, arc * (i - 1), arc * i);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 메서드에서 핵심은 &lt;b&gt;startAngle, endAngle 인자입니다.&lt;/b&gt; 항목 개수로 나눈 크기를 이용해서 &lt;b&gt;(i - 1) ~ i&lt;/b&gt; &lt;b&gt;지점까지 만의&lt;/b&gt; 원을 그리는 코드를 작성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661707161719&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    ...
    
    ctx.textAlign = &quot;center&quot;
    
    // 그려진 배경 위에 텍스트 그리기
    for (let i = 0; i &amp;lt; product.length; i++) {
      const angle = arc * i + arc / 2 - Math.PI / 2;

      ctx.save();
      
      ctx.translate(
        cw + Math.cos(angle) * (cw - 50),
        ch + Math.sin(angle) * (ch - 50),
      );
      ctx.rotate(angle + Math.PI / 2);
	
      // 항목명에 띄어쓰기가 있을 시 줄바꿈
      product[i].split(&quot; &quot;).forEach((text, j) =&amp;gt; {
        ctx.fillText(text, 0, 30 * j);
      });

      ctx.restore();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;save, restore 메서드&lt;/b&gt;를 이용해서 속성 값이 적용된 캔버스의 설정 값(이미지 X)을 저장하고 가져올 수 있습니다. translate, rotate로 인해 변형된 &lt;b&gt;콘텍스트 설정 값을 초기값으로 되돌려 주는 작업&lt;/b&gt;을 통해서 텍스트를 그려줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
&lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-7087881904125734&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-format=&quot;autorelaxed&quot; data-ad-client=&quot;ca-pub-7087881904125734&quot; data-ad-slot=&quot;4683556281&quot; data-matched-content-rows-num=&quot;3,1&quot; data-matched-content-columns-num=&quot;1,3&quot; data-matched-content-ui-type=&quot;image_stacked,image_stacked&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
         (adsbygoogle = window.adsbygoogle || []).push({});
    &lt;/script&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661711229482&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 룰렛 돌리기
const rotate = () =&amp;gt; {
	// 룰렛 당첨 결정
    const ran = Math.floor(Math.random() * product.length);
	
    const arc = 360 / product.length;
    const rotate = (360 - arc * (ran + 1) + 3600) + (arc / 3);
    
    $c.style.transform = `rotate(${rotate}deg)`;
    
    return ran;
};

// 함수 호출
const getResult = rotate();

setTimeout(() =&amp;gt; alert(product[getResult]), 2000);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Math.random() 메서드를 통해서 랜덤 한 난수를 얻을 수 있습니다. 해당 수에 항목의 개수를 곱해주면 랜덤 한 당첨 결과를 얻을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜덤 한 결과 값에 영역의 크기를 곱해서 룰렛의 위치를 맞추어주고, 360도를 10번 돌라는 의미의 3600을 추가로 더해줍니다. 추가로 오차범위를 조정하기 위해서 (arc / 3)의 수식을 추가로 사용하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661711677074&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;canvas {
  transition: 2s;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 CSS 코드로 canvas에 transition 속성을 2초 정도로 지정해주면, 완성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1661707518444&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;CanvasRenderingContext2D.arc() - Web APIs | MDN&quot; data-og-description=&quot;The CanvasRenderingContext2D.arc() method of the Canvas 2D API adds a circular arc to the current sub-path.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc&quot; data-og-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/yfUTa/hyPBHvG61x/ZhhCdGNPbNlo97P9NxkKI0/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/yfUTa/hyPBHvG61x/ZhhCdGNPbNlo97P9NxkKI0/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CanvasRenderingContext2D.arc() - Web APIs | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The CanvasRenderingContext2D.arc() method of the Canvas 2D API adds a circular arc to the current sub-path.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/제작</category>
      <category>Canvas</category>
      <category>CSS</category>
      <category>HTML</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>ROULETTE</category>
      <category>룰렛</category>
      <category>자바스크립트</category>
      <category>캔버스</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/180</guid>
      <comments>https://gurtn.tistory.com/180#entry180comment</comments>
      <pubDate>Mon, 29 Aug 2022 03:37:36 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 프로그래머스 두 큐 합 같게 만들기</title>
      <link>https://gurtn.tistory.com/179</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qje20/btrKxPNOSnQ/HDmBUX98DtyeloHAsBvZq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qje20/btrKxPNOSnQ/HDmBUX98DtyeloHAsBvZq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qje20/btrKxPNOSnQ/HDmBUX98DtyeloHAsBvZq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqje20%2FbtrKxPNOSnQ%2FHDmBUX98DtyeloHAsBvZq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;출처&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118667&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/118667&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1661413693805&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118667&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118667&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118667&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;문제&lt;br /&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길이가&amp;nbsp;같은&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;큐를&amp;nbsp;나타내는&amp;nbsp;정수&amp;nbsp;배열&amp;nbsp;queue1,&amp;nbsp;queue2가&amp;nbsp;매개변수로&amp;nbsp;주어집니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각&amp;nbsp;큐의&amp;nbsp;원소&amp;nbsp;합을&amp;nbsp;같게&amp;nbsp;만들기&amp;nbsp;위해&amp;nbsp;필요한&amp;nbsp;작업의&amp;nbsp;최소&amp;nbsp;횟수를&amp;nbsp;return&amp;nbsp;하도록&amp;nbsp;solution&amp;nbsp;함수를&amp;nbsp;완성해주세요.&amp;nbsp;단,&amp;nbsp;어떤&amp;nbsp;방법으로도&amp;nbsp;각&amp;nbsp;큐의&amp;nbsp;원소&amp;nbsp;합을&amp;nbsp;같게&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;경우,&amp;nbsp;-1을&amp;nbsp;return&amp;nbsp;해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;제한사항&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;queue1의 길이 =&lt;span&gt;&amp;nbsp;&lt;/span&gt;queue2의 길이 &amp;le; 300,000&lt;/li&gt;
&lt;li&gt;1 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;queue1의 원소,&lt;span&gt;&amp;nbsp;&lt;/span&gt;queue2의 원소 &amp;le; 10 ^ 9&lt;/li&gt;
&lt;li&gt;주의: 언어에 따라 합 계산 과정 중 산술 오버플로우 발생 가능성이 있으므로 long type 고려가 필요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #263747;&quot;&gt;배열로 큐를 구현하려 시도하니, 너무 많은 메서드 사용과, 연산으로 인해 시간 초과가 발생했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #263747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이럴 때 사용한 방법으로 알고리즘 문제에 자주 등장하는 &lt;span style=&quot;background-color: #ffffff; color: #212529;&quot;&gt;&lt;b&gt;투 포인터(다중 포인터) &lt;/b&gt;알고리즘 방식을 사용하면 다른 원소를 가리키는 다중의 포인터를 조작하면서 원하는 값을 얻을 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 방식을 사용하여 구현하게 되면, 실제로 배열에서 값을 빼고, 넣는 것이 아니기에 불필요한 연산이 줄어들게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 반복 횟수(queue1 길이 * 3) 만큼 돌려주면서, 한쪽 큐의 총합이 목표치보다 높을 시에는 queue1의 pointer 값를 높여주고, 값이 작으면 queue2의 pointer 값을 높여주면서 해당 값을 빼고, 넣는 효과를 통해 총합의 값을 조절해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1648694600133&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(queue1, queue2) {
    let sumQ1 = sum(queue1),
        sumQ2 = sum(queue2);
    
    let pointer1 = 0, 
        pointer2 = queue1.length;
    
    const target = (sumQ1 + sumQ2) / 2;
    const queue = [...queue1, ...queue2];
    
    const end = queue1.length * 3;
    
    for (let count = 0; count &amp;lt; end; count++) {
        if (sumQ1 === target) {
            return count;
        }
        
        if (sumQ1 &amp;gt; target) {
            sumQ1 -= queue[pointer1++];
        } else {
            sumQ1 += queue[pointer2++];
        }
    }
    
    return -1;
}

const sum = (arr) =&amp;gt; arr.reduce((acc, v) =&amp;gt; acc + v, 0);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스 (JS)</category>
      <category>2단계</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>node.js</category>
      <category>두 큐 합 같게 만들기</category>
      <category>알고리즘</category>
      <category>자바스크립트</category>
      <category>코딩테스트 연습</category>
      <category>투포인터</category>
      <category>프로그래머스</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/179</guid>
      <comments>https://gurtn.tistory.com/179#entry179comment</comments>
      <pubDate>Thu, 25 Aug 2022 16:50:42 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 프로그래머스 성격 유형 검사하기</title>
      <link>https://gurtn.tistory.com/178</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dHYOcZ/btrKwVzLaYt/6k4Xn2CaJtaZOI4Akvb6Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHYOcZ/btrKwVzLaYt/6k4Xn2CaJtaZOI4Akvb6Ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHYOcZ/btrKwVzLaYt/6k4Xn2CaJtaZOI4Akvb6Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHYOcZ%2FbtrKwVzLaYt%2F6k4Xn2CaJtaZOI4Akvb6Ok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;출처&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118666&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/118666&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1661397941525&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118666&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/p2wGH/hyPzoCXEhT/zjM5YWWfrPldT4smMMf9Rk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/G5gom/hyPzpoknx2/vgWzvLDhE33Djgzgqwxno1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118666&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118666&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/p2wGH/hyPzoCXEhT/zjM5YWWfrPldT4smMMf9Rk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/G5gom/hyPzpoknx2/vgWzvLDhE33Djgzgqwxno1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;문제&lt;br /&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매우 동의나&lt;span&gt;&amp;nbsp;&lt;/span&gt;매우 비동의&lt;span&gt;&amp;nbsp;&lt;/span&gt;선택지를 선택하면 3점을 얻습니다.&lt;/li&gt;
&lt;li&gt;동의나&lt;span&gt;&amp;nbsp;&lt;/span&gt;비동의&lt;span&gt;&amp;nbsp;&lt;/span&gt;선택지를 선택하면 2점을 얻습니다.&lt;/li&gt;
&lt;li&gt;약간 동의나&lt;span&gt;&amp;nbsp;&lt;/span&gt;약간 비동의&lt;span&gt;&amp;nbsp;&lt;/span&gt;선택지를 선택하면 1점을 얻습니다.&lt;/li&gt;
&lt;li&gt;모르겠음&lt;span&gt;&amp;nbsp;&lt;/span&gt;선택지를 선택하면 점수를 얻지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검사 결과는 모든 질문의 성격 유형 점수를 더하여 각 지표에서 더 높은 점수를 받은 성격 유형이 검사자의 성격 유형이라고 판단합니다. 단, 하나의 지표에서 각 성격 유형 점수가 같으면, 두 성격 유형 중 사전 순으로 빠른 성격 유형을 검사자의 성격 유형이라고 판단합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문마다 판단하는 지표를 담은 1차원 문자열 배열&lt;span&gt;&amp;nbsp;&lt;/span&gt;survey와 검사자가 각 질문마다 선택한 선택지를 담은 1차원 정수 배열&lt;span&gt;&amp;nbsp;&lt;/span&gt;choices가 매개변수로 주어집니다. 이때, 검사자의 성격 유형 검사 결과를 지표 번호 순서대로 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;제한사항&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;survey의 길이 ( =&lt;span&gt;&amp;nbsp;&lt;/span&gt;n) &amp;le; 1,000
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;survey의 원소는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;RT&quot;, &quot;TR&quot;, &quot;FC&quot;, &quot;CF&quot;, &quot;MJ&quot;, &quot;JM&quot;, &quot;AN&quot;, &quot;NA&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;중 하나입니다.&lt;/li&gt;
&lt;li&gt;survey[i]의 첫 번째 캐릭터는 i+1번 질문의 비동의 관련 선택지를 선택하면 받는 성격 유형을 의미합니다.&lt;/li&gt;
&lt;li&gt;survey[i]의 두 번째 캐릭터는 i+1번 질문의 동의 관련 선택지를 선택하면 받는 성격 유형을 의미합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;choices의 길이 =&lt;span&gt;&amp;nbsp;&lt;/span&gt;survey의 길이
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;choices[i]는 검사자가 선택한 i+1번째 질문의 선택지를 의미합니다.&lt;/li&gt;
&lt;li&gt;1 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;choices의 원소 &amp;le; 7&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;매우 비동의&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;비동의&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;약간 비동의&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;모르겠음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;약간 동의&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;동의&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;매우 동의&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;choices의 값이 3보다 크면 동의, 작으면 비동의라고 생각하고 풀이하면 쉬운 문제입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 성격 유형 케이스를 만들어주고, 점수가 3보다 크면 비동의 캐릭터에 점수를 주고, 작을 시 동의 &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;캐릭터&lt;/span&gt;에 점수를 줍니다. 모든 선택지에 점수를 부여한 후, 캐릭터에게 부여된 점수가 더 큰 캐릭터를 반환해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1648694600133&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(survey, choices) {
    const MBTI = {};
    const types = [&quot;RT&quot;,&quot;CF&quot;,&quot;JM&quot;,&quot;AN&quot;];
    
    types.forEach((type) =&amp;gt;
        type.split('').forEach((char) =&amp;gt; MBTI[char] = 0)
    )
    
    choices.forEach((choice, index) =&amp;gt; {
        const [disagree, agree] = survey[index];
        
        MBTI[choice &amp;gt; 4 ? agree : disagree] += Math.abs(choice - 4);
    });

    return types.map(([a, b]) =&amp;gt; MBTI[b] &amp;gt; MBTI[a] ? b : a).join(&quot;&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스 (JS)</category>
      <category>1단계</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>node.js</category>
      <category>성격 유형 검사하기</category>
      <category>알고리즘</category>
      <category>자바스크립트</category>
      <category>카카오</category>
      <category>코딩테스트 연습</category>
      <category>프로그래머스</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/178</guid>
      <comments>https://gurtn.tistory.com/178#entry178comment</comments>
      <pubDate>Thu, 25 Aug 2022 13:21:00 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 캔버스(Canvas) 이미지 다운로드</title>
      <link>https://gurtn.tistory.com/177</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cARsMp/btrJ8ncTVhR/BY079MOgluC657irwDOXPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cARsMp/btrJ8ncTVhR/BY079MOgluC657irwDOXPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cARsMp/btrJ8ncTVhR/BY079MOgluC657irwDOXPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcARsMp%2FbtrJ8ncTVhR%2FBY079MOgluC657irwDOXPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A태그에 존재하는 download 속성과 canvas.toDataURL 메서드를 이용하여 base64 방식의 인코딩 이미지를 다운로드할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예제 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/QWmYmqa?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;470&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/QWmYmqa&quot;&gt;
  drawing&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1660983207642&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 다운로드할 캔버스
const $canvas = document.querySelector(&quot;canvas&quot;);

// A DOM 생성
const $link = document.createElement(&quot;a&quot;);

$link.download = &quot;파일명.png&quot;;
$link.href = $canvas.toDataURL(&quot;image/png&quot;);

// element에 마우스 클릭
$link.click();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;document.createElement 메서드로 가상의 A DOM 요소를 생성해줍니다. 해당 a태그에 download 속성을 부여함으로써, 링크 이동 대신에 다운로드 기능을 이용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;도움받은 자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/HTML/Element/a&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660995404141&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;&amp;lt;a&amp;gt; - HTML: Hypertext Markup Language | MDN&quot; data-og-description=&quot;HTML &amp;lt;a&amp;gt; 요소(앵커 요소)는 href 특성을 통해 다른 페이지나 같은 페이지의 어느 위치, 파일, 이메일 주소와 그 외 다른 URL로 연결할 수 있는 하이퍼링크를 만듭니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/a&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/a&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sCDYd/hyPvZi9RNx/G4zTrgn7vvOneuQCVpjqxk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTML/Element/a&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sCDYd/hyPvZi9RNx/G4zTrgn7vvOneuQCVpjqxk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lt;a&amp;gt; - HTML: Hypertext Markup Language | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;HTML &amp;lt;a&amp;gt; 요소(앵커 요소)는 href 특성을 통해 다른 페이지나 같은 페이지의 어느 위치, 파일, 이메일 주소와 그 외 다른 URL로 연결할 수 있는 하이퍼링크를 만듭니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/click&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/click&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660996256372&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HTMLElement.click() - Web API | MDN&quot; data-og-description=&quot;HTMLElement.click() 메소는 엘리먼트에 마우스 클릭을 시뮬레이션합니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/click&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/click&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bzglwA/hyPvYEyB1n/FmeKwgh0kfB0CA0ihbGAg1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/click&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/click&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bzglwA/hyPvYEyB1n/FmeKwgh0kfB0CA0ihbGAg1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HTMLElement.click() - Web API | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;HTMLElement.click() 메소는 엘리먼트에 마우스 클릭을 시뮬레이션합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>Canvas</category>
      <category>download</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>다운로드</category>
      <category>변환</category>
      <category>이미지</category>
      <category>자바스크립트</category>
      <category>캔버스</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/177</guid>
      <comments>https://gurtn.tistory.com/177#entry177comment</comments>
      <pubDate>Sat, 20 Aug 2022 21:00:06 +0900</pubDate>
    </item>
    <item>
      <title>[CSS] z-index에 딜레이 적용시키기</title>
      <link>https://gurtn.tistory.com/176</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeWy6Q/btrINuksydg/s9nDyd8ESttOxJPX1PCNKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeWy6Q/btrINuksydg/s9nDyd8ESttOxJPX1PCNKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeWy6Q/btrINuksydg/s9nDyd8ESttOxJPX1PCNKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeWy6Q%2FbtrINuksydg%2Fs9nDyd8ESttOxJPX1PCNKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/GRxQeam?default-tab=css%2Cresult&quot; width=&quot;100%;&quot; height=&quot;425&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/GRxQeam&quot;&gt;
  CSS z-index Delay&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1659508018500&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.zIndexDelay {
  animation: zIndex .5s step-end forwards; 
}

@keyframes zIndexDelay {
  to { 
    z-index: 5; 
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;animation-timing-function의 step-end 속성을 이용해서 &lt;b&gt;keyframes의 진행상태가 끝났을 때 적용되도록&amp;nbsp;&lt;/b&gt;지정해줍니다. to 영역에 지정된 z-index가 지정된 애니메이션의 duration 만큼 진행된 후에 적용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;JavaScript 사용하여 구현하기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1659508400913&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.zIndex {
  z-index: 22;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;CSS로 z-index 속성 값이 적용된 클래스를 정의해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659508512909&quot; class=&quot;coffeescript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;setTimeout(() =&amp;gt; {
  요소.classList.add(&quot;zIndex&quot;);
}, 1000);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS의 setTimeout 함수로 딜레이를 준 후 클래스를 추가해 z-index를 적용시켜줍니다.&lt;/p&gt;</description>
      <category>HTML, CSS/코드</category>
      <category>Animation</category>
      <category>CSS</category>
      <category>delay</category>
      <category>HTML</category>
      <category>JS</category>
      <category>transition</category>
      <category>z-index</category>
      <category>딜레이</category>
      <category>애니메이션</category>
      <category>지연</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/176</guid>
      <comments>https://gurtn.tistory.com/176#entry176comment</comments>
      <pubDate>Wed, 3 Aug 2022 15:41:24 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 마우스 이동 방향 판단하기</title>
      <link>https://gurtn.tistory.com/175</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cq1PhG/btrItvLfG0c/ZcGlAc0x0BkNuHDUM2jC31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cq1PhG/btrItvLfG0c/ZcGlAc0x0BkNuHDUM2jC31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cq1PhG/btrItvLfG0c/ZcGlAc0x0BkNuHDUM2jC31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcq1PhG%2FbtrItvLfG0c%2FZcGlAc0x0BkNuHDUM2jC31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마우스 이동방향을 감지하는 가장 쉬운 방법은 이전에 위치했던 마우스 좌표값과 현재 마우스 좌표 값의 대소를 비교하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/NWYwzdb?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;390&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/NWYwzdb&quot;&gt;
  mouse movement direction&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1659092881129&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 이벤트 생성
window.addEventListener(&quot;mousemove&quot;, getMouseDirection);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;마우스의 이동을 감지하는 대표적인 이벤트로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;mousemove&lt;/b&gt;가 존재합니다. addEventListener 함수를 이용해서 마우스 이벤트를 생성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659093148810&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let prevX = 0, prevY = 0; // 이전에 있던 좌표 

function getMouseDirection(event) {
  const xDir = prevX &amp;lt;= e.pageX ? &quot;right&quot; : &quot;left&quot;;
  const yDir = prevY &amp;lt;= e.pageY ? &quot;down&quot; : &quot;up&quot;;
  
  prevX = e.pageX;
  prevY = e.pageY;
  
  console.log(xDir + &quot;-&quot; + yDir);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;마우스 좌표값의 대소를 비교하기 위해서는 현재 좌표 이전에 위치해 있었던 좌표 값을 저장하고 현재 값과 비교해줘야합니다. 저장된 값과 현재의 마우스 좌표 값을 비교하여 방향을 판단해줍니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_Untitled-1.png&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SyjW1/btrIuXtOImi/0g2wQ3E6sCLo0pJfpFDg0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SyjW1/btrIuXtOImi/0g2wQ3E6sCLo0pJfpFDg0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SyjW1/btrIuXtOImi/0g2wQ3E6sCLo0pJfpFDg0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSyjW1%2FbtrIuXtOImi%2F0g2wQ3E6sCLo0pJfpFDg0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;734&quot; height=&quot;332&quot; data-filename=&quot;edited_Untitled-1.png&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 값이 이전 값보다 작으면, 왼쪽 또는 위쪽으로 이동했다고 볼 수 있습니다.&lt;/li&gt;
&lt;li&gt;반대로 값이 크다면, 오른쪽 또는 아래쪽으로 이동했다고 볼 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>Mouse</category>
      <category>react</category>
      <category>드래그</category>
      <category>리액트</category>
      <category>마우스</category>
      <category>방향</category>
      <category>이동방향</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/175</guid>
      <comments>https://gurtn.tistory.com/175#entry175comment</comments>
      <pubDate>Fri, 29 Jul 2022 20:56:20 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 배열을 n개씩 나누어 묶기(Chunk)</title>
      <link>https://gurtn.tistory.com/174</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v5W4W/btrIejJfUGU/zKQyd8iMU3pvQcYinUw101/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v5W4W/btrIejJfUGU/zKQyd8iMU3pvQcYinUw101/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v5W4W/btrIejJfUGU/zKQyd8iMU3pvQcYinUw101/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv5W4W%2FbtrIejJfUGU%2FzKQyd8iMU3pvQcYinUw101%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1차원 배열을 n개씩 묶어서 정한 개수만큼 2차원 배열로 바꿔서 반환시켜 주는 함수를 제작해 보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1658748934221&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function chunk(data = [], size = 1) {
  const arr = [];
    
  for (let i = 0; i &amp;lt; data.length; i += size) {
    arr.push(data.slice(i, i + size));
  }

  return arr;
}

// chunk([1, 2, 3, 4], 2) -&amp;gt; [ [1,2], [3,4] ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;chunk 함수의 매게 변수로 자를 원본 배열과 개수(n)를 받아줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Array.slice 메서드를 이용해서 i번째부터 ( i + 나눌개수 ) 만큼의 배열 값을 가져와 새로운 배열에 담아줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 방식으로 데이터가 모두 Chunk 되면 새로운 배열을 반환해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 예시&lt;/blockquote&gt;
&lt;pre id=&quot;code_1658751636682&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const item = [1, 2, 3, 4];

chunk(item, 2);
// [ [1,2], [3,4] ]

chunk(item, 1);
// [ [1], [2], [3], [4] ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>array</category>
      <category>chunk</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>n개씩</category>
      <category>나누기</category>
      <category>묶기</category>
      <category>배열</category>
      <category>자바스크립트</category>
      <category>청크</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/174</guid>
      <comments>https://gurtn.tistory.com/174#entry174comment</comments>
      <pubDate>Mon, 25 Jul 2022 21:38:10 +0900</pubDate>
    </item>
    <item>
      <title>[티스토리] Codepen 코드블럭 적용 시키기</title>
      <link>https://gurtn.tistory.com/173</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMENW4/btrHPeClGnU/6FSk3X5Pk7MctyuJ96ojvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMENW4/btrHPeClGnU/6FSk3X5Pk7MctyuJ96ojvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMENW4/btrHPeClGnU/6FSk3X5Pk7MctyuJ96ojvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMENW4%2FbtrHPeClGnU%2F6FSk3X5Pk7MctyuJ96ojvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드펜은 HTML, CSS, JS를 작성하고 결과를 실시간으로 확인할 수 있는 유용한 코딩 사이트입니다. 또한 제작한 코드를 공유하는 데에도 유용하기에 많은 코딩 블로그가 애용하는 코딩 사이트이기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codepen.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codepen.io/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1658367037563&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;CodePen&quot; data-og-description=&quot;An online code editor, learning environment, and community for front-end web development using HTML, CSS and JavaScript code snippets, projects, and web applications.&quot; data-og-host=&quot;codepen.io&quot; data-og-source-url=&quot;https://codepen.io/&quot; data-og-url=&quot;https://codepen.io/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dZ4W6Z/hyO8TR6Ffd/iyFGdQlf57Mfqx1M3drlT0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://codepen.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codepen.io/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dZ4W6Z/hyO8TR6Ffd/iyFGdQlf57Mfqx1M3drlT0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CodePen&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;An online code editor, learning environment, and community for front-end web development using HTML, CSS and JavaScript code snippets, projects, and web applications.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codepen.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;간단 요약&lt;/blockquote&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;계정 필요, 가입, 로그인&lt;/li&gt;
&lt;li&gt;Pen 생성 후 코드 작성&lt;/li&gt;
&lt;li&gt;Save 버튼 클릭 후 Embed 버튼 클릭&lt;/li&gt;
&lt;li&gt;설정 후에 HTML 코드를 복사&lt;/li&gt;
&lt;li&gt;티스토리 글 작성 페이지에서 &lt;b&gt;글 작성 모드를 HTML로 바꾸고 원하는 위치에 붙여 넣기&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;회원 가입하기&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;블로그에 Codepen 코드를 올리기 위해서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;계정이 필요하며,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;twitter, facebook, github 등의 계정이 존재할 시 간편하게 가입과 로그인이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k3UWI/btrHROv5E8w/8U1yTwasbwiXNcEj7t1yAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k3UWI/btrHROv5E8w/8U1yTwasbwiXNcEj7t1yAK/img.png&quot; data-alt=&quot;회원가입&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k3UWI/btrHROv5E8w/8U1yTwasbwiXNcEj7t1yAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk3UWI%2FbtrHROv5E8w%2F8U1yTwasbwiXNcEj7t1yAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;687&quot; height=&quot;368&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;490&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;회원가입&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Codepen에 로그인하기&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 sns 로그인을 이용하거나 가입한 아이디를 이용해서 로그인을 해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFv84P/btrHSBQOyFx/wg9IKdSRY8tFaQncHG2pR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFv84P/btrHSBQOyFx/wg9IKdSRY8tFaQncHG2pR0/img.png&quot; data-alt=&quot;로그인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFv84P/btrHSBQOyFx/wg9IKdSRY8tFaQncHG2pR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFv84P%2FbtrHSBQOyFx%2Fwg9IKdSRY8tFaQncHG2pR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;641&quot; height=&quot;397&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;로그인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;새로운 Pen 생성&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Codepen에서는 하나의 작품을 Pen라고 정의하고 있습니다. 왼쪽 상단에 존재하는 Pen 탭을 클릭해 새로운 작품을 생성해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;387&quot; data-origin-height=&quot;633&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MlFCO/btrHPeI6KYJ/Jp6gh4Hc4ZfF9d5FN2dcdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MlFCO/btrHPeI6KYJ/Jp6gh4Hc4ZfF9d5FN2dcdK/img.png&quot; data-alt=&quot;새로운 Pen 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MlFCO/btrHPeI6KYJ/Jp6gh4Hc4ZfF9d5FN2dcdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMlFCO%2FbtrHPeI6KYJ%2FJp6gh4Hc4ZfF9d5FN2dcdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;298&quot; height=&quot;487&quot; data-origin-width=&quot;387&quot; data-origin-height=&quot;633&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;새로운 Pen 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 HTML, CSS, JavaScript를 작성할 수 있는 화면이 나오게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 언어 영역에 알맞은 코드를 입력할 시, 아래에 보이는 결과창에 보이게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxy9Pm/btrHSzMeSfq/uEWA2CaDmf16Ch69Wm8yg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxy9Pm/btrHSzMeSfq/uEWA2CaDmf16Ch69Wm8yg0/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxy9Pm/btrHSzMeSfq/uEWA2CaDmf16Ch69Wm8yg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcxy9Pm%2FbtrHSzMeSfq%2FuEWA2CaDmf16Ch69Wm8yg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;795&quot; height=&quot;462&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;blockquote data-ke-style=&quot;style2&quot;&gt;티스토리에 코드 적용시키기&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽에 존재하는 텍스트를 바꿈으로 제목을 바꿀 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지의 진행상황을 저장하기 위해서는 상단에 존재하는 Save 버튼을 클릭해 서버에 저장시킬 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxh3g2/btrHOjEp1TL/SGnQFlwwv7971sMkI1W0qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxh3g2/btrHOjEp1TL/SGnQFlwwv7971sMkI1W0qk/img.png&quot; data-alt=&quot;코드 저장 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxh3g2/btrHOjEp1TL/SGnQFlwwv7971sMkI1W0qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbxh3g2%2FbtrHOjEp1TL%2FSGnQFlwwv7971sMkI1W0qk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;339&quot; height=&quot;175&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코드 저장 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 저장이 완료되었다면, &lt;b&gt;오른쪽 하단에 존재하는 Embed 버튼&lt;/b&gt;을 클릭해 코드를 공유할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;226&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pFY3K/btrHPIXsVoG/kcmgIzqhkXrSzl5ITVxMgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pFY3K/btrHPIXsVoG/kcmgIzqhkXrSzl5ITVxMgK/img.png&quot; data-alt=&quot;Embed 버튼 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pFY3K/btrHPIXsVoG/kcmgIzqhkXrSzl5ITVxMgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpFY3K%2FbtrHPIXsVoG%2FkcmgIzqhkXrSzl5ITVxMgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;226&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;226&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Embed 버튼 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 창이 나오면 공유하기 전 마지막으로 다양한 설정을 할 수 있습니다. Theme에서 Light와 Dark를 설정함으로 메인 색상을 변경할 수도 있고, 그 외에 기본으로 보여줄 코드 탭을 설정할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 하단에 존재하는 회색 바를 드래그하여 높이를 조절할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;754&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DM0io/btrHROizpio/cD8cls5j60qCIFkC0D2nDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DM0io/btrHROizpio/cD8cls5j60qCIFkC0D2nDk/img.png&quot; data-alt=&quot;Embed this pen&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DM0io/btrHROizpio/cD8cls5j60qCIFkC0D2nDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDM0io%2FbtrHROizpio%2FcD8cls5j60qCIFkC0D2nDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;747&quot; height=&quot;754&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;754&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Embed this pen&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정 후 오른쪽 하단에 존재하는 &lt;b&gt;HTML (Recommended) 탭에서 Copy code버튼&lt;/b&gt;을 클릭해 복사해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btJsBz/btrHSAYGNcj/bzSgij3jum8uYpMuIFKjK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btJsBz/btrHSAYGNcj/bzSgij3jum8uYpMuIFKjK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btJsBz/btrHSAYGNcj/bzSgij3jum8uYpMuIFKjK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtJsBz%2FbtrHSAYGNcj%2FbzSgij3jum8uYpMuIFKjK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;177&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;177&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 복사한 후 티스토리의 글 작성 페이지로 가줍니다. 상단에 존재하는 기본 모드 탭을 클릭 후 &lt;b&gt;모드를 HTML&lt;/b&gt;으로 바꿔줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dztUgX/btrHN2v9DI4/DCx9j8uG1guOnBxoUYMyJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dztUgX/btrHN2v9DI4/DCx9j8uG1guOnBxoUYMyJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dztUgX/btrHN2v9DI4/DCx9j8uG1guOnBxoUYMyJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdztUgX%2FbtrHN2v9DI4%2FDCx9j8uG1guOnBxoUYMyJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;341&quot; height=&quot;176&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간색 박스처럼 Codepen 블럭을 넣고 싶은 부분에 붙여 넣기 해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0J4jd/btrHOblMxtF/zugxrFeEkFbWjV1kSKI7n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0J4jd/btrHOblMxtF/zugxrFeEkFbWjV1kSKI7n1/img.png&quot; data-alt=&quot;HTML에 적용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0J4jd/btrHOblMxtF/zugxrFeEkFbWjV1kSKI7n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0J4jd%2FbtrHOblMxtF%2FzugxrFeEkFbWjV1kSKI7n1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;821&quot; height=&quot;298&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HTML에 적용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;붙여 넣기 한 후 다시 기본 모드로 돌아오면 아래와 같은 이미지처럼 생긴 박스가 추가된 다면 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;Codepen 코드 추가에 성공하신 겁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biEaVc/btrHOSsxbLO/VEs1ZvcpTqyyBfZ22H7LW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biEaVc/btrHOSsxbLO/VEs1ZvcpTqyyBfZ22H7LW1/img.png&quot; data-alt=&quot;적용 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biEaVc/btrHOSsxbLO/VEs1ZvcpTqyyBfZ22H7LW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiEaVc%2FbtrHOSsxbLO%2FVEs1ZvcpTqyyBfZ22H7LW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;907&quot; height=&quot;458&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;적용 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복사한 Codepen 코드만 존재한다면 티스토리가 아닌 사이트에서도 원하는 위치에 붙여 넣기 하여서 이용이 가능합니다.&lt;/p&gt;</description>
      <category>기타</category>
      <category>codepen</category>
      <category>CSS</category>
      <category>HTML</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>Tistory</category>
      <category>자바스크립트</category>
      <category>코드블럭</category>
      <category>코드펜</category>
      <category>티스토리</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/173</guid>
      <comments>https://gurtn.tistory.com/173#entry173comment</comments>
      <pubDate>Thu, 21 Jul 2022 12:20:27 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 좌표로 요소(element) 가져오기</title>
      <link>https://gurtn.tistory.com/172</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3BKWX/btrHAHTu25R/b53KUPtDdpp7EJ7DQ35cT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3BKWX/btrHAHTu25R/b53KUPtDdpp7EJ7DQ35cT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3BKWX/btrHAHTu25R/b53KUPtDdpp7EJ7DQ35cT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3BKWX%2FbtrHAHTu25R%2Fb53KUPtDdpp7EJ7DQ35cT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서 x, y 값으로 요소를 찾을 수 있는 native 함수가 존재합니다. 해당 함수의 이름은 &quot; &lt;b&gt;elementFromPoint &lt;/b&gt;&quot;입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1658148353485&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const element = document.elementFromPoint(x, y);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;창 기준 지정된 좌표(x, y) 값에 존재하는 element를 찾아 가장 최상위에 존재하는 요소를 반환하는 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 개의 요소가 존재할 시 최상위에 존재하는 요소를 반환합니다.&lt;/li&gt;
&lt;li&gt;해당 좌표에 요소가 존재하지 않거나 &lt;span style=&quot;background-color: #ffffff; color: #1b1b1b;&quot;&gt;좌표가 음수이면&lt;/span&gt; null을 반환합니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #313130;&quot;&gt;해당 메서드는 창 기준 좌표를 사용하기에&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #313130;&quot;&gt;&lt;b&gt;창 안에 보이는 영역&lt;/b&gt;에게만 작동합니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;pointer-events 속성이 none으로 설정된 요소는 무시됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예시 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;GIF 2022-07-19 오전 9-23-38.gif&quot; data-origin-width=&quot;453&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtjV3u/btrHHlgoHIW/L9Arrtaxvo2dhuOBCxtArk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtjV3u/btrHHlgoHIW/L9Arrtaxvo2dhuOBCxtArk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtjV3u/btrHHlgoHIW/L9Arrtaxvo2dhuOBCxtArk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dtjV3u/btrHHlgoHIW/L9Arrtaxvo2dhuOBCxtArk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;453&quot; height=&quot;261&quot; data-filename=&quot;GIF 2022-07-19 오전 9-23-38.gif&quot; data-origin-width=&quot;453&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mousemove 이벤트를 이용하여 움직인 마우스 좌표 값에 존재하는 요소를 감지하여 보여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/gOemYjE?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;396&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/gOemYjE&quot;&gt;
  elementFromPoint Example&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;다수의 element 찾기&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러개의 요소를 찾기 위해서는 elementsFromPoint 함수를 사용하면 됩니다. &lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;elementFromPoint와&lt;span&gt; 다른 점은 최상위 요소부터 차례대로 창 기준 좌표에 존재하는 요소들이 정렬되어 반환되는 함수입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658191164318&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const element = document.elementsFromPoint(x, y);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>elementFromPoint</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>감지</category>
      <category>요소 찾기</category>
      <category>위치</category>
      <category>자바스크립트</category>
      <category>좌표</category>
      <category>지정된 좌표</category>
      <category>탐지</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/172</guid>
      <comments>https://gurtn.tistory.com/172#entry172comment</comments>
      <pubDate>Tue, 19 Jul 2022 09:36:20 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 드래그 이동이 가능한 draggable 요소 만들기</title>
      <link>https://gurtn.tistory.com/171</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;GIF 2022-07-18 오후 8-57-29.gif&quot; data-origin-width=&quot;443&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWmdEd/btrHDAecZO6/qFgK3U3W6r4N8dIB6Wu3o1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWmdEd/btrHDAecZO6/qFgK3U3W6r4N8dIB6Wu3o1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWmdEd/btrHDAecZO6/qFgK3U3W6r4N8dIB6Wu3o1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bWmdEd/btrHDAecZO6/qFgK3U3W6r4N8dIB6Wu3o1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;443&quot; height=&quot;283&quot; data-filename=&quot;GIF 2022-07-18 오후 8-57-29.gif&quot; data-origin-width=&quot;443&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JQuery에 존재하는 draggable 메서드를 직접 순수 자바스크립트로 제작할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;draggable 메서드는 지정한 요소를 드래그로 이동시킬 수 있도록 만들어줍니다. 이때 draggable로 설정된 요소는 position: absolute 속성을 가지게 되며, left, top 속성으로 움직이게 됩니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/NWYdYpd?default-tab=js%2Cresult&quot; width=&quot;100%&quot; height=&quot;453&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/NWYdYpd&quot;&gt;
  Draggable HTML Element&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1658143108169&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;mover&quot;&amp;gt;drag&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 드래그 이동이 가능하도록 만들 요소를 하나 생성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658143654929&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let isPress = false,   // 마우스를 눌렀을 때
    prevPosX = 0,      // 이전에 위치한 X값
    prevPosY = 0;      // 이전에 위치한 Y값
    
const $target = document.querySelector(&quot;.mover&quot;);

// 드래그 구현에 필요한 이벤트
$target.onmousedown = start;
$target.onmouseup = end;

// 요소의 상위 요소 (임시로 window)
window.onmousemove = move;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드래그 기능을 구현하기 위해서는 mousedown, mousemove, mouseup 이벤트를 사용해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;mousedown - 이벤트가 적용된 요소 위에서 마우스 왼쪽 버튼을 누를 때 발생합니다.&lt;/li&gt;
&lt;li&gt;mousemove - &lt;span&gt;이벤트가 적용된 요소위에서 마우스를 움직일 때 발생합니다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;mouseup - 마우스 버튼 누르고 있다가 뗄 때 발생합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS에서는 일반 요소의 drag 여부를 판단할 수 없습니다. 그러므로&amp;nbsp;&lt;b&gt;드래그의 조건인 마우스 클릭과 움직임 이벤트&lt;/b&gt;로 드래그를 구현해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre id=&quot;code_1658143620986&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// mousedown
function start(e) {
  prevPosX = e.clientX;
  prevPosY = e.clientY;

  isPress = true;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요소 위에서 마우스 왼쪽 버튼을 클릭할 시 발생되는 mousedown 이벤트로 함수를 호출해줍니다. 요소가 위치한 좌표를 얻어서 변수에 저장해주고, 마우스 버튼 누름 여부를 저장해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658146332757&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// mousemove
function move(e) {
  if (!isPress) {
    return;
  }
  
  // 이전 좌표와 현재 좌표 차이값
  const posX = prevPosX - e.clientX; 
  const posY = prevPosY - e.clientY; 
  
  // 현재 좌표가 이전 좌표로 바뀜
  prevPosX = e.clientX; 
  prevPosY = e.clientY; 
  
  // left, top으로 이동
  $target.style.left = ($target.offsetLeft - posX) + &quot;px&quot;;
  $target.style.top = ($target.offsetTop - posY) + &quot;px&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요소 위에서 마우스를 움직이면 이벤트가 발생되는 mousemove 이벤트는 &lt;b&gt;&quot;드래그&quot;가 아닌 &quot;움직임&quot;&lt;/b&gt;을 감지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 &lt;b&gt;드래그의 충족 조건인 왼쪽 마우스 버튼 클릭 여부&lt;/b&gt;를 체크해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마우스 클릭 여부가 체크되었다면, 이제 마우스를 움직인 만큼 요소를 이동시켜야 합니다. 요소를 이동시키는 방법은 이전에 위치했던 좌표에서 현재 마우스를 움직인 좌표를 뺌으로 차이 값을 구해주고, top과 left 속성으로 이동시켜줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658146341133&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// mouseup
function end() {
  isPress = false;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마우스를 땔 시, move 함수의 코드가 실행되지 않도록 다시 isPress 변수 값을 false로 바꿔서 마우스 버튼을 땠다는 것을 알 수 있도록 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>div 드래그</category>
      <category>Drag</category>
      <category>draggable</category>
      <category>JavaScript</category>
      <category>jquery</category>
      <category>JS</category>
      <category>react</category>
      <category>드래그</category>
      <category>리액트</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/171</guid>
      <comments>https://gurtn.tistory.com/171#entry171comment</comments>
      <pubDate>Mon, 18 Jul 2022 21:29:43 +0900</pubDate>
    </item>
    <item>
      <title>[CSS] 떨리는 효과 구현하기</title>
      <link>https://gurtn.tistory.com/170</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L9oLa/btrGIwZkHUM/ZaP9qa7rc8owoKnnTmSsyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L9oLa/btrGIwZkHUM/ZaP9qa7rc8owoKnnTmSsyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L9oLa/btrGIwZkHUM/ZaP9qa7rc8owoKnnTmSsyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL9oLa%2FbtrGIwZkHUM%2FZaP9qa7rc8owoKnnTmSsyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별도의 라이브러리 없이 간단한 코드로 진동처럼 흔들리는 애니메이션을 구현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/vYRLvEQ?default-tab=css%2Cresult&quot; width=&quot;100%;&quot; height=&quot;312&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/vYRLvEQ&quot;&gt;
  Vibration Animation Box&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;

&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1657185953063&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;box vibration&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;떨림 효과를 줄 박스 요소를 하나 만들어줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657186271803&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.box {
  width: 150px;
  height: 150px;
  background: #febf00;
}

.box.vibration {
  animation: vibration 0.1s infinite;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;박스 크기와 색깔 속성을 통해 시각화시켜주고, vibration 클래스가 포함된 박스에는 흔들리는 효과를 가진 애니메이션이 작동되도록 구현해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657186882857&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@keyframes vibration {
  from {
    transform: rotate(1deg);
  }
  to {
    transform: rotate(-1deg);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;transform: rotate&lt;/b&gt; 속성을 이용한 미세한 회전을 0.1초 간격의 반복 애니메이션으로 마치 진동이 울리는 것과 같은 흔들리는 효과를 구현하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;JS를 사용한 응용&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트를 사용해서 박스를 클릭할 때, 짧게 동작되는 움직이는 애니메이션 기능을 구현해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657187242872&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;box&quot; onclick=&quot;vibration(this)&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;박스를 클릭할 때&quot;&lt;/b&gt;를 판단하기 위해서 onclick 이벤트를 넣어서 박스 요소를 생성해주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657187231305&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const vibration = (target) =&amp;gt; {
  target.classList.add(&quot;vibration&quot;);

  setTimeout(function() {
    target.classList.remove(&quot;vibration&quot;);
  }, 400);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스를 추가, 제거할 수 있는 add, remove 메서드를 이용해서, &lt;b&gt;클릭 시 vibration 클래스를 추가&lt;/b&gt;해주고 setTimeout 함수로 &lt;b&gt;0.4초 딜레이&lt;/b&gt;를 줍니다. 그 후 해당 요소에 존재하는 vibration 클래스를 지워줌으로 진동 효과를 멈춰줍니다.&lt;/p&gt;</description>
      <category>HTML, CSS/코드</category>
      <category>CSS</category>
      <category>HTML</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>떨리는</category>
      <category>떨림 효과</category>
      <category>애니메이션</category>
      <category>자바스크립트</category>
      <category>진동</category>
      <category>흔들리는 효과</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/170</guid>
      <comments>https://gurtn.tistory.com/170#entry170comment</comments>
      <pubDate>Thu, 7 Jul 2022 18:56:50 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 브라우저 크기 변경에 반응하는 이벤트</title>
      <link>https://gurtn.tistory.com/169</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LEIpU/btrGEmnj563/ydlpu4escQ9Zb8xdIlq78K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LEIpU/btrGEmnj563/ydlpu4escQ9Zb8xdIlq78K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LEIpU/btrGEmnj563/ydlpu4escQ9Zb8xdIlq78K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLEIpU%2FbtrGEmnj563%2Fydlpu4escQ9Zb8xdIlq78K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저 창의 크기 변화에 반응하는 &lt;b&gt;resize &lt;/b&gt;이벤트를 사용하여, 변경된 브라우저 창의 크기를 가져올 수 있습니다. addEventListener 함수를 이용하여 이벤트를 지정하거나, window.onresize 함수를 통해 이벤트를 지정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1656929767880&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1.
window.addEventListener(`resize`, function() {
  
});

// 2.
window.onresize = function() {
	
}&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote data-ke-style=&quot;style2&quot;&gt;변경된 사이즈 가져오기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1656929934165&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;window.onresize = function() {
  const width = window.innerWidth;
  const height = window.innerHeight;	
  
  console.log(width);
  console.log(height);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 창의 현재 가로, 세로 사이즈 정보는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;wndow.innerWidth, window.innerHeight&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;속성에 담겨있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트가 실행될 때마다 달라지는 크기를 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;React에서 resize 이벤트 다루기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1656935740856&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(()=&amp;gt; {
  const windowResize = () =&amp;gt; {
    console.log(&quot;resize&quot;);
  }

  window.addEventListener(`resize`, windowResize);
 
  return () =&amp;gt; {
     window.removeEventListener(`resize`, windowResize);
   }
}, []);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트에서는 useEffect 안에 addEventListenr 함수를 넣어놔도 계속해서 바인딩이 되는 문제가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 방지하기 위해서 &lt;b&gt;새로운 바인딩이 발생되기 전에 기존의 리스너를 제거해줘야 합니다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>resize</category>
      <category>브라우저</category>
      <category>사이즈</category>
      <category>윈도우창</category>
      <category>이벤트</category>
      <category>자바스크립트</category>
      <category>크기 변경</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/169</guid>
      <comments>https://gurtn.tistory.com/169#entry169comment</comments>
      <pubDate>Mon, 4 Jul 2022 21:05:13 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 자동으로 글자 적는 타이핑 효과 구현하기</title>
      <link>https://gurtn.tistory.com/168</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;GIF 2022-06-29 오후 1-08-25.gif&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJYy5D/btrF2NlKAIK/DktfsLqpGWkupxCfTBkMo1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJYy5D/btrF2NlKAIK/DktfsLqpGWkupxCfTBkMo1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJYy5D/btrF2NlKAIK/DktfsLqpGWkupxCfTBkMo1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bJYy5D/btrF2NlKAIK/DktfsLqpGWkupxCfTBkMo1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;205&quot; data-filename=&quot;GIF 2022-06-29 오후 1-08-25.gif&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript를 이용하여 간단한 typing 효과를 구현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;예시 코드&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/yLKLNGM?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;400&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/yLKLNGM&quot;&gt;
  Text Typing Effect&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;

&lt;blockquote data-ke-style=&quot;style3&quot;&gt;위 예시코드는 동작을 보여주기 위해서 무한 반복하고 있습니다. 참고해주세요!&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;무한반복 막기&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1678975553518&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 지우는 효과
if (letters[i + 1]) remove();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1656468751841&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;h1 class=&quot;text&quot;&amp;gt;&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트가 입력될 요소를 하나 생성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1656468818568&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 텍스트 요소
const $text = document.querySelector(&quot;.text&quot;);

// 입력될 글자 모음
const letters = [&quot;HTML&quot;, &quot;CSS&quot;, &quot;JavaScript&quot;];

// 글자 입력 속도
const speed = 100;

// 현재 지정된 글자
let i = 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타이핑 효과를 구현하기 위해서 필요한 기본 요소 및 설정 값들을 선언해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1656469017601&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 딜레이 기능 ( 마이크로초 )
function wait(ms) {
  return new Promise(res =&amp;gt; setTimeout(res, ms))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트가 작성되는 속도나 작성되고 텍스트가 멈추는 시간을 구현하기 위해서 setTimeout 함수로 딜레이를 주고, Promise를 이용해서 딜레이 기능을 주는 함수를 구현해주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1656469159124&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 타이핑 기능   ( wait 기능을 위한 async, await )
const typing = async () =&amp;gt; {
  const letter = letters[i].split(&quot;&quot;);
  
  while (letter.length) {
    // 글자 작성 속도 조절
    await wait(speed);
    $text.innerHTML += letter.shift(); 
  }
  
  // 작성 된 후 잠시 멈추기
  await wait(800);
  
  // 다음에 작성될 글자가 있을 시 지우는 효과 실행
  if (letters[i + 1]) remove();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성할 글자를 모아둔 배열에서 i번째 글자를 가져와 &lt;b&gt;문자열을 배열&lt;/b&gt;로 나눠줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 문자가 텍스트 요소에 추가되면 종료되는 while 문을 작성해줍니다. 배열로 나눈 입력될 문자에서 &lt;b&gt;shfit 메서드를 이용해서 배열의 제일 앞에 있는 값&lt;/b&gt;을 뽑아줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$text.innerHTML 속성을 이용해서 &lt;b&gt;딜레이와 하나씩 추가되는 기능을 통해 타이핑되는 효과&lt;/b&gt;를 구현하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;wait 함수를 이용해서 while 안에서 딜레이 시간이 생기게 만들어 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1656470280974&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  ...

  // 작성 된 후 잠시 멈추기
  await wait(800);
  
  // 다음에 작성될 글자가 있을 시 지우는 효과 실행
  if (letters[i + 1]) remove();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while문이 종료된 후 바로 지우는 효과가 실행되면, 텍스트를 읽을 시간이 없어집니다. 다시 한번 wait 함수를 이용해서 다음 코드 실행에 딜레이를 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 타이핑 기능을 통해서 글자가 작성되었으니 지우는 효과를 만들어야 합니다. 글자를 지우면 그 자리를 다른 글씨가 대체해야 하므로, &lt;b&gt;다음에 작성될 텍스트가 있을 때&lt;/b&gt; 지우는 효과를 실행하도록 조건문을 걸어주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
&lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-7087881904125734&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-format=&quot;autorelaxed&quot; data-ad-client=&quot;ca-pub-7087881904125734&quot; data-ad-slot=&quot;4683556281&quot; data-matched-content-rows-num=&quot;3,1&quot; data-matched-content-columns-num=&quot;1,3&quot; data-matched-content-ui-type=&quot;image_stacked,image_stacked&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
         (adsbygoogle = window.adsbygoogle || []).push({});
    &lt;/script&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1656470516969&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 글자를 지우는 효과
const remove = async () =&amp;gt; {
  const letter = letters[i].split(&quot;&quot;);
  
  while (letter.length) {
    await wait(speed);
    
    letter.pop();
    $text.innerHTML = letter.join(&quot;&quot;); 
  }
  
  // 다음 순서의 글자로 변경
  i++;
  // 다시 타이핑 시작
  typing();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글자를 지우는 효과 또한 타이핑 기능과 비슷합니다. 타이핑 기능과의 차이점으로는 글자를 innerHTML를 이용해서 &lt;b&gt;추가시키는 것이 아닌 대체해주어야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 한번 letter 변수에 작성될 글자를 가져와 선언해줍니다. 이번엔 &lt;b&gt;pop 메서드&lt;/b&gt;를 이용해서 뒷 문자를 뽑아 버려 주고, 남은 글자들을 다시 문자열로 합친 뒤에 뒷 글자가 사라진 문자로 글자를 대체시켜줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;커서 기능 구현&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;GIF 2022-06-29 오후 1-06-07.gif&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcoEki/btrF0tVNwZQ/tgpLODQgdE22tU0HxvVZcK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcoEki/btrF0tVNwZQ/tgpLODQgdE22tU0HxvVZcK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcoEki/btrF0tVNwZQ/tgpLODQgdE22tU0HxvVZcK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bcoEki/btrF0tVNwZQ/tgpLODQgdE22tU0HxvVZcK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;205&quot; data-filename=&quot;GIF 2022-06-29 오후 1-06-07.gif&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1656473929935&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.text::after {
  content: '';
  margin-left: .6rem;
  border-right: 2px solid #777;
  animation: cursor .9s infinite steps(2);
}

@keyframes cursor {
  from { border-right: 2px solid #222; }
  to { border-right: 2px solid #777; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;border-right 속성을 이용해서 타이핑되는 요소 오른쪽에 막대기를 생성해줍니다. animation 속성과 @keyframes을 이용해 border 색상이 바뀌는 애니메이션 효과를 제작해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;줄바꿈 타이핑&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/ZERpvXZ?default-tab=js%2Cresult&quot; width=&quot;100%&quot; height=&quot;427.111083984375&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/ZERpvXZ&quot;&gt;
  Letter Typing(Line Break) Effect&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1667746907778&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 줄바꿈을 위한 &amp;lt;br&amp;gt; 치환
const changeLineBreak = (letter) =&amp;gt; {
  return letter.map(text =&amp;gt; text === &quot;\n&quot; ? &quot;&amp;lt;br&amp;gt;&quot; : text);
}

// 기존에서 변경된 코드
const typing = async () =&amp;gt; {  
  // 기존코드에서 개행치환코드 추가
  const letter = changeLineBreak(letters[i].split(&quot;&quot;));
  
  ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;줄바꿈 타이핑을 구현하기 전에 HTML DIV상에서 개행 문자로 줄바꿈이 불가능하며, &quot;&amp;lt;br&amp;gt;&quot; 태그를 이용해서 줄바꿈 시켜줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개행 문자를 &quot;&amp;lt;br&quot; 태그로 바꿔주는 코드를 추가해줌으로써 간단하게 구현할 수 있습니다.&lt;/p&gt;</description>
      <category>JavaScript/제작</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>Typing</category>
      <category>글자</category>
      <category>자동</category>
      <category>자바스크립트</category>
      <category>타이핑</category>
      <category>타이핑 효과</category>
      <category>텍스트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/168</guid>
      <comments>https://gurtn.tistory.com/168#entry168comment</comments>
      <pubDate>Wed, 29 Jun 2022 13:09:32 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 클립보드에 특정 텍스트 복사하기</title>
      <link>https://gurtn.tistory.com/167</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BLW4k/btrFNGBZWFg/jC6xyGnrmH6bjixFZSPeK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BLW4k/btrFNGBZWFg/jC6xyGnrmH6bjixFZSPeK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BLW4k/btrFNGBZWFg/jC6xyGnrmH6bjixFZSPeK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBLW4k%2FbtrFNGBZWFg%2FjC6xyGnrmH6bjixFZSPeK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1655902178322&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;코드블럭 오른쪽 상단바에 존재하는 &quot;복사 아이콘&quot;을 클릭해보세요!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Ctrl + C&quot; 단축키와 같은 기능 또는 블로그에 새로 추가한 &quot;코드 복사&quot; 기능을 웹 상에서 구현하기 위해서는 &lt;b&gt;특정 텍스트를 클립보드에 추가시켜줘야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클립보드와 상호작용하는데 가장 많이 사용되는 &lt;b&gt;document.execCommand() &lt;/b&gt;방법을 사용하여 쉽게 구현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;document.execCommand(&lt;b&gt;&quot;copy&quot;&lt;/b&gt;) - 클립 보드에 &lt;span&gt;텍스트 &lt;/span&gt;&lt;b&gt;복사&lt;/b&gt; 기능&lt;/li&gt;
&lt;li&gt;document.execCommand(&lt;b&gt;&quot;cut&quot;&lt;/b&gt;) - 클립 보드에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;텍스트&lt;b&gt;&lt;span&gt; 잘라내기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;기능&lt;/li&gt;
&lt;li&gt;document.execCommand(&lt;b&gt;&quot;paste&quot;&lt;/b&gt;) - 클립 보드에 이미&lt;span&gt;&amp;nbsp;존재하는 내용을 &lt;b&gt;붙여넣기&lt;/b&gt; 기능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled-2.png&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;153&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vAyZZ/btrFvW4x5Uv/K7F4J9GLAR94dhDksPGb60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vAyZZ/btrFvW4x5Uv/K7F4J9GLAR94dhDksPGb60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vAyZZ/btrFvW4x5Uv/K7F4J9GLAR94dhDksPGb60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvAyZZ%2FbtrFvW4x5Uv%2FK7F4J9GLAR94dhDksPGb60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;493&quot; height=&quot;153&quot; data-filename=&quot;Untitled-2.png&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;153&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 기능은 input, textarea와 같은 입력창에 입력된 값 중&amp;nbsp;&lt;b&gt;선택(드래그)된 상태인 텍스트&lt;/b&gt;에 적용되는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1655904912741&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const copy = (text) =&amp;gt; {
  // 임시의 textarea 생성
  const $textarea = document.createElement(&quot;textarea&quot;);

  // body 요소에 존재해야 복사가 진행됨
  document.body.appendChild($textarea);
  
  // 복사할 특정 텍스트를 임시의 textarea에 넣어주고 모두 셀렉션 상태
  $textarea.value = text;
  $textarea.select();
  
  // 복사 후 textarea 지우기
  document.execCommand('copy');
  document.body.removeChild($textarea);
}

copy(&quot;복사 테스트&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 텍스트를 삽입할 임시의 textarea 요소를 생성해줍니다. 그 후 원하는 &lt;b&gt;텍스트 값을 임시의&amp;nbsp; textarea에 삽입&lt;/b&gt; 해준 뒤에 &lt;b&gt;삽입한 모든 텍스트를 선택&lt;/b&gt;(복사를 하기 위해서 드래그) 시켜줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 소개한 document.execCommand(&quot;copy&quot;) 기능을 이용하여 &lt;b&gt;셀렉션 된 텍스트들을 복사&lt;/b&gt;시켜주고 임시의 textarea 요소는 제거해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단 요약으로 아래와 같이 진행됩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;텍스트를 입력할 임시의 입력창(textarea) 생성&lt;/li&gt;
&lt;li&gt;입력창에 텍스트를 입력하고 선택(드래그)시켜 복사 준비&lt;/li&gt;
&lt;li&gt;execCommand(&quot;copy&quot;)로 텍스트 복사&lt;/li&gt;
&lt;li&gt;생성한 임시의 입력창 제거&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;익스플로러 환경에서 복사&lt;/blockquote&gt;
&lt;pre id=&quot;code_1663856788539&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const copy = (text) =&amp;gt; {
  window.clipboardData.setData(&quot;text&quot;, text);
} 

copy(&quot;IE 복사 테스트&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;익스플로러 환경에서 복사 기능을 구동하기 위해서는 &lt;b&gt;IE 환경에서만 존재&lt;/b&gt;하는 &lt;b&gt;window.clipboardData.setData() 메서드&lt;/b&gt;를 사용하여야 합니다.&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>clipboard</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>react</category>
      <category>리액트</category>
      <category>복사하기</category>
      <category>붙여넣기</category>
      <category>자바스크립트</category>
      <category>클립보드</category>
      <category>텍스트 복사</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/167</guid>
      <comments>https://gurtn.tistory.com/167#entry167comment</comments>
      <pubDate>Wed, 22 Jun 2022 23:03:19 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 글 작성 경과 시간 표시 (방금전, 몇분전, 몇시간전, 몇일전, 몇달전, 몇년전)</title>
      <link>https://gurtn.tistory.com/166</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMxhRG/btrEZDZpveY/ZM7lZc6pm2yHf3BZKKOv9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMxhRG/btrEZDZpveY/ZM7lZc6pm2yHf3BZKKOv9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMxhRG/btrEZDZpveY/ZM7lZc6pm2yHf3BZKKOv9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMxhRG%2FbtrEZDZpveY%2FZM7lZc6pm2yHf3BZKKOv9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;246&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유명 SNS 게시물을 보면 작성 날짜 항목에 &quot;방금 전&quot;, &quot;몇분 전&quot;, &quot;몇시간 전&quot;, &quot;몇일 전&quot;에 작성됨, 과 같은 형식으로 표현하는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;iframe src=&quot;https://codepen.io/hyukson/embed/xxYBLWB?default-tab=js%2Cresult&quot; width=&quot;100%;&quot; height=&quot;400&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/hyukson/pen/xxYBLWB&quot;&gt;
  Untitled&lt;/a&gt; by hyukson (&lt;a href=&quot;https://codepen.io/hyukson&quot;&gt;@hyukson&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드&lt;/blockquote&gt;
&lt;pre id=&quot;code_1655394260613&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function elapsedTime(date) {
  const start = new Date(date);
  const end = new Date();

  const diff = (end - start) / 1000;
  
  const times = [
    { name: '년', milliSeconds: 60 * 60 * 24 * 365 },
    { name: '개월', milliSeconds: 60 * 60 * 24 * 30 },
    { name: '일', milliSeconds: 60 * 60 * 24 },
    { name: '시간', milliSeconds: 60 * 60 },
    { name: '분', milliSeconds: 60 },
  ];

  for (const value of times) {
    const betweenTime = Math.floor(diff / value.milliSeconds);

    if (betweenTime &amp;gt; 0) {
      return `${betweenTime}${value.name} 전`;
    }
  }
  return '방금 전';
}

elapsedTime('2022-11-15');&lt;/code&gt;&lt;/pre&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;코드 풀이&lt;/blockquote&gt;
&lt;pre id=&quot;code_1655394773242&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function elapsedTime(date) {
  const start = new Date(date);
  const end = new Date(); // 현재 날짜
  
  const diff = (end - start) / 1000; // 경과 시간 구하기 (밀리초 기본으로 빼주기)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경과시간을 구하기 위해서는 비교할 날짜와 현재 날짜가 필요로 합니다. 그러므로 함수 파라미터 값으로 비교할 날짜 정보를 받아와 줍니다. 그다음 현재 날짜와 비교할 날짜 사이의 경과 시간 값을 구해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1655395004176&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const times = [
  { name: '년', milliSeconds: 60 * 60 * 24 * 365 },
  { name: '개월', milliSeconds: 60 * 60 * 24 * 30 },
  { name: '일', milliSeconds: 60 * 60 * 24 },
  { name: '시간', milliSeconds: 60 * 60 },
  { name: '분', milliSeconds: 60 },
];

// 아래 코드를 위해서는 (년 ~ 분) 순서여야함&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &quot;몇분 전&quot;, &quot;며칠&amp;nbsp;전&quot; 등과 같은 시간을 표시하기 위해서 배열에 &lt;b&gt;차례대로 시간 명칭과 해당하는 밀리초 값&lt;/b&gt;을 구분 지어 작성해주고 &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 반복문 코드를 위해서 대소 관계를 비교하기 위해서 [년도 ~ 분] 순서로 코드를 작성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1655395273246&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 년 단위부터 알맞는 단위 찾기
for (const value of times) {
  const betweenTime = Math.floor(diff / value.milliSeconds);
  
  // 큰 단위는 0보다 작은 소수점 값이 나옴
  if (betweenTime &amp;gt; 0) {
    return `${betweenTime}${value.time} 전`;
  }
}

// 모든 단위가 맞지 않을 시
return &quot;방금 전&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;경과시간에 밀리초 값을 나눠서&lt;/b&gt; 비교 값을 구해줄 수 있습니다. 해당 단위 밀리초 값보다 경과시간이 적을 시, 0보다 작은 소수점 값이 나오게 됩니다. ( 1분 / 1년 ) =&amp;gt; 0.0000019...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구해준 값이 0보다 작을 시, 다음 작은 단위로 넘어가서 다시 비교해주고 &lt;b&gt;정수 값이 나오게 되면&lt;/b&gt;, 구한 비교 값에 시간 명칭을 붙여서 반환해줍니다. 마지막 분단위에서도 결과가 나오지 않는다면 더 이상 비교가 불가능하다고 판단하고 &quot;방금 전&quot;이라는 문자를 반환해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Intl.RelativeTimeFormat 사용하기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1669963652641&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function elapsedTime(date) {
  const start = new Date(date);
  const end = new Date();

  const diff = (end - start) / 1000;

  const formatter = new Intl.RelativeTimeFormat('ko', {
    numeric: 'auto',
  });

  const times = [
    { name: 'year', milliSeconds: 60 * 60 * 24 * 365 },
    { name: 'month', milliSeconds: 60 * 60 * 24 * 30 },
    { name: 'day', milliSeconds: 60 * 60 * 24 },
    { name: 'hour', milliSeconds: 60 * 60 },
    { name: 'minute', milliSeconds: 60 },
  ];

  for (const value of times) {
    const betweenTime = Math.floor(diff / value.milliSeconds);

    if (betweenTime &amp;gt; 0) {
      return formatter.format(betweenTime, value.name);
    }
  }
  return '방금 전';
}

elapsedTime('2022-11-15');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Intl.&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;RelativeTimeFormat 객체를 사용해서 &lt;span style=&quot;color: #000000;&quot;&gt;현재 시간 기준으로 얼마나 시간이 지났는지 혹은 얼마나 걸릴 것인지 &lt;span style=&quot;background-color: #ffffff; color: #1b2e46;&quot;&gt;국제화해주는 형식입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1669963997819&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;formatter.format(1, 'day')
// '내일'
formatter.format(-1, 'day')
// '어제'
formatter.format(0, 'day')
// '오늘'
formatter.format(60, 'day')
// '60일 후'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 '1일 전', '2일 전'과 같이 형식이 아닌 &lt;b&gt;최대한 문자를 사용&lt;/b&gt;해서 '오늘', '어제'와 같은 형식을 받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/113&quot;&gt;https://gurtn.tistory.com/113&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669961860284&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JS] 두 날짜 사이의 일수 구하기&quot; data-og-description=&quot;코드 const getDateDiff = (d1, d2) =&amp;gt; { const date1 = new Date(d1); const date2 = new Date(d2); const diffDate = date1.getTime() - date2.getTime(); return Math.abs(diffDate / (1000 * 60 * 60 * 24));..&quot; data-og-host=&quot;gurtn.tistory.com&quot; data-og-source-url=&quot;https://gurtn.tistory.com/113&quot; data-og-url=&quot;https://gurtn.tistory.com/113&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/byE7ZZ/hyONVgqzar/KTUBBA3OpSsfqxQfkcNsz1/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246,https://scrap.kakaocdn.net/dn/bs7TKv/hyOMO4iNuh/h7TeG6CxxMqSkJhj0tS7l1/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246,https://scrap.kakaocdn.net/dn/bhQ3lZ/hyOMOb9BET/2EzqeUCmEA9meKOyeKuYwK/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246&quot;&gt;&lt;a href=&quot;https://gurtn.tistory.com/113&quot; data-source-url=&quot;https://gurtn.tistory.com/113&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/byE7ZZ/hyONVgqzar/KTUBBA3OpSsfqxQfkcNsz1/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246,https://scrap.kakaocdn.net/dn/bs7TKv/hyOMO4iNuh/h7TeG6CxxMqSkJhj0tS7l1/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246,https://scrap.kakaocdn.net/dn/bhQ3lZ/hyOMOb9BET/2EzqeUCmEA9meKOyeKuYwK/img.png?width=246&amp;amp;height=246&amp;amp;face=0_0_246_246');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JS] 두 날짜 사이의 일수 구하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 const getDateDiff = (d1, d2) =&amp;gt; { const date1 = new Date(d1); const date2 = new Date(d2); const diffDate = date1.getTime() - date2.getTime(); return Math.abs(diffDate / (1000 * 60 * 60 * 24));..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gurtn.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/코드</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>경과날짜</category>
      <category>경과시간</category>
      <category>몇달전</category>
      <category>몇분전</category>
      <category>몇시간전</category>
      <category>몇일전</category>
      <category>방금전</category>
      <category>자바스크립트</category>
      <author>나를 제외한 천재들</author>
      <guid isPermaLink="true">https://gurtn.tistory.com/166</guid>
      <comments>https://gurtn.tistory.com/166#entry166comment</comments>
      <pubDate>Fri, 17 Jun 2022 01:12:43 +0900</pubDate>
    </item>
  </channel>
</rss>