<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>n-u002.log</title>
        <link>https://velog.io/</link>
        <description>기록하며 발전하는 삶</description>
        <lastBuildDate>Thu, 03 Nov 2022 16:25:12 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>n-u002.log</title>
            <url>https://velog.velcdn.com/images/n-u-002/profile/15f29071-823a-4a0c-99c3-ee7265eb4aa2/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. n-u002.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/n-u-002" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[회원가입 form의 마크업과 focus제어]]></title>
            <link>https://velog.io/@n-u-002/%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-form%EC%9D%98-%EB%A7%88%ED%81%AC%EC%97%85%EA%B3%BC-focus%EC%A0%9C%EC%96%B4</link>
            <guid>https://velog.io/@n-u-002/%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-form%EC%9D%98-%EB%A7%88%ED%81%AC%EC%97%85%EA%B3%BC-focus%EC%A0%9C%EC%96%B4</guid>
            <pubDate>Thu, 03 Nov 2022 16:25:12 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 예제는 <code>tab키로 이동이 가능</code>합니다.
또한, 체크박스에 <code>space바</code>를 눌러 체크해 보세요.</p>
</blockquote>
<p>!codepen[yyyhhh/embed/Vwdaody?default-tab=js%2Cresult&amp;editable=true&amp;theme-id=dark]</p>
<blockquote>
<ul>
<li>회원가입 form요소 : <code>form-wrap</code></li>
<li>이용약관 클릭시 나타나는 모달창 :<code>popup</code></li>
</ul>
</blockquote>
<h2 id="tab키-이동에-대한-포커스-제어">tab키 이동에 대한 포커스 제어</h2>
<h3 id="선형구조">선형구조</h3>
<p>tab키를 이용해 form요소의 내용을 순차적으로 탐색할 수 있도로고 HTML구조에 신경을 썼습니다.
초점같은 경우에는 기본적으로 마크업 순서에 맞춰 움직이게 되어있어, HTML의 구조가 가장 중요하다고 생각을 했습니다.</p>
<p>하지만, 약관의 내용을 보여주는 모달창인 경우, form요소의 약관 체크박스를 클릭했을때에 나타나야하는 부분이지만, HTML구조상 초점이 자동으로 모달창으로 진입하기에는 어려움이 있습니다.</p>
<p>그래서 javascript를 이용해 모달창이 열릴때 초점이 모달창 안쪽 버튼에 초점이 갈 수 있도록 작성했습니다.</p>
<pre><code class="language-javascript">function openTerm(){
    body.style.overflow = &#39;hidden&#39;;
    dim.style.display = &#39;block&#39;;
    popup.style.display = &#39;block&#39;;
    btnPopClose.focus(); //form 요소에 있던 초점이 모달창 버튼에 들어가도록 하는 코드
    btnPopClose.style.outline = &#39;1px solid red&#39;;
}
function clsoeTerm(){
    body.style.overflow = &#39;auto&#39;;
    dim.style.display = &#39;none&#39;;
    popup.style.display = &#39;none&#39;;
    termEmailBox.focus();//모달창이 닫히고 나서 다음 체크박스에 초점을 강제로 옮겨준다.
}</code></pre>
<h3 id="form-요소-약관체크-박스-시나리오">form 요소 약관체크 박스 시나리오</h3>
<blockquote>
<ul>
<li>약관 체크박스를 클릭할때에 약관관련 안내 모달창이 나타난다.</li>
<li>약관체크박스가 체크된 상태에서 체크를 해체한다면, 모달창은 나타나지 않도록 제어한다.</li>
</ul>
</blockquote>
<p>위에 시나리오를 바탕으로 초점을 제어하고 커스텀한 체크박스의 형태를 바꿔 보았습니다.
가장 보편적으로 사용하는 label태그의 가상선택자를 만들어 라벨을 클릭하면 체크박스가 클리되도록 커스텀을 해보았습니다.</p>
<h3 id="html">HTML</h3>
<pre><code class="language-html">&lt;input type=&quot;checkbox&quot; required id=&quot;termsService&quot;&gt;
&lt;label for=&quot;termsService&quot;&gt;
  &lt;span class=&quot;underline&quot;&gt;이용약관 동의&lt;/span&gt; 및 &lt;span class=&quot;underline&quot;&gt;개인정보 처리방침&lt;/span&gt; &lt;span class=&quot;require&quot;&gt;&lt;/span&gt;
&lt;/label&gt;</code></pre>
<h3 id="css">CSS</h3>
<pre><code class="language-css">.form-wrap .agree label{
    position: relative;
    margin-bottom: 0px;
    padding-left: 41px;
    font-size: 18px;
    line-height: 26px;
}
.form-wrap .agree label::before{
    content: &quot;&quot;;
    position: absolute;
    top: 0;
    left: 0;
    width: 26px;
    height: 26px;
    border: 1px solid #dcdce0;
    border-radius: 5px;
    box-sizing: border-box;
}
.form-wrap .agree input[type=checkbox]{
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);

    /*
    IR기법으로 체크박스를 숨깁니다.
    이 방법은 sass를 사용하다면 @mixin을 사용하면 편할 거라고 생각했습니다.
    */
}
.form-wrap .agree input[type=checkbox]:focus + label::before{
    outline: 1px solid #ff2a00;
    /*
    input에 포커스를 주면 커스텀한 label에 가상선택자에 초점이 진입했다는 것을 알려주기 위해 의미로 넣은 outline입니다.
    */
}
.form-wrap .agree input[type=checkbox]:checked + label::before{
    background: #595a60;
    /*
    체크박스가 체크가 되면(클릭 또는 키보드로 spacebar) 커스텀된 라벨이 체크가 되는 것처럼 css로 변화를 줍니다.
    */
}</code></pre>
<h3 id="javascript">JAVASCRIPT</h3>
<pre><code class="language-javascript">termBox.addEventListener(&#39;click&#39;,()=&gt;{
    if(termBoxLi.classList.contains(&#39;checked&#39;)){
        termBoxLi.classList.remove(&#39;checked&#39;);
    }else{
        termBoxLi.classList.add(&#39;checked&#39;);
        openTerm();
    }
});</code></pre>
<blockquote>
<p>약관 시나리오 중..</p>
<ul>
<li>약관체크박스가 체크된 상태에서 체크를 해체한다면, 모달창은 나타나지 않도록 제어한다.</li>
</ul>
</blockquote>
<p>위의 내용의 시나리오를 설정하기 위한 코드입니다.
<code>checked</code>라는 클래스의 여부에 따라 조건식을 걸어 각 상황에 맞는 동작을 하도록 만들었습니다.</p>
<h4 id="1-checked되지-않은-상황">1. checked되지 않은 상황</h4>
<p>약관에 체크가 되지 않는다면, 체크 클래스를 추가해주면서 약관 모달창이 나타나도록 하는 함수를 호출해 약관 모달창이 화면에 나타나도록 합니다.</p>
<h4 id="2-checked된-상황">2. checked된 상황</h4>
<p>checked된 상황은 약관 모달창을 열고 닫은 후의 상황이므로, 취소하는 상황만 남게 됩니다.
checked된 상황에서 클릭을 하게 된다면 클래스를 가지고 있어 클래스를 제거만 합니다.
체크박스는 체크되었을때 다시 클릭하게 되면 자동으로 해제 되기 때문에 따로 처리를 하지 않았습니다.
**
이렇게 되면, 약관동의하기를 체크했을 경우에 모달창이 나타나고, 취소하기 위해 다시 클릭했을 경우에는 모달창이 나타나지 않고 체크만 해제됩니다.**</p>
<hr>
<h3 id="마치며">마치며..</h3>
<p> 이번 폼을 만들게 되면서 알게 된 것이 있는에 폼요소를 tab키로 이동하다 마우스의 클릭을 요하는 상황에는 <code>space바</code>를 이용한다는 것을 알게 되었습니다.
 Enter를 누르게되면 form요소가 제출되는 상황이 발생해 키보드만으로도 마우스와 동일하게 작동하고 싶은데 어떻게 해야 하나 고민이 많았는데, 클릭이 <code>space바</code>라는 것을 알고 고민되었던 것들이 쉽게 다가왔습니다.</p>
<p> 이 폼요소가 기획에 따라 초점제어 코드가 달라진다는 것을 생각해 보다면 form요소에도 많은 고려사항이 필요하다는 것을 알게 되었던 것 같습니다.</p>
<p>더 좋은 방법이 있다면 알려주세요.^^</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[무한루프 텍스트 애니메이션 만들기]]></title>
            <link>https://velog.io/@n-u-002/%EB%AC%B4%ED%95%9C%EB%A3%A8%ED%94%84-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@n-u-002/%EB%AC%B4%ED%95%9C%EB%A3%A8%ED%94%84-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Thu, 03 Nov 2022 15:25:41 GMT</pubDate>
            <description><![CDATA[<p>무한으로 반복되는 텍스트 애니메이션은 가끔씩은 필요할 때가 있습니다. 라이브러리를 사용해도 되겠다고 생각은 하지만, 라이브러리를 잘 알지 못하기 때문에 이번 기회에 직접 제작해 보았습니다.</p>
<p> 라이브러리를 사용하지 않고 <strong>Vanilla Javascript</strong>를 이용해 만듭니다.</p>
<p>!codepen[yyyhhh/embed/qBKWgRq?default-tab=js%2Cresult&amp;editable=true&amp;theme-id=dark]</p>
<h3 id="✔️-구상">✔️ 구상</h3>
<p><img src="https://velog.velcdn.com/images/n-u-002/post/79672815-bc18-4254-9ec6-84e4d8da7f39/image.png" alt=""></p>
<ul>
<li>슬라이드를 만드는 방법으로 제작합니다.<ul>
<li>마지막 요소를 클론하여, 첫번째 요소 앞에 붙여주고, 마지막 요소가 나타난 후 바로 클론된 요소의 위치로 이동하여 제작합니다.</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/n-u-002/post/bf2d6d47-381c-4088-888e-410ff31317a3/image.png" alt=""></p>
<ul>
<li>전체 감싸고 있는 요소의 높이를 100%으로 합니다</li>
<li>안의 요소의 갯수가 변경되어도 코드를 수정하지 않아도 동작이 되도록 구현하는 것을 목표로 합니다.</li>
<li>두 개 이상의 요소에 같은 애니메이션을 부여하도록 합니다.</li>
</ul>
<h3 id="✔️-html">✔️ HTML</h3>
<p><code>.move-box</code>의 유형은 2가지 입니다.</p>
<blockquote>
<ol>
<li>하나는 일반적인 텍스트 box</li>
<li>애니메이션을 가지고 있는 텍스트 box</li>
</ol>
</blockquote>
<h3 id="✔️-javascript">✔️ JAVASCRIPT</h3>
<h4 id="🔸-변수">🔸 변수</h4>
<pre><code class="language-javascript">const titlemoveBox = document.querySelectorAll(&quot;.move-box&quot;);</code></pre>
<p>2개의 <code>.moveBox</code>에게 동시에 같은 동작을 주기 위해서 <code>querySelectorAll</code>을 이용해 nodelist의 배열형식으로 변수에 담습니다.</p>
<p>담긴 유사배열은 <code>forEach</code>메소드를 이용해 각 요소에 접근에 동일한 동작을 하도록 할 예정입니다.</p>
<h4 id="🔸-요소의-갯수에-따라-높이의--구하기">🔸 요소의 갯수에 따라 높이의 % 구하기</h4>
<pre><code class="language-javascript">const boxCount = titlemoveBox[0].childElementCount;
//nodelist에서 다른 요소들도 HTML에 구조는 같기때문에 대표적인 요소 하나만 가져와 자식 요소들의 숫자를 변수에 담는다.
const moveRate = 100 / (boxCount + 1);
//전체 높이를 100으로 봤을때 요소의 갯수마다 동일한 높이로 옮기기 위해 자동으로 계산하도록 한다.
// 1을 더한건, 클론이 될 요소 때문에 1을 더한다.
let num = 0;
//num은 titleMove()함수가 호출될때마다 1씩 증가하도록 해서 요소의 갯수보다 크거나 같으면 0이 되어 무한 루프를 돌 수 있도록 해주는 변수</code></pre>
<h4 id="🔸-마지막-요소-클론-함수">🔸 마지막 요소 클론 함수</h4>
<pre><code class="language-javascript">function cloneBox(){
  //클론 Movebox 마지막 div
  titlemoveBox.forEach((elem) =&gt; {

  ////////--마지막 요소를 클론--///////////////
    //elem은 .move-box를 가진 요소들 ( 2개 )
  let lastChild = elem.lastElementChild;
    //마지막 요소들을 변수에 담는다.
  let cloneLast = lastChild.cloneNode(true);
    //마지막요소를 클론해 변수에 담는다.
  elem.prepend(cloneLast);
    //클론한 요소를 첫번째 자식 요소로 추가한다.
  cloneLast.style.opacity = 0;
    //처음 나타났을때는 클론된 요소가 보이지 않기를 원하기 때문에 opacity를 0으로 한다.

    //////--opacity를 0에서 1로 만드는 구간--///////////////
    setTimeout(() =&gt; {
      cloneLast.style.opacity = 1;
      cloneLast.classList.add(&#39;ani&#39;);
      lastChild.classList.add(&#39;ani&#39;);
      //setTimeout을 이용해 로딩 후 첫번째 요소(클론하지 않은 원래의 .move-box의 요소(DIGITAL /DESiGN 텍스트가 있는 요소)가 화면에 나타난 이 후에 opacity를 1로 만들어서 클론된 요소가 나타나게 한다.
      // 그리고 ani클래스를 마지막요소와 클론된 요소에 같은 부여해 애니메이션 재생시작 타이밍을 같이해 딜레이되는 오류를 막는다.

    }, 1000); //로딩 될때 box가 나타난 이후의 시간
  });
}</code></pre>
<h4 id="🔸-무한-로테이션-핸들러-함수">🔸 무한 로테이션 핸들러 함수</h4>
<p><code>requestAnimationFrame()</code>을 이용해 자기자신을 콜백시켜, 자연스러우면서도 반복적인 애니메이션을 만들려고 했습니다.</p>
<pre><code class="language-javascript">function titleMove() {
  num++;

  titlemoveBox.forEach((elem, idx) =&gt; {
    if (num &gt;= boxCount) {
      elem.style.transform = `translateY(-${moveRate * num}%)`;

      //////--마지막 요소에서 클론된 요소로 바꿔치기하는 코드--///////////////
      setTimeout(() =&gt; {
        num = 0;
        elem.style.transition = &quot;none&quot;;
        elem.style.transform = `translateY(-${moveRate * num}%)`;
      }, 1210); 
      //requestAnimation반복 시간(0.4) + 트랜지션시간(0.8) + 약간의 여유(0.1);
      // 아래에서 위로 올라오는 동작의 소요시간이 다 완료 된 다음 바꿔치기를 해야 자연스러운데 바로 하게 되면 조금 &#39;틱틱&#39;거리는 감이 있어서 0.1초를 더 더했다.

    } else {
      elem.style.transition = &quot;0.8s&quot;; 
      elem.style.transform = `translateY(-${moveRate * num}%)`;
    }
  });

  //////--4초마다 반복 실행되도록 하는 코드--///////////////
  setTimeout(() =&gt; {
    window.requestAnimationFrame(titleMove);
  }, 4000); //시간s마다 텍스트가 올라가는 애니메이션 무한 실행
}</code></pre>
<ul>
<li><p><code>num</code></p>
<ul>
<li><p><code>titleMove()</code>함수가 실행될때마다 증가합니다.</p>
</li>
<li><p>증가된 <code>num</code>의 값에 따라 <code>.box-move</code>의 <code>transformY</code>의 값이 증가하도록 만들어 text가 아래에서 위로 올라가는 모습이 보이도록 만듭니다.</p>
</li>
<li><p><code>if조건식</code>을 이용해 마지막 요소가 해당하는 <code>transformY</code>가 발생한 후에 <code>num의 값을 0으</code>로 재할당해서 클론된 요소가 보이도록 합니다.</p>
</li>
<li><p>이때, <code>transition</code>의 값이 없어야 변화가 눈에 보이지 않아 무한루프처럼 보이게 됩니다.</p>
<ul>
<li><p>transition의 값을 지우지 않는다면 빠르게 클론 요소로 옮겨지는 것을 볼 수 있을 겁니다.</p>
</li>
<li><p>아래의 코드펜에서 볼 수 있습니다.</p>
<p>!codepen[yyyhhh/embed/VwdaJGa?default-tab=js%2Cresult&amp;editable=true&amp;theme-id=dark]</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="🔸-호출">🔸 호출</h4>
<pre><code class="language-javascript">window.addEventListener(&#39;load&#39;,()=&gt;{
  cloneBox();
  titleMove();  
})</code></pre>
<p>윈도우가 로드되자마자 두개의 함수를 호출하면 무한 루프 텍스트 애니메이션이 작동이 됩니다.</p>
<h3 id="✔️-마치며">✔️ 마치며..</h3>
<p>이번에도 겹치는 코드들이 있어서 조그만 코드를 정리하면 좋지 않을까하는 생각이 들었습니다. 그리고 애니메이션의 타이밍을 잡을때 transition의 값을 가져와 변수에 담는다면 좋을텐데 라는 생각이 들었지만, 어떤 방법을 사용하면 좋을지 잘 모르겠어서 아쉬움이 있습니다.</p>
<p>더 좋은 방법이 있다면 알려주시면 감사하겠습니다.^^ㅎ</p>
<blockquote>
<h4 id="reference">reference</h4>
<ul>
<li><a href="https://im-developer.tistory.com/97">바닐라 자바스크립트로 무한 루프 슬라이드 래퍼런스</a></li>
<li><a href="https://www.youtube.com/watch?v=7rTW0mndIy0">무한 반복 멀티플 슬라이드, 순수 자바스크립트로 구현하기</a></li>
</ul>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[하위메뉴 일체형]]></title>
            <link>https://velog.io/@n-u-002/%ED%95%98%EC%9C%84%EB%A9%94%EB%89%B4-%EC%9D%BC%EC%B2%B4%ED%98%95</link>
            <guid>https://velog.io/@n-u-002/%ED%95%98%EC%9C%84%EB%A9%94%EB%89%B4-%EC%9D%BC%EC%B2%B4%ED%98%95</guid>
            <pubDate>Thu, 20 Oct 2022 16:39:09 GMT</pubDate>
            <description><![CDATA[<p>이번 예제는 메뉴를 호버 및 초점 진입시 하위메뉴가 전부 나타나는 UI 디자인이다.
호버했을때 호버한 부분의 하위메뉴의 배경색이 변경되어 시각적으로 구분이 되도록 설정하였다.</p>
<p><img src="https://velog.velcdn.com/images/n-u-002/post/6b16b2c0-1588-4275-af7b-88943aa90441/image.png" alt=""></p>
<h3 id="특징">특징</h3>
<h4 id="1-배경색">1. 배경색</h4>
<p>jQuery에서는 마우스 호버에 대한 하위메뉴 배경변경만 설정되어 초접진입시 하위메뉴의 배경색이 변경되지 않는다.
Vanilla JS로 변경할때 초점 진입시에도 지정된 1depth메뉴의 하위메뉴의 배경색을 변경할 수 있도록 보충해 보았다.
<del>(초점 부분 코드 작성할때 정말 애 많이 먹었따...ㅠ 그래서 책 예제에도 언급이 안되어 있었던 건가 싶기도 했다)</del></p>
<h4 id="2-하위메뉴에-최대-height값-자동-부여">2. 하위메뉴에 최대 height값 자동 부여</h4>
<p>이번 메뉴에서는 호버시 흰색 바탕이 메뉴의 회색영역의 높이값만큼 모든 하위메뉴가 동일하게 가져야 하는 경우이다.
css로 하나씩 지정하는 방법이 있을 수 있으나, 유지보수를 생각해보면 번거로운 일이 될 것 이다.
따라서 javascript를 이용해 하위메뉴의 높이 값을 뽑아 비교해 가장 큰 값의 높이값을 모든 하위메뉴의 높이값으로 부여하는 로직을 추가해 콘텐츠의 변화가 있어도 따로 작업을 하지 않도록 설정해 두고 있다.
(물론 회색배경색도 값은 높이값을 부여해 준다.)</p>
<h5 id="jquery">jQuery</h5>
<pre><code class="language-javascript">li.on(&#39;mouseover focusin&#39;, function(){
  hig = 0;
  gnbdiv.each(function(){
    temp = parseInt($(this).outerHeight());
    if(hig &lt;= temp){
      hig = temp;
    }
  });
  gnbdiv.show().css(&#39;height&#39;,hig);
  bg.show().css(&#39;height&#39;,hig);

});
</code></pre>
<h5 id="javascript">Javascript</h5>
<pre><code class="language-javascript">function showMenu(e){
  const eachBg = e.currentTarget.lastElementChild;
  let hig = 0;
  depth2.forEach((div)=&gt; {
    div.style.display = &#39;block&#39;;

    if(div.getAttribute(&#39;style&#39;)){
      let divHig = div.clientHeight;
      if(hig &lt;= divHig) hig = divHig;
    }
  });

  depth2.forEach((div)=&gt; {
    div.style.background = &#39;none&#39;;
    div.style.height = `${hig}px`;
  });
  eachBg.style.background = &#39;#fff&#39;;
  menuBg.style.display = &#39;block&#39;;
  menuBg.style.height = `${hig}px`;
}   </code></pre>
<h2 id="html">HTML</h2>
<p>구조적으로 간단하게 설명하자면 호버시 나타나는 회색 배경은 header섹션에 포함되어 있지 않고 div태그로 독립적으로 위치해 있다.</p>
<pre><code class="language-html">&lt;header&gt;
....
&lt;/header&gt;
&lt;div class=&#39;bg_gnb&#39;&gt;&lt;/div&gt; //&lt;-하위메뉴의 회색 배경</code></pre>
<p>이 이유는 UI 상 호버했을 당시 브라우저 화면너비를 충분히 덮어서 나타나야 하는 UI이다.
header를 중앙으로 배치하기 위해 css로 haeder에 너비값을 1160px로 설정하였다.
따라서, header의 자식으로 있게 되면 header의 너비가 최대의 너비인 1160px만큼만 표현이 되어 브라우저 화면 전체 너비만큼 나타나지 않기 때문에 독립적으로 위치시켜 body를 부모요소로 가지도록 설정해 두었다.</p>
<h2 id="jquery-1">jQuery</h2>
<p>!codepen[yyyhhh/embed/WNJqKKX?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<h2 id="vanilla-javascript">Vanilla Javascript</h2>
<p>!codepen[yyyhhh/embed/ExLBpJB?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<h3 id="함수-showmenu--hidemenu">함수 (showMenu / hideMenu)</h3>
<h4 id="showmenu">showMenu</h4>
<p>하위메뉴가 나타나는 동작하는 함수</p>
<blockquote>
<h4 id="특징-1">특징</h4>
<ul>
<li>하위메뉴와 회색 배경의 높이값을 구해 height값을 부여해 준다.</li>
<li><code>e.currentTarget</code>과 <code>lastElementChild</code></li>
</ul>
</blockquote>
<pre><code class="language-javascript">function showMenu(){
  const eachBg = e.currentTarget.lastElementChild;
  let hig = 0; //가장 큰 높이값을 담을 변수(비교하면서 변경되기때문에 let으로 선언)
  depth2.forEach((div)=&gt; { //forEach를 이용해 Nodelist에 접근 각 하위메뉴에 css를 적용하도록 한다.
    div.style.display = &#39;block&#39;; //일단 화면에 보여야 높이값을 얻을 수 있다.

    // 하위메뉴 높이값 구하는 조건문
    if(div.getAttribute(&#39;style&#39;)){ //하위메뉴가 style을 가지고 있다면 실행
      let divHig = div.clientHeight; //각 하위메뉴의 높이값을 구해 변수에 할당
      if(hig &lt;= divHig) hig = divHig;//위에 선언한 hig와 비교하여 하위메뉴 중 높이 값이 큰 값이 결국에는 hig변수에 할당된다.
    }
  });

  //각 하위메뉴의 높이값 지정
  depth2.forEach((div)=&gt; {
    div.style.background = &#39;none&#39;; //기본적인 값으로 안보이도록 설정
    div.style.height = `${hig}px`;
  });
  //현재 이벤트가 선택된 요소의 자식(하위메뉴)의 배경색 지정
  eachBg.style.background = &#39;#fff&#39;;
  //회색 배경에 높이값 및 block 지정
  menuBg.style.display = &#39;block&#39;;
  menuBg.style.height = `${hig}px`;
} </code></pre>
<ul>
<li><code>div.style.display = &#39;block&#39;;</code> 먼저 실행시킨 이유<ul>
<li>요소가 <code>display : none</code>인 경우에 아무리 height값을 얻어내려고 해도 화면에 보이지 않기 때문에 값을 얻어 낼 수 없는 상태이다. </li>
<li>그래서 각 하위메뉴의 height값을 얻기 위해서 <code>display : block</code>을 실행한 것</li>
</ul>
</li>
</ul>
<h4 id="hidemenu">hideMenu</h4>
<p>지금까지 보였던 것들을 다 없애버도록 동작한다.</p>
<pre><code class="language-javascript">function hideMenu(){
  depth2.forEach((div)=&gt; div.style.display = &#39;none&#39;);
  menuBg.style.display = &#39;none&#39;;
}</code></pre>
<h3 id="이벤트">이벤트</h3>
<h4 id="2-마우스-이벤트">2. 마우스 이벤트</h4>
<pre><code class="language-javascript">depth1Li.forEach((li)=&gt; li.addEventListener(&#39;mouseenter&#39;, showMenu));
depth1Li.forEach((li)=&gt; li.addEventListener(&#39;mouseleave&#39;, hideMenu));</code></pre>
<h4 id="3-초점-이벤트">3. 초점 이벤트</h4>
<pre><code class="language-javascript">depth1Li.forEach((li)=&gt; li.addEventListener(&#39;focusin&#39;,showMenu));
logo.addEventListener(&#39;focusin&#39;,hideMenu);
lang.addEventListener(&#39;focusin&#39;,hideMenu);</code></pre>
<p>초점이 메뉴에 벗어날때 하위메뉴들이 보이지 않도록 하기 위해 메뉴의 앞, 뒤 요소에 초점이 진입할때 hideMenu함수를 실행시켜 하위메뉴가 보이지 않도록 한다.</p>
<br>
<br>

<hr>
<br>
<br>

<h3 id="마치며">마치며...</h3>
<p>이번 예제는 이 글을 쓰면서 오류를 발견해 부랴부랴 오류(초점진입시 마우스 호버효과가 사라졌다)를 수정하고 전반적인 글을 수정하는 과정이 있었다.
초점이 메뉴에 진입 후 동시에 마우스 호버할 경우 css로 지정된 호버 효과(하위메뉴 색상변경) 동작이 작동하지 않은 오류가 발생했다.</p>
<p>!codepen[yyyhhh/embed/eYrwbRq?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<p> 오류 수정과정에서 불필요한 변수가 어떤 것이 있는지를 확인하게 되고 간결하게 원하는 동작을 실행 시킬 수 있는 코드가 된 것 같다.</p>
<br>

<p>나를 제일 애먹게 한건, 초점 진입시에 동작이었다.
초점시 <code>e.target</code>을 이용해 요소를 잡아내려니(초점 이동할때마다 다 다른 요소값이 찍혔다.) 여러가지 고려할 상황이 많아져 초점 이벤트에 어떻게 동작을 시킬 코드 작성에 애를 먹었다.
그러다 <code>e.currentTarget</code>을 이용해 고정된 기준(상위 li)로 하여 동작하도록 하니 초점에 관련된 동작을 작성할 수 있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[하위 메뉴가 세로형 GNB]]></title>
            <link>https://velog.io/@n-u-002/%ED%95%98%EC%9C%84-%EB%A9%94%EB%89%B4%EA%B0%80-%EC%84%B8%EB%A1%9C%ED%98%95-GNB</link>
            <guid>https://velog.io/@n-u-002/%ED%95%98%EC%9C%84-%EB%A9%94%EB%89%B4%EA%B0%80-%EC%84%B8%EB%A1%9C%ED%98%95-GNB</guid>
            <pubDate>Mon, 17 Oct 2022 15:23:54 GMT</pubDate>
            <description><![CDATA[<p>이번에는 하위메뉴가 가로로 나타는 메뉴를 jQuery로 <code>마우스 호버</code>, <code>초점진입</code> 코드를 Vanilla Javascript로 변경하는 작업을 하였다.</p>
<p>jQuery로는 <code>fadeIn()와 fadeOut()</code>메서드를 이용해 <code>display:none</code>인 요소를 부드럽게 나타나지만, 같은 css를 이용해야 하는 전제조건(<del>css까지 하기에는 귀찮다.</del>)으로 javascript에는 약간의 나타나는 효과는 다를 수 있으나, 마우스 호버와 초점진입에 대한 동작이 같도록 하는 것을 목표로 하였다.</p>
<h2 id="jquery">jQuery</h2>
<p>!codepen[yyyhhh/embed/gOzyoxQ?default-tab=html%2Cresult&amp;theme-id=dark]</p>
<pre><code class="language-javascript">$(document).ready(function () {
  //gnb의 li에 마우스오버, 포커싱 했을때 동작
  $(&quot;.gnb li&quot;).on(&quot;mouseover focusin&quot;, function () {
    $(this).children(&quot;ul&quot;).stop().fadeIn(300);
  });
  //마우스가 떠나갈떄 동작
  $(&quot;.gnb li&quot;).on(&quot;mouseleave&quot;, function () {
    $(this).children(&quot;ul&quot;).stop().fadeOut(200);
  });
  //배경색이 나타나도록 하는 동작
  $(&quot;.gnb&quot;).on(&quot;mouseover focusin&quot;, function () {
    $(&quot;.bg_gnb&quot;).stop().fadeIn(300);
  });
  $(&quot;.gnb&quot;).on(&quot;mouseleave focusout&quot;, function () {
    $(&quot;.bg_gnb&quot;).stop().fadeOut(200);
  });
  //1뎁스 메뉴에서 키보드 초점이 벗어나면 ul이 없어지는 작용을 한다.
  $(&quot;.gnb &gt; li&quot;).on(&quot;focusout&quot;, function () {
    $(this).children(&quot;ul&quot;).stop().fadeOut(200);
  });
});</code></pre>
<h2 id="javascript">Javascript</h2>
<h3 id="1-map을-이용해-각-요소에-이벤트-지정">1. map()을 이용해 각 요소에 이벤트 지정</h3>
<p><code>전개연산자</code>와 <code>map()</code>을 이용해 Nodelist에 접근해 각 요소에 이벤트들이 실행되면 지정된 함수가 실행되도록 작성해 보았다.</p>
<p>!codepen[yyyhhh/embed/gOzyozq?default-tab=html%2Cresult&amp;theme-id=dark]</p>
<h4 id="1뎁스의-li에-초점-진입시-이벤트">1뎁스의 li에 초점 진입시 이벤트</h4>
<pre><code class="language-javascript">[...depth1].map((li)=&gt;{
  li.addEventListener(&quot;mouseenter&quot;,function(e){
    const target = e.target;
    notShowMenu();  
    showMenu(target);
  });

  li.addEventListener(&quot;mouseleave&quot;,function(e){
    const target = e.target;
    notShowMenu();  
  });
});</code></pre>
<h4 id="1뎁스의-a에-초점-진입시-이벤트">1뎁스의 a에 초점 진입시 이벤트</h4>
<pre><code class="language-javascript">[...depth1TagA].map((a)=&gt;{
  const lastLi = a.nextElementSibling.lastElementChild;
  a.addEventListener(&quot;focusin&quot;,function(e){
    const target = e.target.parentElement;
    notShowMenu();
    showMenu(target);
  });
  lastLi.addEventListener(&quot;focusout&quot;,function(e){
    notShowMenu();
  });
})</code></pre>
<ul>
<li><code>focusout</code> 이벤트 경우
  <code>lastLi(하위메뉴의 마지막 li)</code>에 초점이 나갈때 하위메뉴가 사라지도록 했다.<ul>
<li>초점 같은 경우에는 순차적 탐색이 가능해야 하는데 <code>a</code>태그에 <code>focusout 이벤트</code>를 지정해주면 하위메뉴가 나타나지만 다음 tab동작에서 초점이 a태그를 벗어나기 때문에 하위메뉴로 초점이 가지 않는 상황이 발생했다.</li>
<li>따라서 <code>focusout</code>이벤트는 하위메뉴를 다 탐색하고 난 후 마지막 li에 초점이 떠날때 하위메뉴가 사라지는 함수인 <code>notShowMenu()</code>를 불러 동작하게 했다.</li>
</ul>
</li>
</ul>
<h4 id="하위메뉴에-동작-대한-함수">하위메뉴에 동작 대한 함수</h4>
<pre><code class="language-javascript">//메뉴 나타남(a 호버시 형제 노드인 ul의 style을 지정)
function showMenu(elem){
  elem.querySelector(&#39;ul&#39;).style.display = &#39;block&#39;;
  bg.style.display = &#39;block&#39;;
}
//사라짐(a호버, 초점 진입시 -&gt; 모든 ul의 style을 지정해 다 안보이게 만든다. )
function notShowMenu(){  
  [...depth2].map((ul)=&gt; ul.style.display = &#39;none&#39;);
  bg.style.display = &#39;none&#39;;
}</code></pre>
<h5 id="매개변수로-받지-않고-queryselectorall을-이용해-nodelist형태로-받은-이유">매개변수로 받지 않고 querySelectorAll을 이용해 Nodelist형태로 받은 이유</h5>
<p>다른 li에 호버 및 초점 진입시 다른(형제) li들의 하위메뉴 인 ul이 보이지 않아야 하기 떄문이다.
인수로 받을 경우 해당 타켓된 ul의 메뉴만 사라지기 때문에 Nodelist형태에 map()을 이용해 모든 ul에 display = none을 지정해주어 하위메뉴가 보이지 않도록 해주었다.</p>
<h3 id="2-위의-코드를-정리예정">2. 위의 코드를 정리(...예정)</h3>
<br>
<br>
<br>
<br>


<hr>
<h2 id="마치며">마치며</h2>
<p>저번 <a href="https://velog.io/@n-u-002/%ED%95%98%EC%9C%84%EB%A9%94%EB%89%B4%EA%B0%80-%EC%84%B8%EB%A1%9C%ED%98%95-GNB">하위메뉴가 세로형 GNB</a>에서는 nodeElement를 이용해 코드를 작성하려고 했으나 class를 이용해 해결했다면 이번에는 매개변수로 element를 받고 그 element의 자식, 형제 node를 찾아 스타일을 지정하는 방법으로 해결하였다.</p>
<p>솔직히 이 방법이 좋은 방법인지는 잘 모르겠지만, 일단은 화면상에서 jQuery에서 의도한 동작을 Javascript를 통해 동작하고 있다는 것에 의의를 둔다.</p>
<p>글을 적으면서 2개의 함수(나타나는 함수와 사라지는 함수)로 코드를 정리하면 어떨까 하는 생각이 들었다. 시간이 된다면 차차 2개의 함수 안에 코드를 넣어 함수를 호출해 동작하도록 해봐야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[jQurey → Vanilla JS로 변경 스터디(메뉴 - 웹접근성 고려 스크립트)]]></title>
            <link>https://velog.io/@n-u-002/%EC%B4%88%EC%A0%90%EC%9D%B4%EB%8F%99-%EC%A0%9C%EC%96%B4jQurey-Vanilla-JS%EB%A1%9C-%EB%B3%80%EA%B2%BD-%EC%8A%A4%ED%84%B0%EB%94%94</link>
            <guid>https://velog.io/@n-u-002/%EC%B4%88%EC%A0%90%EC%9D%B4%EB%8F%99-%EC%A0%9C%EC%96%B4jQurey-Vanilla-JS%EB%A1%9C-%EB%B3%80%EA%B2%BD-%EC%8A%A4%ED%84%B0%EB%94%94</guid>
            <pubDate>Tue, 11 Oct 2022 22:50:58 GMT</pubDate>
            <description><![CDATA[<p>아직까지도 퍼블리싱에 관련되 JS들은 jQurey를 이용해 DOM요소들을 조작하는 경우가 많다. 이제는 jQurey는 레거시로 여겨지면서 Vanilla JS로 코드를 수정하는 작업이 필요함을 느꼈다. 또한, 나도 jQurey보다 Vanilla JS로 작업을 하기 때문에 jQurey가 어렵게 느껴지는 경우가 종종 있다.
<del>사용하는 것을 지양하는 추세이다 보니 공부할 필요성을 느끼지 못하기도 하다.</del></p>
<h3 id="📖-스터디에-사용한-책">📖 스터디에 사용한 책</h3>
<p><img src="https://image.aladin.co.kr/product/27406/36/cover500/k042732457_1.jpg" alt="">
웹접근성 마크업을 공부하기 위해 
<a href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=274063602">리베하얀의 웹퍼블리셔를 위한 실무 UI 패턴집 &lt;메뉴 편&gt;</a>를 공부했다.</p>
<p>이 책은 <code>메뉴</code>만 다루는데 웹접근성(초점이동)을 중점으로 공부하기 위해 읽으면 도움이 많이 되는 책이다. 아쉽게도, 책은 jQurey를 이용해 스크립트가 작성되어 있어 내가 다니는 회사 실무에 적용하기에 에러사항이 있다.</p>
<p>따라서, 접근성 중에서도 초점이동관련 스크립트 공부 할 겸, 책에 나온 예제들을 jQurey를 Vanilla JS로 바꿔보려 한다.</p>
<h3 id="✔️-스터디-목표">✔️ 스터디 목표</h3>
<p>jQuery의 내용을 그대로 변경하는 것이 아닌, jQuery 스크립트일때와 동일한 동작을 하도록 Vanilla JS로 변경하는 것을 목표로 하였다.</p>
<h3 id="✔️-스터디-리스트">✔️ 스터디 리스트</h3>
<ol>
<li><a href="https://velog.io/@n-u-002/%ED%95%98%EC%9C%84%EB%A9%94%EB%89%B4%EA%B0%80-%EC%84%B8%EB%A1%9C%ED%98%95-GNB">하위메뉴가 세로형 GNB</a></li>
<li><a href="">comming soon...ㅎ</a></li>
</ol>
<p>공부해하면서 하나씩 채울 예정...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[마크업 - IR기법]]></title>
            <link>https://velog.io/@n-u-002/%EB%A7%88%ED%81%AC%EC%97%85-IR%EA%B8%B0%EB%B2%95</link>
            <guid>https://velog.io/@n-u-002/%EB%A7%88%ED%81%AC%EC%97%85-IR%EA%B8%B0%EB%B2%95</guid>
            <pubDate>Tue, 20 Sep 2022 15:48:05 GMT</pubDate>
            <description><![CDATA[<h2 id="hide-클래스">hide 클래스</h2>
<p>hide 클래스는 텍스트를 화면에 표시하지 않을때 사용한다.
&#39;한국형 웹 콘텐츠 접근성 지침 2.1 : 대체텍스트&#39;를 위한 으로<code>IR기법</code>이라고 한다.</p>
<blockquote>
<h3 id="ir기법">IR기법</h3>
<p>&#39;의미 있는 배경 이미지&#39;조항에서 배경이미지란 <code>background-image</code>속성으로 표현하는 방법인데 이때 삽입한 이미지가 의미가 있다면 이미지를 설명할 수 있는 텍스트를 제공해야 한다.
<br>
브라우저 화면에는 이미지를 설명하는 텍스트가 노출되지 않게 하는 방법</p>
</blockquote>
<pre><code class="language-css">.hide{
    overfolw : hidden;
    display:block;
    position : absolute;
    border : 0;
    width : 1px;
    height : 1px;
    clip : rect(1px,1px,1px,1px)
    }</code></pre>
<p>IR기법을 적용하면 마우스나 기보드의 초점이 사라지지 않아 화면 낭독기가 제대로 인식을 할 수 있다.</p>
<h2 id="ir-기법-예시">IR 기법 예시</h2>
<h3 id="메뉴">메뉴</h3>
<pre><code class="language-html">&lt;header&gt;
  &lt;h1&gt;&lt;a href=&quot;&quot;&gt;&lt;span class=&quot;hide&quot;&gt;로고&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;
  &lt;h2 class=&#39;hide&#39;&gt;메인 메뉴&lt;/h2&gt;
  &lt;nav&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;&quot;&gt;기업정보&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;&quot;&gt;기업정보&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;&quot;&gt;기업정보&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/nav&gt;
&lt;/header&gt;</code></pre>
<ul>
<li><code>&lt;h2 class=&#39;hide&#39;&gt;메인 메뉴&lt;/h2&gt;</code> 인 경우에는 스크린리더 사용자에게 이 영역이 <code>메인 메뉴</code>인 부분의 시작을 알려주기 위해 사용된 대체 텍스트이다.<ul>
<li>브라우저 화면 영역에는 나타나지 않으며 스크린리더에서 읽어준다.</li>
</ul>
</li>
</ul>
<h3 id="콘텐츠-블록">콘텐츠 블록</h3>
<h4 id="한국형-웹-콘텐츠-접근성-지침-21---제목-제공">한국형 웹 콘텐츠 접근성 지침 2.1 - 제목 제공</h4>
<p>콘텐츠 블록 제목 구성 : 콘텐츠 블록에는 적절한 제목(heading)을 제공하면 제목과 본문을 구분 할 수 있으며, 제목을 이용하여 콘텐츠 블록 간의 이동이 가능하다.
그러나, 본문이 없는 콘텐츠 블록에는 제목을 붙이지 않는다.</p>
<p>블록을 시작할 때 제목 요소 <code>&lt;h1&gt; ~ &lt;h6&gt;</code>를 사용해서 해당 콘텐츠에 대한 적절한 제목을 표시해야 한다.</p>
<hr>
<h4 id="유틸리티-메뉴">유틸리티 메뉴</h4>
<blockquote>
<p>로그인, 로그아웃, 마이페이지, 다국어 사이트 이동, 검색 등과 같은 보조 기능으로 구성된 메뉴</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[GSAP - 숫자 카운터 애니메이션]]></title>
            <link>https://velog.io/@n-u-002/GSAP-%EC%88%AB%EC%9E%90-%EC%B9%B4%EC%9A%B4%ED%84%B0-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98</link>
            <guid>https://velog.io/@n-u-002/GSAP-%EC%88%AB%EC%9E%90-%EC%B9%B4%EC%9A%B4%ED%84%B0-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98</guid>
            <pubDate>Sat, 20 Aug 2022 14:23:51 GMT</pubDate>
            <description><![CDATA[<h2 id="⌛-gsap을-이용한-숫자-카운트-애니메이션-만들기">⌛ GSAP을 이용한 숫자 카운트 애니메이션 만들기</h2>
<p> 이번에는 변화되는 숫자가 위에서 아래로, 아래에서 위로 움직여 변화하는 애니메이션 모션을 만들어보았습니다.
 <a href="https://kafeaterra.eu/en">랜딩페이지에 숫자가 변화되는 애니메이션을 래퍼런스</a>로하여 <strong>GSAP을 이용</strong>해 사용해보았습니다.</p>
<p><del>(디테일적인 면은 완전히 다르지만, 일단은 숫자가 변경되는 모습을 구현하는 것에 초점을 맞췄습니다)</del>
<del>또한, 이 페이지는 <a href="https://github.hubspot.com/odometer/docs/welcome/">odometor.js</a>를 이용한 것 같습니다.</del></p>
<p><img src="https://velog.velcdn.com/images/n-u-002/post/ac6cc3b2-1dcc-481e-84bc-0e8e763f2b3a/image.gif" alt=""></p>
<p>!codepen[yyyhhh/embed/qBKZoKd?default-tab=js%2Cresult&amp;editable=true&amp;theme-id=dark]</p>
<h3 id="구상">구상</h3>
<p><img src="https://velog.velcdn.com/images/n-u-002/post/4c7a2ead-b77b-46e2-a583-e051c55f4fd9/image.png" alt=""></p>
<ul>
<li>애니메이션 구상은 <code>.number-wrap</code>의 <code>y(translateY)</code>값을 조절해 화면에 보이는 숫자가 변경되어 보이도록 합니다.</li>
<li>숫자 변화를 동일하게 주기 위해서 숫자 <code>0 - 9</code>의 <code>li</code>를 한 번 더 만들어 그 <code>numberWrap</code>의     <code>y</code>값에 변화를 주고자 했습니다.</li>
<li>만들어질 함수에 인자 값이 화면에 나오는 숫자와 동일하도록 만드는 것을 목표로 하였습니다.</li>
</ul>
<h3 id="html">HTML</h3>
<pre><code class="language-html">&lt;section id=&quot;numberCount&quot;&gt;
                &lt;div class=&quot;Count-wrap&quot;&gt;
                    &lt;ul class=&quot;nb1&quot;&gt;
                        &lt;span class=&quot;number-wrap&quot;&gt;
                            &lt;li&gt;0&lt;/li&gt;
                            &lt;li&gt;1&lt;/li&gt;
                            &lt;li&gt;2&lt;/li&gt;
                            &lt;li&gt;3&lt;/li&gt;
                            &lt;li&gt;4&lt;/li&gt;
                            &lt;li&gt;5&lt;/li&gt;
                            &lt;li&gt;6&lt;/li&gt;
                            &lt;li&gt;7&lt;/li&gt;
                            &lt;li&gt;8&lt;/li&gt;
                            &lt;li&gt;9&lt;/li&gt;
                            &lt;li&gt;0&lt;/li&gt;
                            &lt;li&gt;1&lt;/li&gt;
                            &lt;li&gt;2&lt;/li&gt;
                            &lt;li&gt;3&lt;/li&gt;
                            &lt;li&gt;4&lt;/li&gt;
                            &lt;li&gt;5&lt;/li&gt;
                            &lt;li&gt;6&lt;/li&gt;
                            &lt;li&gt;7&lt;/li&gt;
                            &lt;li&gt;8&lt;/li&gt;
                            &lt;li&gt;9&lt;/li&gt;

                        &lt;/span&gt;
                    &lt;/ul&gt;
                    &lt;ul class=&quot;nb2&quot;&gt;
                        &lt;span class=&quot;number-wrap&quot;&gt;
                            &lt;li&gt;0&lt;/li&gt;
                            &lt;li&gt;1&lt;/li&gt;
                            &lt;li&gt;2&lt;/li&gt;
                            &lt;li&gt;3&lt;/li&gt;
                            &lt;li&gt;4&lt;/li&gt;
                            &lt;li&gt;5&lt;/li&gt;
                            &lt;li&gt;6&lt;/li&gt;
                            &lt;li&gt;7&lt;/li&gt;
                            &lt;li&gt;8&lt;/li&gt;
                            &lt;li&gt;9&lt;/li&gt;
                            &lt;li&gt;0&lt;/li&gt;
                            &lt;li&gt;1&lt;/li&gt;
                            &lt;li&gt;2&lt;/li&gt;
                            &lt;li&gt;3&lt;/li&gt;
                            &lt;li&gt;4&lt;/li&gt;
                            &lt;li&gt;5&lt;/li&gt;
                            &lt;li&gt;6&lt;/li&gt;
                            &lt;li&gt;7&lt;/li&gt;
                            &lt;li&gt;8&lt;/li&gt;
                            &lt;li&gt;9&lt;/li&gt;

                        &lt;/span&gt;
                    &lt;/ul&gt;
                    &lt;ul class=&quot;nb3&quot;&gt;
                        &lt;span class=&quot;number-wrap&quot;&gt;
                            &lt;li&gt;0&lt;/li&gt;
                            &lt;li&gt;1&lt;/li&gt;
                            &lt;li&gt;2&lt;/li&gt;
                            &lt;li&gt;3&lt;/li&gt;
                            &lt;li&gt;4&lt;/li&gt;
                            &lt;li&gt;5&lt;/li&gt;
                            &lt;li&gt;6&lt;/li&gt;
                            &lt;li&gt;7&lt;/li&gt;
                            &lt;li&gt;8&lt;/li&gt;
                            &lt;li&gt;9&lt;/li&gt;
                            &lt;li&gt;0&lt;/li&gt;
                            &lt;li&gt;1&lt;/li&gt;
                            &lt;li&gt;2&lt;/li&gt;
                            &lt;li&gt;3&lt;/li&gt;
                            &lt;li&gt;4&lt;/li&gt;
                            &lt;li&gt;5&lt;/li&gt;
                            &lt;li&gt;6&lt;/li&gt;
                            &lt;li&gt;7&lt;/li&gt;
                            &lt;li&gt;8&lt;/li&gt;
                            &lt;li&gt;9&lt;/li&gt;

                        &lt;/span&gt;
                    &lt;/ul&gt;
                    &lt;ul class=&quot;nb4&quot;&gt;
                        &lt;span class=&quot;number-wrap&quot;&gt;
                            &lt;li&gt;0&lt;/li&gt;
                            &lt;li&gt;1&lt;/li&gt;
                            &lt;li&gt;2&lt;/li&gt;
                            &lt;li&gt;3&lt;/li&gt;
                            &lt;li&gt;4&lt;/li&gt;
                            &lt;li&gt;5&lt;/li&gt;
                            &lt;li&gt;6&lt;/li&gt;
                            &lt;li&gt;7&lt;/li&gt;
                            &lt;li&gt;8&lt;/li&gt;
                            &lt;li&gt;9&lt;/li&gt;
                            &lt;li&gt;0&lt;/li&gt;
                            &lt;li&gt;1&lt;/li&gt;
                            &lt;li&gt;2&lt;/li&gt;
                            &lt;li&gt;3&lt;/li&gt;
                            &lt;li&gt;4&lt;/li&gt;
                            &lt;li&gt;5&lt;/li&gt;
                            &lt;li&gt;6&lt;/li&gt;
                            &lt;li&gt;7&lt;/li&gt;
                            &lt;li&gt;8&lt;/li&gt;
                            &lt;li&gt;9&lt;/li&gt;

                        &lt;/span&gt;
                    &lt;/ul&gt;
                &lt;/div&gt;
            &lt;/section&gt;</code></pre>
<p>모션을 만들게 되면 불필요한 HTML태그들을 생성해야 한다는 것을 이번 카운터 애니메이션을 만들면서 알게 되었습니다. 
이것들을 사용할때만 생성해서 화면 상에 나타낼 수 없을까 하는 생각이 듭니다만, 실력이 부족하다는 것을 알고 있으므로, 제가 할 수 있는 최선의 방법으로 HTML과 CSS를 최대한 이용해 만들어 보았습니다.</p>
<h3 id="css">CSS</h3>
<pre><code class="language-css">#numberCount{
    display: flex;
    justify-content: center;
    flex-direction : column;
    width: 100%;
    height: 200%;
    margin-top : 50px;
    text-align : center;
/*     border : 3px solid red; */
  }
  #numberCount &gt; .Count-wrap{
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top : 50px;
  }
  #numberCount &gt; .Count-wrap ul{
    position: relative;
    display: block;
    width: 200px;
    height: 100px;
/*     border: 3px solid salmon; */
    overflow: hidden;
  }
  .number-wrap{
    display: block;
  }
  #numberCount li{
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-shrink : 1;
    font-size: 100px;
/*     border: 7px solid yellow; */
  }</code></pre>
<h3 id="jsgsap">JS(GSAP)</h3>
<pre><code class="language-javascript">const numberWrap = document.querySelector(&quot;.number-wrap&quot;);
const number = document.querySelector(&quot;.number-wrap li&quot;);
const numberHeight = number.offsetHeight;

//gsap 애니메이션을 타이밍을 한번에 관리하기 위해 timeline을 사용했습니다.
const counterTimeline = gsap.timeline();

//numberWrap이 이동할때, 루즈하지 않도록 해주기 위해 위치 값을 변화를 크게 주기 위해 지정한 변수 : r
let r = 0;

//이동할 값 계산해주는 함수
const count = (i) =&gt; {
  let rv = -(numberHeight * (i + 10 * r));
  return rv;
};

//애니메이션 호출 함수
const countAnimation = (n, m, o, p) =&gt; {
  counterTimeline
    .add(&quot;start&quot;)
    .to(
    &quot;.nb1 .number-wrap&quot;,
    { y: count(n), ease: &quot; Power1.easeOut&quot; },
    &quot;start&quot;
  )
    .to(
    &quot;.nb2 .number-wrap&quot;,
    { y: count(m), ease: &quot; Power1.easeOut&quot; },
    &quot;start+=0.3&quot;
  )
    .to(
    &quot;.nb3 .number-wrap&quot;,
    { y: count(o), ease: &quot; Power1.easeOut&quot; },
    &quot;start+=0.5&quot;
  )
    .to(
    &quot;.nb4 .number-wrap&quot;,
    { y: count(p), ease: &quot; Power1.easeOut&quot; },
    &quot;start+=0.7&quot;
  );
    //r의 값의 조건을 걸어 이동값에 변화를 줍니다.
  if (r === 0) {
    r++;
  } else if (r == 1) {
    r--;
  }
};

//초기값
countAnimation(1, 9, 8, 7);

//Gsap을 이용해 해당영역에서 애니메이션이 실행되도록 설정합니다.
ScrollTrigger.create({
  trigger: &quot;#numberCount&quot;,
  start: &quot;top-=5% top&quot;,
  end: &quot;+=100%&quot;,
  scroller: pageContainer,
  pin: true,
  markers: true,
  scrub: true,
  onEnter: () =&gt; {
    countAnimation(2, 0, 2, 2);
    //뷰포트와 start값이 위에서 아래로 스크롤할때 함수 실행
  },
  onLeaveBack: () =&gt; {
    countAnimation(1, 9, 8, 7);
    //뷰포트와 start값이 아래에서 위로 스크롤될떄 함수 실행
  },
});</code></pre>
<br>
<br>

<h3 id="⌛-마치며">⌛ 마치며...</h3>
<p>현재 만든 예제에는 HTML코드 상으로 보기가 안좋은 것 같단 생각이 듭니다. 반복되는 것들이 많다고 할까요.. 자바스크립트 코드 같은 경우에는 객체로 묶에 HTML에 넣어주거나, 반복되는 코드를 반복문을 돌려 실행하는 것은 어떨까하는 아쉬움이 있습니다만, 지금의 제 실력은 여기까지 인 것 같습니다. 
클래스나 프로토타입를 이용해 코드를 정리하도록 공부해야 할 것 같습니다. ㅎ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 1316. 그룹 단어 체커]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-1316.-%EA%B7%B8%EB%A3%B9-%EB%8B%A8%EC%96%B4-%EC%B2%B4%EC%BB%A4</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-1316.-%EA%B7%B8%EB%A3%B9-%EB%8B%A8%EC%96%B4-%EC%B2%B4%EC%BB%A4</guid>
            <pubDate>Sun, 14 Aug 2022 15:35:32 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-1316-그룹-단어-체커">백준 1316. 그룹 단어 체커</h2>
<p><a href="https://www.acmicpc.net/problem/1316">https://www.acmicpc.net/problem/1316</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">const fs = require(&quot;fs&quot;);
const file = process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;;
let input = fs.readFileSync(file).toString().split(&quot;\r\n&quot;);
let count = 0;

for (let i = 1; i &lt;= input[0]; i++) {
  let arr = [];
  let string = input[i].split(&quot;&quot;);
  for (let j = 0; j &lt; string.length; j++) {
    if (!arr.includes(string[j])) {
      arr.push(string[j]);
    }
    if (string[j - 1] === string[j]) arr.push(string[j]);
  }

  if (arr.join(&quot;&quot;) === input[i]) count++;
}
console.log(count);
</code></pre>
<p>문제 풀이 강의
<a href="https://www.youtube.com/watch?v=btH6nvpvO2k">https://www.youtube.com/watch?v=btH6nvpvO2k</a></p>
<h4 id="문제-개념">문제 개념</h4>
<p>입력 받은 단어가 1개 또는 연속 중복 될때의 단어를 &quot;그룹단어&quot;라 칭한다.
즉, &#39;a&#39;, &#39;b&#39; / &#39;aab&#39;, &#39;abbbcccc&#39; 는 모두 다 &quot;그룹단어&quot;이다.
하지만, &#39;aba&#39;와 같은 단어는 이미 나온 철자가 있으므로, &quot;그룹단어&quot;가 아니다.</p>
<ul>
<li>각 단어를 받은 후 철자로 쪼갠다.</li>
<li>빈 배열에 각 절차의 유무를 비교 후 배열에 담긴 철자들을 입력 받았던 단어와 비교한다.</li>
<li>그렇게 되면 나중에 같은 철자가 나와도 중복되지 한 번만 배열에 담기게 된다.</li>
<li>중복된 철자 그룹의 조건식을 세워 연속으로(인덱스값사용) 중복된 철자를 배열에 담도록 한다.</li>
<li>입력 받은 단어와 배열의 값이 같다면 count를 올린다면, 제시한 단어 중에 그룹단어의 조건에 맞는 단어의 개수를 알 수 있다.</li>
</ul>
<h4 id="문제-풀이-과정">문제 풀이 과정</h4>
<ol>
<li>문자를 <code>split()</code>를 이용해 철자으로 쪼갠다.</li>
<li>쪼갠 철자를 빈 배열에<code>includes</code>를 사용하여 배열안에 쪼갠 철자의 유무를 판단 후 <code>push</code>를 해주되, 배열에 이미 있는 철자라면 <code>push</code>하지 않도록 한다.</li>
<li>다만, 중복 철자(&quot;pp, cccc, dd&quot;)등 과 같은 연속적인 철자는 조건(<code>string[j - 1] === string[j]</code>)을 걸어 <code>push</code>해준다.</li>
<li>각 단어의 철자는 for문이 다 돌게 되면, 빈배열에 담겨진 각 철자은 <code>join()</code>메서드를 이용해 한 단어로 만든다. </li>
<li>만들어진 단어를 입력 받은 단어와 같다면 <code>count</code>의 값을 올려준다.</li>
</ol>
<h3 id="문제를-풀면서-알게-된-것">문제를 풀면서 알게 된 것</h3>
<ul>
<li>주어진 조건 및 입력값을 충분히 활용하면 문제를 풀 수 있다.</li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/includes"><code>includes()</code></a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 2941 -  크로아티아 알파벳 ]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-2941-%ED%81%AC%EB%A1%9C%EC%95%84%ED%8B%B0%EC%95%84-%EC%95%8C%ED%8C%8C%EB%B2%B3</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-2941-%ED%81%AC%EB%A1%9C%EC%95%84%ED%8B%B0%EC%95%84-%EC%95%8C%ED%8C%8C%EB%B2%B3</guid>
            <pubDate>Thu, 11 Aug 2022 14:37:32 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-2941----크로아티아-알파벳">백준 2941 -  크로아티아 알파벳</h2>
<p><a href="https://www.acmicpc.net/problem/2941">https://www.acmicpc.net/problem/2941</a></p>
<h3 id="❌-제출한-풀이1">❌ 제출한 풀이1</h3>
<pre><code class="language-javascript">let input = fs.readFileSync(file).toString().trim();
const croatiaAlph = [&quot;c=&quot;, &quot;c-&quot;, &quot;dz=&quot;, &quot;d-&quot;, &quot;lj&quot;, &quot;nj&quot;, &quot;s=&quot;, &quot;z=&quot;];

for (let i = 0; i &lt; croatiaAlph.length; i++) {
  input = input.replaceAll(croatiaAlph[i], 0);
}
console.log(input.length);</code></pre>
<ul>
<li><code>replace()</code>메서드는 동일한 문자를 중에 일치하는 문자 중 첫번째만 치환시켜준다.</li>
<li><code>replaceAll()</code>메서드를 이용하여 입력받는 문자열의 일치하는 문자를 <code>0</code>으로 치환하는 방향으로 문제를 풀었다.<br>
그런데, 이 문제가 만들어진지 오래 되어서 그런지 최근에 추가된 메서드를 쓰지 못하는 것인지...알 수는 없지만, 계속 오답으로 채점이 되어서 다른 방법을 찾아보았다.</li>
</ul>
<blockquote>
<p><a href="https://7942yongdae.tistory.com/47"><code>replaceAll()</code>은  ECMA-262 12th(2021) 스펙 기준으로 추가</a>된 메서드여서 최신개발환경이 아니라면 사용이 어려운 것같다.</p>
</blockquote>
<h3 id="⭕-제출한-풀이2">⭕ 제출한 풀이2</h3>
<pre><code class="language-javascript">let input = fs.readFileSync(file).toString().trim();
const croatiaAlph = [&quot;c=&quot;, &quot;c-&quot;, &quot;dz=&quot;, &quot;d-&quot;, &quot;lj&quot;, &quot;nj&quot;, &quot;s=&quot;, &quot;z=&quot;];

for (let elem of croatiaAlph) {
  input = input.split(elem).join(&quot;0&quot;);
}
console.log(input.length);</code></pre>
<ol>
<li><p>문자 -&gt; 분리된 배열</p>
<ul>
<li>각 배열의 요소를 input의 문자열을 같은 요소들이 있다면 <code>split()</code>메서드를 이용해 문자를 자른다.</li>
</ul>
</li>
<li><p>분리된 배열요소 -&gt; 문자</p>
<ul>
<li>그리고 잘려진 문자배열을 <code>join()</code>메서드를 이용해 배열의 요소를 문자열로 만들어주되, 기준을 <code>join()</code>메서드의 인자로 이어붙여준다.</li>
</ul>
</li>
<li><p>join()으로 변환된 문자열은 input에 재 할당되어 다음 for문의 순서에 사용된다.</p>
</li>
</ol>
<blockquote>
<p><strong>elem : 1번상황 -&gt; 2번상황 : input의 값으로 재할당된다.(3번)</strong>
&quot;c=&quot; : [ &#39;ljes=njak&#39; ] -&gt; ljes=njak
&quot;c-&quot; : [ &#39;ljes=njak&#39; ] -&gt; ljes=njak
&quot;dz=&quot; : [ &#39;ljes=njak&#39; ] -&gt; ljes=njak
&quot;d-&quot; : [ &#39;ljes=njak&#39; ] -&gt; ljes=njak
&quot;lj&quot; : [ &#39;&#39;, &#39;es=njak&#39; ] -&gt; 0es=njak
&quot;nj&quot; : [ &#39;ljes=&#39;, &#39;ak&#39; ] -&gt; 0es=0ak
&quot;s= : [ &#39;lje&#39;, &#39;njak&#39; ] -&gt; 0e00ak
&quot;z=&quot; : [ &#39;ljes=njak&#39; ] -&gt; 0e00ak </p>
</blockquote>
<h3 id="풀면서-알게-된-것">풀면서 알게 된 것</h3>
<ul>
<li><code>replaceAll</code>은 2021의 아주 최신버전 기능이여서 적용되지 않는 곳이 있을 수 있다.</li>
<li><code>let 요소 in 배열</code> : map()메서드 처럼 사용 가능한 반복문 조건</li>
<li>문자 치환 관련해서는 정규표현식을 이용해야 좋을 것 같다.. 공부할거 너무 많은데?ㅎㅎ</li>
</ul>
<h3 id="reference">Reference</h3>
<p><a href="https://jb-dailylife.tistory.com/entry/%EB%B0%B1%EC%A4%80-nodejs-2941%EB%B2%88-%ED%81%AC%EB%A1%9C%EC%95%84%ED%8B%B0%EC%95%84-%EC%95%8C%ED%8C%8C%EB%B2%B3">split(),join()이용 풀이 블로그</a>
<a href="https://codechacha.com/ko/javascript-replace-in-string/">정규포현식 약간</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 1152 - 단어개수]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-1152-%EB%8B%A8%EC%96%B4%EA%B0%9C%EC%88%98</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-1152-%EB%8B%A8%EC%96%B4%EA%B0%9C%EC%88%98</guid>
            <pubDate>Sun, 24 Jul 2022 12:33:20 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-1152---단어개수">백준 1152 - 단어개수</h2>
<p><a href="https://www.acmicpc.net/problem/1152">https://www.acmicpc.net/problem/1152</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">const fs = require(&quot;fs&quot;);
const file = process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;;
let input = fs.readFileSync(file).toString().trim().split(&quot; &quot;);

if (input[0] === &quot;&quot;) {
  console.log(0);
} else {
  console.log(input.length);
}</code></pre>
<ul>
<li>문자열을 공백을 기준으로 잘랐을때의 배열의 길이를 출력하면 되겠다 생각해서 제출했는데 오답이 나왔다.</li>
<li>예외의 케이스를 생각해야 한다는 것을 알게 되었고, 공백이었을때의 예외처리를 해서 제출하였다.</li>
</ul>
<h3 id="문제를-풀면서-알게-된-것">문제를 풀면서 알게 된 것</h3>
<ul>
<li><code>trim()</code> : 계속해서 오답이 나와서 이상하다고 생각했는데 trim()을 사용하니 정답이 되었다.<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/Trim"><code>trim()</code></a>은 문자열 양 끝의 공백을 제거해준다.<ul>
<li>예외처리에 대해 생각하기</li>
</ul>
</li>
</ul>
</li>
</ul>
<br>
<br>
<br>
<br>

<h3 id="😂문제를-잘-못-이해해서">😂문제를 잘 못 이해해서...</h3>
<p>문제를 잘 못 이해해서 문장에 사용된 철자의 개수를 구해 출력하도록 하는 코드로 문제를 풀다가 답이 너무 많이 나와서 다시 문제를 읽게 되고, 내가 잘 못 풀고 있음을 알게 되었다...</p>
<h4 id="문제를-잘-읽어보자-">문제를 잘 읽어보자 !</h4>
<h4 id="잘못-이해해-풀어본-코드">잘못 이해해 풀어본 코드</h4>
<pre><code class="language-javascript">// 1. 알파벳배열개수를 가진 배열을 생성한다. fill(false)
// 2. input의 요소들을 하나로 쪼갠다.
// 3. 아스키코드의 숫자를 이용해 알파벳 숫자 배열의 false -&gt; true로 만든다.
// 4. true의 개수를 구해 출력한다.

let Arr = new Array(26).fill(false);

for (let i = 0; i &lt; input.length; i++) {
  let splitArr = input[i].split(&quot;&quot;);
  for (let j = 0; j &lt; splitArr.length; j++) {
    Arr[splitArr[j].charCodeAt(0) - 65] = true;
  }
}

let count = 0;
const result = Arr.filter((elem) =&gt; {
  if (elem === true) count++;
});

console.log(count);</code></pre>
<p>틀렸는지 맞았는지는 잘 모르겠지만, true의 개수를 통해 사용된 알파벳의 개수를 구하는 코드를 만드는 삽질을 하고 다시 문제를 제대로 읽고 풀었다.ㅎ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 1157 - 단어공부]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-1157-%EB%8B%A8%EC%96%B4%EA%B3%B5%EB%B6%80</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-1157-%EB%8B%A8%EC%96%B4%EA%B3%B5%EB%B6%80</guid>
            <pubDate>Sun, 24 Jul 2022 12:22:37 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-1157---단어공부">백준 1157 - 단어공부</h2>
<p><a href="https://www.acmicpc.net/problem/1157">https://www.acmicpc.net/problem/1157</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">const fs = require(&quot;fs&quot;);
const file = process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;;
let input = fs.readFileSync(file).toString().toUpperCase().split(&quot;&quot;);
//아스키코드를 이용하기 위해 전체 문자열을 대문자로 변환시켜준다.

let Arr = new Array(26).fill(0);

for (let i = 65; i &lt; 91; i++) {
  for (let j = 0; j &lt; input.length; j++) {
    if (i === input[j].charCodeAt(0)) {
      Arr[i - 65] += 1;
    }
  }
}

let count = 0;
let maxNum = Math.max(...Arr);

Arr.map((elem) =&gt; {
  if (elem === maxNum) count++;
});

count === 1
  ? console.log(String.fromCharCode(Arr.indexOf(maxNum) + 65))
  : console.log(&quot;?&quot;);
</code></pre>
<ul>
<li>문제 접근 <ul>
<li>아스키코드를 이용 (대문자 알파벳 : 65 - 90)</li>
<li>알파벳 개수만큼을 가진 배열을 생성(0-25) -&gt; 0 : A, 1: B .... 25 : z</li>
<li>알파벳 배열에 숫자를 이용해 중복된 값이 있는지 확인</li>
<li>중복 된 값이 있다면 ? 출력 / 아니면 알파벳 배열에 인덱스를 찾고 + 65의 숫자 값을 아스키코드의 알파벳으로 변환</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">let Arr = new Array(26).fill(0);</code></pre>
<p>알파벳 개수에 맞는 배열 생성 / 0으로 다 채움</p>
<pre><code class="language-javascript">for (let i = 65; i &lt; 91; i++) {  //아스키코드를 확인하기 위한 i
  for (let j = 0; j &lt; input.length; j++) { //input의 배열을 순회하기 위한 j
    if (i === input[j].charCodeAt(0)) { //i와 input의 요소의 아스키코드가 같다면?
      Arr[i - 65] += 1;
      //같다면 Arr배열에 넣는데, Arr배열을 0부터 25까지 밖에 없음 
      //즉, (아스키코드 - 65)를해야 배열에 잘 넣을 수 있음
    }
  }
}</code></pre>
<p>input안에 있는 철자들이 아스크코드와 맞는지 확인 후 맞다면 1을 더해준다.</p>
<pre><code class="language-javascript">let count = 0;
let maxNum = Math.max(...Arr);
//Max.max는 배열을 그대로 넣을 수 없어 스프레드 연산자를 이요해서 넣어야 작동된다. 아니면 apply이용

Arr.map((elem) =&gt; {
  if (elem === maxNum) count++;
});</code></pre>
<p>Arr의 배열을 순회해 count를 더한다.
count는 중복수를 알아보기 위한 변수</p>
<pre><code class="language-javascript">count === 1
  ? console.log(String.fromCharCode(Arr.indexOf(maxNum) + 65))
  : console.log(&quot;?&quot;);</code></pre>
<p>count값이 1이라면 숫자를 알파벳으로 변환(아스키코드이용<code>String.fromCharCode()</code>)
count값이 1보다 크다면 -&gt; 중복된 값이 있다는 뜻이므로, &quot;?&quot;를 출력한다.</p>
<h3 id="문제를-풀면서-알게-된-것">문제를 풀면서 알게 된 것</h3>
<ul>
<li><code>toUpperCase()</code></li>
<li><code>String.fromCharCode()</code></li>
<li><code>Math.max(...Array)</code></li>
</ul>
<br>

<hr>
<h4 id="reference">Reference</h4>
<p><a href="https://onelight-stay.tistory.com/368">https://onelight-stay.tistory.com/368</a>
<a href="https://gurtn.tistory.com/49">https://gurtn.tistory.com/49</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 2675 - 문자열 반복]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-2675-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B0%98%EB%B3%B5</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-2675-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B0%98%EB%B3%B5</guid>
            <pubDate>Sun, 24 Jul 2022 12:05:12 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-2675---문자열-반복">백준 2675 - 문자열 반복</h2>
<p><a href="https://www.acmicpc.net/problem/2675">https://www.acmicpc.net/problem/2675</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">
const fs = require(&quot;fs&quot;);
const file = process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;;
let input = fs.readFileSync(file).toString().split(&quot;\n&quot;);

for (let i = 1; i &lt;= input[0]; i++) { //index 1번부터 출력값을 도출해야 하기 때문에 1부터 시작
  let result = &quot;&quot;;   //반복될 문자열을 넣는 변수
  let arr = input[i].split(&quot; &quot;);  
  let word = arr[1].split(&quot;&quot;);
  for (let j = 0; j &lt; arr[1].length; j++) {
    result += word[j].repeat(arr[0]);
  }
  console.log(result);
}
</code></pre>
<blockquote>
<h4 id="입력값">입력값</h4>
<p>2
3 ABC
5 /HTP</p>
</blockquote>
<ul>
<li>첫번째 for문은 입력된 첫번째 값을 이용해 for문을 두번 순회하도록 하였다.</li>
<li><code>let arr = input[i].split(&quot; &quot;);</code> : 반복해야하는 숫자와 문자열을 공백을 기준으로 분리</li>
<li><code>let word = arr[1].split(&quot;&quot;);</code> : 문자열을 한 글자씩 분리하여 word에 배열로 담는다.</li>
<li><code>for (let j = 0; j &lt; arr[1].length; j++)</code> : for문을 이용해서 word배열에 문자들을 순회</li>
<li><code>result += word[j].repeat(arr[0]);</code> : <a href="https://curryyou.tistory.com/199">repeat()메서드</a>를 이용해 문자열을 반복시켜 result변수에 담아 출력한다.<ul>
<li><code>arr[0]</code>의 값은 문자열을 반복할 개수를 뜻하기 때문에 이용</li>
</ul>
</li>
</ul>
<h3 id="문제를-풀면서-알게-된-것">문제를 풀면서 알게 된 것</h3>
<ul>
<li><code>reapeat()</code>메서드 </li>
</ul>
<br>

<hr>
<h4 id="reference">Reference</h4>
<p><a href="https://curryyou.tistory.com/199">https://curryyou.tistory.com/199</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 10809 - 알파벳 찾기]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-10809-%EC%95%8C%ED%8C%8C%EB%B2%B3-%EC%B0%BE%EA%B8%B0</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-10809-%EC%95%8C%ED%8C%8C%EB%B2%B3-%EC%B0%BE%EA%B8%B0</guid>
            <pubDate>Tue, 19 Jul 2022 06:28:36 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-10809---알파벳-찾기">백준 10809 - 알파벳 찾기</h2>
<p><a href="https://www.acmicpc.net/problem/10809">https://www.acmicpc.net/problem/10809</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">const fs = require(&quot;fs&quot;);
const file = process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;;
let input = fs.readFileSync(file).toString().split(&quot;&quot;);

let stringArr = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;,&quot;e&quot;,&quot;f&quot;,&quot;g&quot;,&quot;h&quot;,&quot;i&quot;,&quot;j&quot;,&quot;k&quot;,&quot;l&quot;,&quot;m&quot;,&quot;n&quot;,&quot;o&quot;,&quot;p&quot;,&quot;q&quot;,&quot;r&quot;,&quot;s&quot;,&quot;t&quot;,&quot;u&quot;,&quot;v&quot;,&quot;w&quot;,&quot;x&quot;,&quot;y&quot;,&quot;z&quot;];

for (let i = 0; i &lt; stringArr.length; i++) {
  for (let j = 0; j &lt; input.length; j++) {
    if (input[j] === stringArr[i]) {
      stringArr[i] = j;
    }
  }
}

for (let k = 0; k &lt; stringArr.length; k++) {
  if (typeof stringArr[k] === &quot;string&quot;) stringArr[k] = -1;
}

console.log(stringArr.join(&quot; &quot;));
</code></pre>
<h3 id="문제풀이-과정">문제풀이 과정</h3>
<ol>
<li>구상</li>
</ol>
<ul>
<li>입력값인 input의 인덱스 값을 이용해서 알파벳 순서의 배열에 넣어준다.</li>
</ul>
<ol start="2">
<li>풀이</li>
</ol>
<ul>
<li>중첩 for문을 이용해 <code>stringArr</code>(알파벳 문자가 들어있는 배열)에 input배열의 요소와 같은 것을 찾아 내고, 찾은 요소를 input의 인덱스 값으로 변경 시켜준다.</li>
<li>새로운 for문을 이용해 변경되지 않은 요소들은 <code>문자타입</code>이므로, 문자타입만을 골라 요소의 값을 <code>-1</code>로 변경한다.</li>
<li>출력할때에는 배열을 문자열로 출력해야 하기 때문에 <code>join()</code>메서드를 사용해서 배열을 문자로 변경하여 출력한다</li>
</ul>
<h3 id="문제를-풀면서-겪은-에러-및-생각">문제를 풀면서 겪은 에러 및 생각</h3>
<ul>
<li><code>map()</code>을 이용해 배열의 요소를 변경할려고 했는데 배열의 요소들이 <code>undefined</code>가 나와서 for문으로 변경했다.</li>
<li>처음 for문 안에서 다 해결할려고 했는데 <code>else문안에 input[i] != stringArr[j]일때</code>의 경우에 <code>-1</code>을 넣으려고 하니, 출력되는 배열의 모든 요소가 <code>-1</code>이 되어 새로운 for문을 돌려 <code>-1</code>값을 배열에 넣어줬다.</li>
<li>뭔가 이 방법 보다 더 좋은 방법이 있을 것 같긴 한데.. 잘 모르겠다.<br>

</li>
</ul>
<p>이번 문제는 검색하지 않고 내가 문제를 보고 구상하고 문제를 풀어서 뿌듯하다 ㅎㅎㅎ</p>
<br>
<br>

<hr>
<h4 id="reference">Reference</h4>
<p><a href="https://codechacha.com/ko/javascript-array-to-string/">join메서드</a></p>
<h3 id="❗아스키코드를-이용해-문제푸는-방식">❗아스키코드를 이용해 문제푸는 방식</h3>
<p><a href="https://gurtn.tistory.com/48">https://gurtn.tistory.com/48</a></p>
<ul>
<li>알파벳의 아스키코드는 97 ~ 122 번이다.</li>
<li><code>String.fromCharCode()</code>를 이용하게 되면 인자로 들어온 숫자를 아스키코드가 가지고 있는 문자열로 변환해주는데 input에 <code>indexOf</code>를 이용해 input안에 들어온 아스키코드의 값이 들어있는지 체크한다.</li>
<li><code>index0f()</code>메서드를 이용해 배열에 <code>indexOf()</code>메서드 인자의 값이 없으면 <code>-1</code>을 반환하게 되는데 그 값을 새로운 배열에 넣어준다.</li>
</ul>
<br>


<h3 id="알게-된것">알게 된것</h3>
<ul>
<li>숫자, 문자를 아스키코드로 변환 : <code>charCodeAt()</code></li>
<li>아스키코드를 문자로 변환 : <code>String.formCharCode()</code> </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 11720 - 숫자의 합]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-11720-%EC%88%AB%EC%9E%90%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-11720-%EC%88%AB%EC%9E%90%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Tue, 19 Jul 2022 06:14:36 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-11720---숫자의-합">백준 11720 - 숫자의 합</h2>
<p><a href="https://www.acmicpc.net/problem/11720">https://www.acmicpc.net/problem/11720</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">const fs = require(&quot;fs&quot;);
const file = process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;;
let input = fs.readFileSync(file).toString().split(&quot;\n&quot;);
let num = 0;

const numArr = input[1].split(&quot;&quot;).map((i) =&gt; (num += Number(i)));
console.log(num);
</code></pre>
<p>for문을 이용해 답을 찾으려 했으나, for문이 중접되는 것 같아 <code>map()</code>메서드를 이용해 배열에 각 요소마다 접근해 <code>num</code>변수에 값을 축적하는 방식으로 접근했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준11654 - 아스키코드]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%8011654-%EC%95%84%EC%8A%A4%ED%82%A4%EC%BD%94%EB%93%9C</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%8011654-%EC%95%84%EC%8A%A4%ED%82%A4%EC%BD%94%EB%93%9C</guid>
            <pubDate>Tue, 19 Jul 2022 06:10:58 GMT</pubDate>
            <description><![CDATA[<h2 id="백준14681---사분면-고르기">백준14681 - 사분면 고르기</h2>
<p><a href="https://www.acmicpc.net/problem/11654">https://www.acmicpc.net/problem/11654</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">const fs = require(&quot;fs&quot;);
const file = process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;;
let input = fs.readFileSync(file).toString().split(&quot;&quot;);

console.log(input[0].charCodeAt(0));
</code></pre>
<p>문제를 풀면서 <code>아스키코드</code>라는 개념 자체를 처음 접했다.
이건 뭔가 싶었는데 절대로 내 머리로 구현할 수 없는 규칙?인 것 같았다. 그래서 왠지 자바스크립트 언어내에서 도출할 수 있는 메소드가 있을 거서 같았고, 검색해 보니 <code>charCodeAt()</code>메소드를 알게 되었다.</p>
<h3 id="풀면서-알게-된-것">풀면서 알게 된 것</h3>
<ul>
<li><code>charCodeAt()</code> : &#39;UTF-16&#39;코드로 문자, 숫자를 값을 도출 할 수 있다.</li>
</ul>
<br>
<br> 

<hr>
<h4 id="reference">Reference</h4>
<p><a href="http://delftstack.com/ko/howto/javascript/javascript-convert-character-code-to-ascii-code/">http://delftstack.com/ko/howto/javascript/javascript-convert-character-code-to-ascii-code/</a>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 4344. 평균은 넘겠지]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-4344.-%ED%8F%89%EA%B7%A0%EC%9D%80-%EB%84%98%EA%B2%A0%EC%A7%80</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-4344.-%ED%8F%89%EA%B7%A0%EC%9D%80-%EB%84%98%EA%B2%A0%EC%A7%80</guid>
            <pubDate>Tue, 12 Jul 2022 14:03:50 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-4344-평균은-넘겠지">백준 4344. 평균은 넘겠지</h2>
<p><a href="https://www.acmicpc.net/problem/4344">https://www.acmicpc.net/problem/4344</a></p>
<blockquote>
<h3 id="문제-해결-접근-순서">문제 해결 접근 순서</h3>
<p>1.반 평균을 구한다.
2.반 평균을 넘은 학생 수를 구한다.
3.학생수 / 전체 학생수의 비율을 구한다.</p>
</blockquote>
<h3 id="❌-제출한-풀이">❌ 제출한 풀이</h3>
<pre><code class="language-javascript">for(let i = 1; i &lt;= input[0]; i++){
    let sum = 0;
    let score = 0;
    let filterArr = [];

    // 1.반평균 구하기
    let numArr = input[i].split(&#39; &#39;).map((i)=&gt;+i);
    for(let j = 1; j &lt;= numArr[0]; j++){
        sum += numArr[j]; 
    }
    score = sum/numArr[0];

    //2. 반 평균을 넘는 학생 수 구하기
    filterArr = numArr.filter((i)=&gt; i &gt; score);

    //3. 학생 비율 구하기
    let rate = (filterArr.length)/ numArr[0] * 100;
    console.log(rate.toFixed(3) + &#39;%&#39;);
}</code></pre>
<ul>
<li>출력된 값은 똑같이 나왔는데 오답으로 처리 되었다.</li>
</ul>
<p><br><br></p>
<h3 id="⭕-제출한-풀이">⭕ 제출한 풀이</h3>
<pre><code class="language-javascript">const fs = require(&#39;fs&#39;);
const file = process.platform === &#39;linux&#39; ? &#39;/dev/stdin&#39; : &#39;./input.txt&#39;;
let input = fs.readFileSync(file).toString().split(&#39;\n&#39;);

for(let i = 1; i &lt;= input[0]; i++){
    let sum = 0;
    let score = 0;
    let filterArr = [];

    // 1.반평균 구하기
    let numArr = input[i].split(&#39; &#39;).map((i)=&gt;+i);
    let studentNum = numArr.shift()
    for(let j = 0; j &lt; studentNum; j++){
        sum += numArr[j]; 
    }
    score = sum/studentNum;

    //2. 반 평균을 넘는 학생 수 구하기
    filterArr = numArr.filter((i)=&gt; i &gt; score);

    //3. 학생 비율 구하기
    let rate = (filterArr.length)/ studentNum * 100;
    console.log(rate.toFixed(3) + &#39;%&#39;);
}</code></pre>
<ul>
<li>틀린 코드에서 <code>numArr[0]</code>으로 사용한 부분을 <code>shift()</code>메서드를 이용해 잘라 변수에 저장하여 그 값으로 대체 했더니 정답으로 처리 되었다.</li>
</ul>
<ol>
<li>반 평균 구하기<ul>
<li>numArr배열의 모든 요소를 sum 값에 누적시킨다.</li>
<li>누적된 값의 평균값을 score변수에 넣는다.</li>
</ul>
</li>
<li>반 평균을 넘는 학생 수 구하기<ul>
<li>filter()메서드를 이용해 score값이 큰 요소들만 들어있는 배열을 만든다.</li>
</ul>
</li>
<li>학생 비율 구하기<ul>
<li>필터링 된 값을 가진 배열의 길이로 학생수를 구한 후, 전체 학생 수로 나누어 % 값을 얻는다. </li>
<li>소수점 3자리 수의 값을 얻기 위해 <code>toFixed()</code>메서드를 이용해 소수점 자리수의 값을 얻는다.</li>
</ul>
</li>
</ol>
<br>
<br>

<h3 id="문제를-풀면서-알게-된-것">문제를 풀면서 알게 된 것</h3>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed"><code>toFixed()</code></a>메서드를 사용하면 원하는 소수점 자리를 얻을 수 있다.</li>
<li>필요에 의해 배열의 요소를 제거하는 것<ul>
<li><code>shift()</code>메서드를 이용하면 제거된 값을 반환한다.</li>
</ul>
</li>
</ul>
<br>
<br>

<hr>
<h4 id="reference">Reference</h4>
<p><a href="https://7942yongdae.tistory.com/173">소수점 자리 반올림, 내림, 올림 포스팅</a>
<a href="https://gurtn.tistory.com/45">shift()를 이용해 값을 따로 저장</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 8958 OX퀴즈]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-8958-OX%ED%80%B4%EC%A6%88</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-8958-OX%ED%80%B4%EC%A6%88</guid>
            <pubDate>Tue, 12 Jul 2022 11:39:37 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-8958-ox퀴즈">백준 8958 OX퀴즈</h2>
<p><a href="https://www.acmicpc.net/problem/8958">https://www.acmicpc.net/problem/8958</a></p>
<blockquote>
<h4 id="입력값">입력값</h4>
<p>5
OOXXOXXOOO
OOXXOOXXOO
OXOXOXOXOXOXOX
OOOOOOOOOO
OOOOXOOOOXOOOOX</p>
</blockquote>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">for(let i = 1; i&lt;= input[0]; i++){
    let count = 0;
    let newArr = input[i].split(&#39;X&#39;).map((i)=&gt;{
        for(let j =1; j &lt;= i.length; j++){
            count += j
        }
    });

    console.log(count);
}</code></pre>
<ul>
<li><p>input의 요소에 split()를 사용해 입력값에 &#39;X&#39;를 기준으로 &#39;O&#39;만 남긴다.</p>
<blockquote>
</blockquote>
<p>[ &#39;OO&#39;, &#39;&#39;, &#39;O&#39;, &#39;&#39;, &#39;OOO&#39; ] <br>
[ &#39;OO&#39;, &#39;&#39;, &#39;OO&#39;, &#39;&#39;, &#39;OO&#39; ]<br>
[&#39;O&#39;, &#39;O&#39;, &#39;O&#39;,&#39;O&#39;, &#39;O&#39;, &#39;O&#39;, &#39;O&#39;, &#39;&#39;]<br>
[ &#39;OOOOOOOOOO&#39; ]<br>
[ &#39;OOOO&#39;, &#39;OOOO&#39;, &#39;OOOO&#39;, &#39;&#39; ]</p>
</li>
<li><p>문자의 길이(글자수) length를 이용해 각 요소의 글자 수를 최대값으로 한 for문을 만든다.</p>
</li>
<li><p>요소의 글자수 만큼의 최대값을 j가 최대값을 가지게 된다.</p>
</li>
<li><p>j의 값만큼 count변수에 값을 더해주면 &#39;O&#39;연속해서 퀴즈를 풀어 누적된 점수를 얻을 수 있다. </p>
</li>
</ul>
<br>

<h3 id="문제를-풀면서-알게-된-것">문제를 풀면서 알게 된 것</h3>
<p> &#39;X&#39;값을 제거하는 것 까지는 생각했는데 그 다음 스텝을 풀 방법이 생각나지 않아 어려움이 있었다. 다른 사람들은 어떻게 풀었나 검색해 보았더니 for문을 이용해서 풀어서 for문을 사용했다. 다른 사람들이 푼 것을 따라하는 것이 아닌, 내가 생각했던 풀이방법으로 풀어보고 싶어서 다른 사람들꺼보다는 풀이 과정이 복잡해진 것 같지만, 구상했던 풀이방법으로 문제를 풀 수 있어 뜻 깊었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준. 1546 평균]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80.-1546-%ED%8F%89%EA%B7%A0</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80.-1546-%ED%8F%89%EA%B7%A0</guid>
            <pubDate>Tue, 12 Jul 2022 11:24:20 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-1546-평균">백준. 1546 평균</h2>
<p><a href="https://www.acmicpc.net/problem/1546">https://www.acmicpc.net/problem/1546</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<pre><code class="language-javascript">let input = fs.readFileSync(file).toString().split(&#39;\r\n&#39;);
let score = input[1].split(&#39; &#39;).map((i) =&gt; +i);

// 1. 최대값 M 을 구한다.
// 2. 최대값의 인덱스를 구해서 filter를 사용해 나머지 값들에게( 점수 / M * 100)해준다.

function changScore(score){
    const M = Math.max(...score);
    let sum = 0;
    for(let i = 0; i &lt; input[0]; i++){
        sum += score[i] / M * 100;
    }
    console.log(sum /input[0]);
}
changScore(score);</code></pre>
<ul>
<li>최대값 구하는 것은 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Math/max">Math.max()메서드</a>를 이용하여 구했다.<ul>
<li>Math.max()메서드의 인자로 배열을 그대로 넣을 수 없다.</li>
<li>따라서 spread 문법을 이용해 배열의 요소를 넣어 최대값을 구할 수 있다.</li>
</ul>
</li>
<li>문제에 따라 각 점수을 계산해야 하기 때문에 for문을 이용해 각 점수에 접근 후 sum변수에 값을 더해주었다.</li>
</ul>
<br>

<h3 id="문제를-풀면서-알게-된-것">문제를 풀면서 알게 된 것</h3>
<ul>
<li>문제를 제대로 읽고 이해 할 것!<ul>
<li>제대로 이해 못해서 이상하게 문제풀지 말자</li>
</ul>
</li>
<li><code>Math.max(...score)</code>에 배열의 요소를 넣는 방법<ul>
<li><code>Math.max(score)</code> 통째로 넣었는데 에러가 나서 문제를 풀 수 없었는데 배열을 넣는 방법이 따로 있다는 것을 이번에 알 수 있었다.</li>
</ul>
</li>
<li>for문을 적극적으로 사용해 볼 것</li>
</ul>
<br>
<br>

<hr>
<h4 id="reference">Reference</h4>
<p><a href="https://gurtn.tistory.com/53">https://gurtn.tistory.com/53</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준. 3052. 나머지]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80.-3052.-%EB%82%98%EB%A8%B8%EC%A7%80</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80.-3052.-%EB%82%98%EB%A8%B8%EC%A7%80</guid>
            <pubDate>Fri, 01 Jul 2022 06:45:39 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-3052-나머지">백준. 3052. 나머지</h2>
<p><a href="https://www.acmicpc.net/problem/3052">https://www.acmicpc.net/problem/3052</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<h4 id="풀이-과정">풀이 과정</h4>
<ol>
<li>24를 나눈 나머지를 구한다.</li>
<li>서로 다른 값 비교해 배열을 만든다.</li>
<li>그 배열의 길이를 구해 개수를 구한다.</li>
</ol>
<pre><code class="language-javascript">const fs = require(&#39;fs&#39;);
const file = process.platform === &quot;linux&quot; ? &#39;/dev/stdin&#39; : &#39;./input.txt&#39;;
let input = fs.readFileSync(file).toString().trim().split(&#39;\n&#39;);
let result =[];

input.map((i)=&gt; {
  //1번
   let rem = i % 42;
  //2번
    if(result.indexOf(rem) === -1){
        result.push(rem);
    }
});
//3번
console.log(result.length);</code></pre>
<ul>
<li>2번 과정<ul>
<li>result의 배열은 빈 배열을 시작으로 값의 나머지 값들을 하나씩 같게 되는데 업데이트 되는 과정에서 이미 있는 값이 있을 경우에는 push되지 않음으로 똑같은 값은 배열에 들어갈 수 없다.</li>
<li><code>indexOf()</code>에는 들어온 인자가 배열에 없다면 <code>-1</code>을 반환한다. 그것을 이용해 result배열에 일치하는 요소가 있다면 그 요소의 index값을 반환하여 push되지 않는다.</li>
<li>따라서, result에는 중복되지 않은 나머지의 값들을 가질 수 있다.</li>
</ul>
</li>
<li>입력 받는 데이터에 숫자 뒤 공백 하나가 있어서 틀렸는데 <code>trim()</code>메서드를 이용해서 불필요한 공백을 없애고 하니 답을 맞출 수 있었다.</li>
</ul>
<h3 id="다른-풀이-new-set사용">다른 풀이 (new Set()사용)</h3>
<pre><code class="language-javascript">let newArr = input.map((i)=&gt; i % 24);
let count = new Set(newArr);
console.log(count.size);</code></pre>
<ul>
<li><code>new Set()</code>은 중복된 요소를 갖지 않는 객체이다.
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set</a></li>
<li><code>set객체</code>는 일단 객체와 다르게 사용법이 조금 다르다.
<a href="https://miiingo.tistory.com/323">https://miiingo.tistory.com/323</a><ul>
<li><code>set 객체</code>의 길이를 알기 위해서는 size라는 프로퍼티를 이용한다.</li>
</ul>
</li>
</ul>
<h4 id="풀면서-알게-된-것">풀면서 알게 된 것</h4>
<ul>
<li><code>indexOf</code>를 통해 중복된 요소를 찾는 방법</li>
<li><code>set 객체</code> </li>
<li><code>trim()</code></li>
</ul>
<hr>
<h4 id="reference">Reference</h4>
<p><a href="https://gurtn.tistory.com/44">https://gurtn.tistory.com/44</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백준 2562. 최댓값]]></title>
            <link>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-2562.-%EC%B5%9C%EB%8C%93%EA%B0%92</link>
            <guid>https://velog.io/@n-u-002/JS-%EB%B0%B1%EC%A4%80-2562.-%EC%B5%9C%EB%8C%93%EA%B0%92</guid>
            <pubDate>Mon, 27 Jun 2022 15:40:00 GMT</pubDate>
            <description><![CDATA[<h2 id="백준-2562-최댓값">백준 2562. 최댓값</h2>
<p><a href="https://www.acmicpc.net/problem/2562">https://www.acmicpc.net/problem/2562</a></p>
<h3 id="제출한-풀이">제출한 풀이</h3>
<blockquote>
<ol>
<li>입력 받는 값은 배열로 만든다.</li>
<li>input의 배열을 복사한다.(깊은 복사를 해서 원본 배열이 바뀌지 않도록 한다.)</li>
<li>sort()를 이용해서 배열을 오름차순으로 정렬한다.</li>
<li>출력(원배열에서 최대값의 인덱스를 찾는다.)</li>
</ol>
</blockquote>
<pre><code class="language-javascript">//1
let input = fs.readFileSync(file).toString().split(&#39;\n&#39;).map(Number);
//2
let cloneInput = [...input];

//3
cloneInput.sort((a, b) =&gt; b - a);
//4
console.log(cloneInput[0]);
console.log(input.indexOf(cloneInput[0]) + 1);</code></pre>
<h3 id="풀면서-알게-된-것">풀면서 알게 된 것</h3>
<ul>
<li><code>indexOf()</code>은 0부터 시작한다. (인덱스이므로!)</li>
<li>배열을 가지고 있는 변수를 다른 변수에 할당할 경우, <code>얕은 복사?</code>가 일어나는 것 같다.</li>
<li><blockquote>
<p>콘솔에 찍었을때 배열의 순서가 바뀌였었다.</p>
</blockquote>
</li>
<li>변하기 않은 배열을 만들기 위해 <code>spread문법</code>을 이용해서 깊은 복사를 해서 사용했다.</li>
</ul>
<br>
<br><br>

<hr>
<h4 id="reference">Reference</h4>
<p><a href="https://developer-talk.tistory.com/159">https://developer-talk.tistory.com/159</a>
<a href="https://bbaktaeho-95.tistory.com/40">https://bbaktaeho-95.tistory.com/40</a></p>
]]></description>
        </item>
    </channel>
</rss>