<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>nemo-cat.log</title>
        <link>https://velog.io/</link>
        <description>담신믄 넴모넴모 빔메 맞맜습니다.</description>
        <lastBuildDate>Wed, 22 May 2024 08:48:06 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>nemo-cat.log</title>
            <url>https://velog.velcdn.com/images/nemo-cat/profile/2587fc6e-4d0d-4a6b-8e2c-f7614c3f732e/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. nemo-cat.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/nemo-cat" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[나 보려고 만든 GSAP 사용법]]></title>
            <link>https://velog.io/@nemo-cat/%EB%82%98-%EB%B3%B4%EB%A0%A4%EA%B3%A0-%EB%A7%8C%EB%93%A0-GSAP-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@nemo-cat/%EB%82%98-%EB%B3%B4%EB%A0%A4%EA%B3%A0-%EB%A7%8C%EB%93%A0-GSAP-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Wed, 22 May 2024 08:48:06 GMT</pubDate>
            <description><![CDATA[<p>나중에 나 보려고 작성해두는 gsap 간단 사용법!</p>
<p><a href="https://gsap.com/">gsap 홈페이지 바로가기</a></p>
<hr>
<h2 id="gsap--scrolltrigger-cdn">GSAP &amp; ScrollTrigger CDN</h2>
<pre><code class="language-html">&lt;!-- gsap cdn --&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js&quot;&gt;&lt;/script&gt;

&lt;!-- gsap ScrollTrigger --&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js&quot;&gt;&lt;/script&gt;</code></pre>
<h3 id="scrolltigger-플러그인-등록">ScrollTigger 플러그인 등록</h3>
<blockquote>
<p>ScrollTrigger 사용하려면 js파일에 플러그인을 등록해줘야함.</p>
</blockquote>
<pre><code class="language-js">// 스크롤트리거 플러그인 불러오기
gsap.registerPlugin(ScrollTrigger);</code></pre>
<hr>
<h2 id="gsap-기본-사용법">GSAP 기본 사용법</h2>
<p>GASP 기본 사용법에는 <code>gsap.to()</code>, <code>gsap.from()</code>, <code>gsap.fromTo()</code> 메소드가 있다. 순서대로 애니메이션의 끝점, 시작점, 시작과 끝점을 정해주는 메소드이다.</p>
<blockquote>
<h3 id="gsapto">gsap.to()</h3>
</blockquote>
<p>to 메소드는 요소를 기본 상태에서 -&gt; to(끝점)값으로 변경시킨다.</p>
<pre><code class="language-js">gsap.to()(`타겟요소`, { 애니메이션 속성 : 속성 값, ... });</code></pre>
<blockquote>
<h3 id="gsapfrom">gsap.from()</h3>
</blockquote>
<p>from 메소드는 요소를 from(시작점)상태에서 -&gt; 기본상태로 변경시킨다. (to랑 반대)</p>
<pre><code class="language-js">gsap.from()(`타겟요소`, { 애니메이션 속성 : 속성 값, ... });</code></pre>
<blockquote>
<h3 id="gsapfromto">gsap.fromTo()</h3>
</blockquote>
<p>fromTo 메소드는 요소의 첫 시작점(from)과 끝점(to)를 지정할 수 있다.</p>
<pre><code class="language-js">gsap.fromTo()(`타겟요소`, { from 값(애니메이션 시작점) }, { to 값(애니메이션 끝점)});</code></pre>
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="wvbGVwL" data-pen-title="gsap animation" data-user="So-An" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/So-An/pen/wvbGVwL">
  gsap animation</a> by So-An (<a href="https://codepen.io/So-An">@So-An</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<blockquote>
<h3 id="gsaptimeline">gsap.timeline()</h3>
</blockquote>
<p><code>gsap.timeline()</code> 메소드를 통해 애니메이션을 <code>순차적</code>으로 실행시킬 수 있다.</p>
<pre><code class="language-js">const tl = gsap.timeline();
tl.to(&quot;.element&quot;, { duration: 1, x: 200 });
tl.to(&quot;.element&quot;, { duration: 1, y: 200 });
tl.to(&quot;.element&quot;, { backgroundColor: &#39;pink&#39; });</code></pre>
<p>이렇게 작성하면 순서대로 <code>.element</code>요소가 x축으로 200px 이동한 후, y축으로 200px 이동을 하고 마지막으로 색상이 pink로 바뀌는 애니메이션이 실행된다.</p>
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="ExzKqbQ" data-pen-title="gsap timeline" data-user="So-An" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/So-An/pen/ExzKqbQ">
  gsap timeline</a> by So-An (<a href="https://codepen.io/So-An">@So-An</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<blockquote>
<h3 id="gsap-기본-속성">GSAP 기본 속성</h3>
</blockquote>
<p>기본적으로 css 속성값은 거의 다 먹는다고 보면된다!
속성 여러개 사용할때 <code>,</code> 꼭 써주고(이거때문에 오류 자주남), <code>px</code> , <code>%</code>같은 단위를 사용하지 않음</p>
<pre><code class="language-js">gsap.to(`element`, {
    x: 100, //x축으로 100px 이동
      xPercent : 100, // x축으로 100% 이동
      y: 100, // y축으로 100px 이동
    yPercent: 100, // y축으로 100% 이동
    rotation: 360, // 360도 회전
      opacity: 1, // 불투명도
      duration: 5, // 5초동안 애니메이션 지속
      ease: none, // 애니메이션 가속도(?)값 링크 첨부해둘테니 참고요망
},5) //5초 딜레이</code></pre>
<p><a href="https://gsap.com/docs/v3/Eases/">ease 속성 더 알아보기</a></p>
<hr>
<h2 id="scrolltrigger-사용법">ScrollTrigger 사용법</h2>
<p>GSAP에서 좀 더 나아가면 ScrollTrigger을 통해 스크롤에 반응해서 애니메이션을 작동시킬 수 있다.</p>
<blockquote>
<h3 id="scrolltrigger-기본-사용법">ScrollTrigger 기본 사용법</h3>
</blockquote>
<pre><code class="language-js">gsap.to(&#39;.element&#39;, {
    scrollTrigger: &#39;.element&#39;, // .element가 뷰포트에 나타났을때 애니메이션 실행 
    x: 500 // x축으로 500px 이동
});</code></pre>
<p>기본적인 사용법은 gsap 사용법과 같지만, scrollTrigger 속성이 추가됐다는게 다르다.
근데 저렇게 사용하면 애니메이션의 시작점과 끝점을 정확하게 잡을순 없다.
그래서 많이 사용하는게 다음과 같은 방법이다</p>
<pre><code class="language-js"> gsap.to(&quot;.element&quot;, {
      scrollTrigger: {
        trigger: &quot;.element&quot;, // 트리거 대상
        start: &quot;top 75%&quot;, // 요소가 뷰포트의 75% 지점에 도달할 때 애니메이션 시작
        end: &quot;top 25%&quot;,   // 요소가 뷰포트의 25% 지점에 도달할 때 애니메이션 종료
        scrub: true,      // 스크롤에 따라 애니메이션의 진행이 조절됨
        markers: true     // 시작 및 종료 지점을 표시하는 마커를 보여줌
      },
      x: 500,
      rotation: 360
    });</code></pre>
<p>이번에는 위에 사용했던것과는 다르게 <code>scrollTrigger</code>안에 속성값이 많이 있다.
대충 설명해보자면 <code>.element</code>가 뷰포트의 75%에 도달했을때 애니메이션이 실행되며, <code>.element</code>가 뷰포트의 25%지점에 도달하면 애니메이션이 종료된다.
<code>scrub</code>을 주어 스크롤이 되는동안 애니메이션이 서서히 진행되는 듯한 효과를 주었다.</p>
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="eYaZqLe" data-pen-title="scrollTrigger" data-user="So-An" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/So-An/pen/eYaZqLe">
  scrollTrigger</a> by So-An (<a href="https://codepen.io/So-An">@So-An</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<blockquote>
<h3 id="start-end-기준">start, end 기준</h3>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/2af4c40a-2a63-4604-98bb-52e1429f8290/image.png" alt="">
scrollTrigger 속성중 <code>markers: true</code> 로 주면 저렇게 스크롤바 옆에 start, end가 써있는걸 볼 수 있다. start와 end는 애니메이션의 시작점과 끝점을 정해준다.
마커를 켜놓고 start와 end를 보면서 정해주면 더 쉽게 애니메이션의 시작과 끝을 조절할 수 있음</p>
<p><code>start: { 트리거대상기준 }, { 스크롤바(뷰포트) 기준 }</code> 으로 작성해주면 된다</p>
<pre><code class="language-js"> gsap.to(&quot;.element&quot;, {
      scrollTrigger: {
        trigger: &quot;.element&quot;, // 트리거 대상
        start: &quot;top 75%&quot;, //트리거대상(.element)의 0%(top)부분과 스크롤바의 75%부분이 만나면 애니메이션이 실행됨
        end: &quot;top 25%&quot;, //트리거대상(.element)의 0%(top)부분과 스크롤바의 25%부분이 만나면 애니메이션이 종료됨
      }
    });</code></pre>
<p>tmi) <code>0%</code> 과 <code>top</code>은 같은 의미이고, <code>100%</code>과 <code>bottom</code>은 같은 의미이다. + <code>50%</code>와 <code>center</code>도 같다. </p>
<blockquote>
<h3 id="scrub-pin-속성">scrub, pin 속성</h3>
</blockquote>
<h4 id="scrub-속성">scrub 속성</h4>
<ul>
<li><code>scrub</code>은 스크롤에 따라 애니메이션의 진행을 조절한다.</li>
<li>true 또는 숫자 값을 사용할 수 있음(숫자가 커질수록 부드럽게 작동)</li>
<li>애니메이션의 재사용이 가능하다( 스크롤 벗어났다가 돌아와도 애니메이션이 작동함)</li>
</ul>
<p>scrub은 위에 예시에 적용되어있으니 생략!</p>
<h4 id="pin-속성">pin 속성</h4>
<ul>
<li><code>pin</code>은 요소를 화면에 고정시키는 속성이다( position: sticky 같은 느낌 )</li>
<li>가로스크롤 같은거 만들때 사용하면 좋다</li>
</ul>
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="gOJMYOP" data-pen-title="scrollTrigger pin" data-user="So-An" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/So-An/pen/gOJMYOP">
  scrollTrigger pin</a> by So-An (<a href="https://codepen.io/So-An">@So-An</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<hr>
<p>일단 이정도로 정리하고 추후에 더 필요한 내용이있으면 조금조금씩 수정해야겠당 :D</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[나 보려고 만든 Swiper 사용법]]></title>
            <link>https://velog.io/@nemo-cat/%EB%82%98-%EB%B3%B4%EB%A0%A4%EA%B3%A0-%EB%A7%8C%EB%93%A0-Swiper-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@nemo-cat/%EB%82%98-%EB%B3%B4%EB%A0%A4%EA%B3%A0-%EB%A7%8C%EB%93%A0-Swiper-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Mon, 20 May 2024 07:41:25 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nemo-cat/post/2cca95f3-0f36-445f-b099-ba2095b2d45c/image.png" alt=""></p>
<p>나 보려고 정리한 Swiper 사용법! 자꾸 한번씩 찾아보게 돼서 아예 정리를 해놔야겠다.</p>
<hr>
<h2 id="swiper란">Swiper란?</h2>
<p>슬라이더 구현을 쉽게 할 수 있는 터치 슬라이더 라이브러리이다. 슬라이더를 직접 만들어서 쓰는것보다 훨씬 편하고 빠르게 만들 수 있다.
<a href="https://swiperjs.com/">swiper 페이지 바로가기</a></p>
<h2 id="swiper-사용법">Swiper 사용법</h2>
<h3 id="swiper-설치하기">Swiper 설치하기</h3>
<p>Swiper 설치 방법에는 크게 2가지가 있는데, 나는 CDN쓸거지롱 + 직접 다운받아서 추가하는 방법도 있다!</p>
<ol>
<li><p>NPM을 통해 설치해주기
<img src="https://velog.velcdn.com/images/nemo-cat/post/f9de4945-44e4-4888-9899-54c2bc809c61/image.png" alt=""></p>
</li>
<li><p>CDN 사용하기
<img src="https://velog.velcdn.com/images/nemo-cat/post/68b80d68-2537-44de-8735-67444756c1de/image.png" alt=""></p>
<pre><code class="language-html">&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css&quot;/&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/swiper@11/swiperbundle.min.js&quot;&gt;&lt;/script&gt;</code></pre>
</li>
</ol>
<h3 id="swiper-기본-사용법">Swiper 기본 사용법</h3>
<h4 id="html">HTML</h4>
<pre><code class="language-html">&lt;!-- Slider main container --&gt;
&lt;div class=&quot;swiper&quot;&gt;
  &lt;!-- Additional required wrapper --&gt;
  &lt;div class=&quot;swiper-wrapper&quot;&gt;
    &lt;!-- Slides --&gt;
    &lt;div class=&quot;swiper-slide&quot;&gt;Slide 1&lt;/div&gt;
    &lt;div class=&quot;swiper-slide&quot;&gt;Slide 2&lt;/div&gt;
    &lt;div class=&quot;swiper-slide&quot;&gt;Slide 3&lt;/div&gt;
    ...
  &lt;/div&gt;
  &lt;!-- pagination 필요시 추가 --&gt;
  &lt;div class=&quot;swiper-pagination&quot;&gt;&lt;/div&gt;

  &lt;!-- navigation buttons 필요시 추가--&gt;
  &lt;div class=&quot;swiper-button-prev&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;swiper-button-next&quot;&gt;&lt;/div&gt;

  &lt;!-- scrollbar 필요시 추가 --&gt;
  &lt;div class=&quot;swiper-scrollbar&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre>
<p><strong>pagination</strong> 추가시
<img src="https://velog.velcdn.com/images/nemo-cat/post/a153860d-ec85-4016-af45-12a7804f2cb7/image.png" alt=""></p>
<p><strong>navigation buttons</strong> 추가시
<img src="https://velog.velcdn.com/images/nemo-cat/post/7d660967-62c5-499b-9558-18ddacd11bcb/image.png" alt=""></p>
<p><strong>scrollbar</strong> 추가시
<img src="https://velog.velcdn.com/images/nemo-cat/post/21f9037f-b05c-46d9-9320-aea88ada4c56/image.png" alt=""></p>
<hr>
<h4 id="swiper-기본-css-변경하기">swiper 기본 css 변경하기</h4>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/5588307d-28fe-47e4-9740-ec0fdce72a34/image.png" alt="">
css변경하고 싶으면 개발자모드를 켜서 어디에 어떻게 스타일이 적용되었는지 확인하고 수정해 주도록 하자!</p>
<hr>
<h4 id="script">script</h4>
<pre><code class="language-js">const swiper = new Swiper(&#39;.swiper&#39;, {
        // Optional parameters
       direction: &#39;horizontal&#39;, // 슬라이드방향 vertical 수직, horizontal 수평 
        loop: true, //반복 여부
        loopFillGroupWithBlank: true, //슬라이드 갯수 채우기(빈칸으로 채워줌)
        slidesPerView: &#39;1&#39;, // 한 슬라이드당 보여줄 갯수
        spaceBetween: 10, // 슬라이드 간격
          slidesPerGroup : 3, // 슬라이드 그룹으로 묶을 갯수
        autoplay: {
            delay: 2500, //시간설정
        },
        // 반응형
        breakPoints: {
          1280: {
            slidesPerView: &#39;3&#39;,
            spaceBetween: 10,
          },
          768: {
            slidesPerView: &#39;2&#39;, 
            spaceBetween: 10,
            },
        },      

        // If we need pagination
        pagination: {
          el: &#39;.swiper-pagination&#39;,
        },

        // Navigation arrows
        navigation: {
          nextEl: &#39;.swiper-button-next&#39;,
          prevEl: &#39;.swiper-button-prev&#39;,
        },

        // And if we need scrollbar
        scrollbar: {
          el: &#39;.swiper-scrollbar&#39;,
        },
    });</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[레이아웃 연습]01.삼성전자]]></title>
            <link>https://velog.io/@nemo-cat/%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EC%97%B0%EC%8A%B501.%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90</link>
            <guid>https://velog.io/@nemo-cat/%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EC%97%B0%EC%8A%B501.%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90</guid>
            <pubDate>Thu, 16 May 2024 08:46:44 GMT</pubDate>
            <description><![CDATA[<p>공부에 끝은 없는법.
레이아웃 잡는 연습좀 하려고한다.
디테일하게는 정리 안하고 부분부분만 따로 정리해보려고 한다.</p>
<h2 id="오늘의-사이트--원본">오늘의 사이트 / 원본</h2>
<p>오늘의 사이트는 바로 <a href="https://www.samsung.com/sec/">삼성전자</a></p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/ede23c17-426e-4efe-babf-4d952411848f/image.png" alt=""></p>
<h2 id="레이아웃-퍼블리싱-완성본">레이아웃 퍼블리싱 완성본</h2>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/f4d370ac-dcd3-4f3b-9677-981169088680/image.png" alt=""></p>
<h2 id="퍼블리싱-과정">퍼블리싱 과정</h2>
<h3 id="section1-특별기획전">section1. 특별기획전</h3>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/2a51400e-d8c4-46f4-9d5d-a2d86aafcff0/image.png" alt=""></p>
<p>원본 사이트 코드를보면 html+css로 레이아웃 잡은게 아니라 이미지로 넣었더라.
나는 일단 레이아웃 연습을 위해 하는거라 이 부분도 html+css로 작성했다.
평소에는 flex를 많이 쓰는데, 이런 배치는 grid가 편하기 때문에 grid를 사용했다.</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/aabfd4e9-7e40-485f-9bbe-cde930d8c9a6/image.png" alt=""></p>
<pre><code class="language-html">&lt;!--html 마크업--&gt;
&lt;section class=&quot;special&quot;&gt;
        &lt;div class=&quot;wrap&quot;&gt;
            &lt;h2 class=&quot;hide&quot;&gt;특별기획전&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;삼성닷컴 특별기획전&lt;/li&gt;
                &lt;li&gt;삼성닷컴 특별기획전&lt;/li&gt;
                &lt;li&gt;삼성닷컴 특별기획전&lt;/li&gt;
                &lt;li&gt;삼성닷컴 특별기획전&lt;/li&gt;
                &lt;li&gt;삼성닷컴 특별기획전&lt;/li&gt;
            &lt;/ul&gt;
            &lt;div class=&quot;item-wrap&quot;&gt;
                &lt;div class=&quot;item-box left&quot;&gt;
                    &lt;div class=&quot;item&quot;&gt;아이템&lt;/div&gt;
                    &lt;div class=&quot;item&quot;&gt;아이템&lt;/div&gt;
                    &lt;div class=&quot;item&quot;&gt;아이템&lt;/div&gt;
                    &lt;div class=&quot;item&quot;&gt;아이템&lt;/div&gt;
                &lt;/div&gt;
                &lt;div class=&quot;item-box right&quot;&gt;
                    &lt;div class=&quot;item&quot;&gt;아이템&lt;/div&gt;
                    &lt;div class=&quot;item&quot;&gt;아이템&lt;/div&gt;
                    &lt;div class=&quot;item&quot;&gt;아이템&lt;/div&gt;
                    &lt;div class=&quot;item&quot;&gt;아이템&lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/section&gt;</code></pre>
<pre><code class="language-css">/* css 코드 */
.item {
    min-height: 100px; /* 최소 높이값 */
}

/* special */
.special ul {
    display: flex;
    justify-content: center;
}

.special ul li {
    padding: 0 5px;
    margin-bottom: 50px;
}

.special .item-wrap {
    display: flex;
    justify-content: space-between;
}

/* ==== 유심히 볼 부분! ==== */
.special .item-box {
    position: relative;
    display: grid;  
    grid-template-columns: 1fr 1fr;
    gap: 10px;  
    width: 48%;
}

.special .item-box.left .item:nth-child(1) {
    grid-row: 1 /  3;
}

.special .item-box.left .item:last-child {
    grid-column: 1 /  3;
}
/* ===================== */
.special .item {
    background-color: #c4c4c4;
}</code></pre>
<p>여기서 유심히 볼 부분은 따로 체크해놨다!
gird를 이용해서 아래 그림(그림판주의)과 같이 배치한다음에 빨간색 영역과 파란색 영역을 합치면된다.
<img src="https://velog.velcdn.com/images/nemo-cat/post/716b0c70-4ce4-4647-89ba-754626b9bee2/image.png" alt=""></p>
<pre><code class="language-css">.special .item-box.left .item:nth-child(1) {
    grid-row: 1 /  3;
}

.special .item-box.left .item:last-child {
    grid-column: 1 /  3;
}</code></pre>
<p>grid설명은 1분코딩님이 잘 정리해놨으니 참고해도 좋을듯하다 <a href="https://studiomeal.com/archives/533">https://studiomeal.com/archives/533</a></p>
<hr>
<h3 id="section2-스토리-영역-li에-counter-넣기">section2. 스토리 영역 li에 counter 넣기</h3>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/8a1962b6-2026-4178-bf9e-9ba7254e276b/image.png" alt=""></p>
<p>원본 사이트에 보면 li앞에 숫자로 넘버링이 되어있는데 물론 span같은걸로 직접 입력해줄수도 있겠지만 나는 css counter함수(?)를 이용해서 작성해보았다.</p>
<p>html마크업은 아래와 같고..</p>
<pre><code class="language-html">&lt;section class=&quot;story&quot;&gt;
        &lt;div class=&quot;wrap&quot;&gt;
            &lt;div class=&quot;left&quot;&gt;
                &lt;h2&gt;스토리&lt;br&gt;#DoWhatYouCant&lt;/h2&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;
                이미지
            &lt;/div&gt;
            &lt;div class=&quot;right&quot;&gt;
                &lt;ul&gt;
                    &lt;li&gt;
                        리스트
                        &lt;a href=&quot;#none&quot;&gt;더 알아보기&lt;/a&gt;
                    &lt;/li&gt;
                    &lt;li&gt;리스트&lt;/li&gt;
                    &lt;li&gt;리스트&lt;/li&gt;
                    &lt;li&gt;리스트&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/section&gt;</code></pre>
<p>css는 counter부분만 가져왔다!</p>
<pre><code class="language-css">.story .right ul {
    width: 100%;
    counter-reset: numbering;
}

.story .right li {
    position: relative;
    padding: 22px 0 22px 45px;
    border-top: 1px solid #c4c4c4;
}

.story .right li::before {
    position: absolute;
    top: 22px;
    left: 20px;
    counter-increment : numbering; 
    content : &#39;0&#39; counter(numbering);
}</code></pre>
<h3 id="css-counter사용법">Css counter사용법</h3>
<p>일단 <code>counter</code>란.. 말그대로 카운팅을 해주는 속성이다. 자동으로 넘버링이 된다! 애초에 순서가 있는 목록을 작성하려면 <code>ol</code>을 쓰면 되지 않을까? 싶기도 한데.. counter을 사용해서 순서를 주는게 좀더 자유롭게 작성할 수 있는것같다.
counter  사용법은 부모요소에 <code>counter-reset</code>을 주어 초기화 시켜주고, 자식요소에 <code>counter-increment</code>을 주어 값을 증가시켜주면 된다.</p>
<pre><code class="language-css">.parenet {
    counter-reset: numbering 0;
    /* counter의 이름 : numbering, 초기값 0*/
}

.child::before {
    counter-increment : numbering;
    /* numbering의 카운터를 1씩 증가,
      counter-increment : numbering -1;으로 쓰면 -1씩 감소,
      counter-increment : numbering 2;면 2씩 증가
    */
    content : counter(numbering); /* counter의 값을 표시*/
}</code></pre>
<p>이런식으로 사용할 수 있고, 나는 01 02 03 이렇게 <code>0 + 카운트 값</code>으로 나타내고 싶어서 counter(numberig)앞에 0을 붙여줬다.</p>
<pre><code class="language-css">.story .right li::before {
    counter-increment : numbering; 
    content : &#39;0&#39; counter(numbering);
}</code></pre>
<hr>
<p>나머지는 특별한게 없어서.. 정리안할거지롱!
레이아웃 잡은김에 그냥 마저 퍼블리싱해야겠다.
그럼 20000</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/bd26ee91-327f-4aa4-a6cc-cdf45671f1a4/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[first-of-type와 first-child의 차이]]></title>
            <link>https://velog.io/@nemo-cat/first-of-type%EC%99%80-first-child%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@nemo-cat/first-of-type%EC%99%80-first-child%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Thu, 16 May 2024 07:46:04 GMT</pubDate>
            <description><![CDATA[<h2 id="서론">서론</h2>
<p>현재 포트폴리오 사이트 작업까지 끝내고.. 이력서 넣으면서 추가적으로 레이아웃 연습이나 좀 하려고 냅다 삼성전자 사이트에 들어가서 레이아웃을 잡고 있었다.
앞에는 다 잡았고 이제 footer만 잡으면 됐는데
<img src="https://velog.velcdn.com/images/nemo-cat/post/798c09e6-f4cb-4951-8e3a-df656afb5883/image.png" alt=""></p>
<p>문제가 발생!</p>
<p>삼성전자 홈페이지에 들어가면 푸터가 요렇게 생겼는데
<img src="https://velog.velcdn.com/images/nemo-cat/post/c49ee3b2-dca7-4ebc-b301-45f08e2c65be/image.png" alt=""></p>
<p>대충 빨간색으로 감싼 영역에 border top bottom주고,
보라색영역엔 전체적으로 border-left를 주고, 첫번째 요소만 border-right를 줘서 표현을 하려고 했다.
<img src="https://velog.velcdn.com/images/nemo-cat/post/dd4ba650-feab-4eca-a4c3-d69a77e64ff0/image.png" alt=""></p>
<h3 id="수정-전-html--css">수정 전 HTML &amp; CSS</h3>
<pre><code class="language-html5">   &lt;div class=&quot;footer-nav&quot;&gt;
        &lt;div class=&quot;inner&quot;&gt;
            &lt;h2 class=&quot;hide&quot;&gt;하단메뉴&lt;/h2&gt;
            &lt;div class=&quot;content-item&quot;&gt;
                &lt;h3&gt;제품&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
           &lt;!-- 생략 --&gt;
            &lt;div class=&quot;content-item&quot;&gt;
                &lt;h3&gt;제품&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                    &lt;li&gt;하단메뉴&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;</code></pre>
<p>대충 html 마크업은 .inner안에 .content-item이 들어있게 해주었고, 숨김제목으로 <code>h2.hide</code>를 하나 만들어주었다(이게 문제가 된거지)</p>
<pre><code class="language-css">.footer-nav{
    border-top: 1px solid #c4c4c4;
    border-bottom: 1px solid #c4c4c4;
}

.footer-nav .inner {
    display: flex;
    width: 90%;
    margin: 0 auto;
}

.footer-nav .content-item {
    flex-grow: 1;
    border-right: 1px solid #c4c4c4;
}

.footer-nav .content-item:nth-child(1) {
    border-left: 1px solid #c4c4c4;
}</code></pre>
<p>css는 위와 같이 간단하게 줬는데 nth-child(1)이 안먹는것이다!! first-child로도 바꿔도 안먹더라..</p>
<h3 id="수정전-결과물">수정전 결과물</h3>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/45c28bec-1c11-4e0f-9502-65e485811264/image.png" alt=""></p>
<p>맨첫번째 요소 왼쪽에도 border가 들어가야하는데.. 왜 안되는건지 몰랐는데
내가 여태껏 nth-child랑 first-child를 쓸때 ul &gt; li 요소에서만 써서 진짜 기초적인걸 간과하고 만것이다..</p>
<h2 id="본론">본론</h2>
<p>본론으로 들어가자면 <code>.footer-nav에 .content-item</code>은 첫번째 요소가 아니다.
<code>h2.hide</code>이친구가 첫번째 요소고, <code>.content-item</code>은 두번째 부터 시작하는것이다.!</p>
<p>여기서 알아야할 css지식!</p>
<h3 id="first-child와-first-of-type의-차이">first-child와 first-of-type의 차이</h3>
<p><code>first-child</code> 는 자식요소중 <code>제일 첫번째</code> 자식을 선택하는 가상선택자이고,
<code>first-of-type</code>은 해당하는 <code>타입의 첫번째</code> 요소를 선택하는 가상선택자이다.</p>
<p>첫번째를 선택한다는것에선 같을 수 있지만 약간은 다르다는점!</p>
<p>위에서 내가 작성한 코드를 예시로 들면, <code>first-child</code>는 <code>h2</code>이고, <code>div</code>중에 첫번째를 잡고 싶은거면 <code>first-of-type</code>을 선택해야 한다!</p>
<h3 id="수정후-css">수정후 css</h3>
<pre><code class="language-css">.footer-nav .content-item:first-of-type {
     /* div 요소(타입)중 첫번째 요소를 선택한다. */
    border-left: 1px solid #c4c4c4;
}</code></pre>
<h2 id="느낀점">느낀점</h2>
<p>평상시에는 ul &gt; li로 만 작성해서 li의 <code>nth-child</code>나 <code>first-child</code>이런식으로 선택했기 때문에 <code>first-of-type</code>을 써본적이 없었기에 생긴 문제였다.
아직도 배워야할게 많다는걸 느끼는 하루였당 :D
지금이라도 알았으니 다행인건가(?)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹 접근성을 고려한 요소 숨기]]></title>
            <link>https://velog.io/@nemo-cat/%EC%9B%B9-%EC%A0%91%EA%B7%BC%EC%84%B1%EC%9D%84-%EA%B3%A0%EB%A0%A4%ED%95%9C-%EC%9A%94%EC%86%8C-%EC%88%A8%EA%B8%B0</link>
            <guid>https://velog.io/@nemo-cat/%EC%9B%B9-%EC%A0%91%EA%B7%BC%EC%84%B1%EC%9D%84-%EA%B3%A0%EB%A0%A4%ED%95%9C-%EC%9A%94%EC%86%8C-%EC%88%A8%EA%B8%B0</guid>
            <pubDate>Thu, 09 May 2024 05:49:15 GMT</pubDate>
            <description><![CDATA[<h2 id="css에서-요소를-안보이게하는-다양한-방법">CSS에서 요소를 안보이게하는 다양한 방법</h2>
<ul>
<li><p><code>display: none</code> : HTML 구조는 남고, 화면에서 영역이 사라진다.</p>
</li>
<li><p><code>visibility: hidden</code> : 화면에서 사라지지만 영역은 가지고있다.</p>
</li>
<li><p><code>opacity: 0</code> : 불투명도를 조절하는거라 영역은 그대로 있다. 애니메이션 적용가능</p>
</li>
<li><p><code>transfrom : scale(0)</code> : 요소의 크기를 축소시켜 안보이게함. 애니메이션 적용가능</p>
<ul>
<li>다른사람들은 영역도 사라진다는데..? 실제로 작성해서 보면 영역은 그대로있다.</li>
</ul>
</li>
<li><p><code>position: absolute</code> : top, left 를 함께 사용해 요소를 다른곳으로 보내버린다. 영역도 사라짐.</p>
</li>
<li><p><code>width: 0; height: 0;</code> : 화면에서 영역이 사라진다. 단, 텍스트는 남을 수 있는데 <code>overflow: hidden</code>을 추가해주면 텍스트도 사라짐</p>
</li>
</ul>
<p>각 속성들이 어떻게 숨겨지는지 궁금하다면 아래 코드펜을 확인해보자!</p>
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="Jjqjdrv" data-user="So-An" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/So-An/pen/Jjqjdrv">
  Untitled</a> by So-An (<a href="https://codepen.io/So-An">@So-An</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<h2 id="그렇다면-모두-웹-접근성을-준수한-방법일까">그렇다면 모두 웹 접근성을 준수한 방법일까?</h2>
<h3 id="웹-접근성-web-accessibility">웹 접근성 (Web Accessibility)</h3>
<p>웹 접근성이란 고령자, 장애인, 비 장애인 등 웹을 이용하려는 사용자 모두에게 동등한 정보를 제공해야 하는것을 말한다. </p>
<p>예시로 네이버 사이트에 접속을 했다고치자. 대부분의 사람들은 아이콘을 봤을때 아 저게 메뉴구나, 페이구나를 알아볼 수 있다. 하지만 시각장애인이 접속했을때 저런 아이콘 하나로 이게 무슨 버튼인지, 무슨아이콘인지 알 수 없다. 웹 접근성을 위해서는 스크린 리더가 읽을 수 있도록 보조로 설명하는 글이 필요하다.</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/5dfff6db-2b4b-4283-b766-a55e602886ac/image.png" alt=""></p>
<p>실제로 개발자 도구를 켜서 네이버 사이트를 보다보면 <code>blind</code> 클래스를 가진 요소들을 찾아볼 수 있다. 이 클래스를 가진 요소들은 화면상에서 보여지진 않지만, 스크린리더가 읽을 수 있는 요소들이다.</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/6e5aead7-7445-4c3b-a397-ed857229e05f/image.png" alt=""></p>
<h3 id="웹-접근성을-위한-요소-숨기기">웹 접근성을 위한 요소 숨기기</h3>
<p>앞서 다양한 CSS 속성을 사용해서 요소 숨기는법을 알려줬다. 하지만 대표적으로 <code>display: none</code>같은 경우는 스크린리더기에서 읽히지 않는다.
웹 접근성을 위해서는 화면에서만 보이지 않으면서 스크린 리더가 읽을수 있게 작성을 해줘야한다.</p>
<pre><code class="language-css">.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap; /* 줄바꿈 금지 */
}

.hide {
    display: block;
    position: absolute;
    border: 0;
    width: 1px;
    height: 1px;
    clip: rect(1px, 1px, 1px, 1px);
    overflow: hidden;
}

.blind {
    position: absolute;
    clip: rect(0, 0, 0, 0);
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
}
</code></pre>
<p>작성자마다 사용하는 속성이 약간씩 다르지만 핵심은 이거인듯하다</p>
<ul>
<li><code>position: absolute</code>를 이용해 본문의 흐름에서 떼어놓고</li>
<li><code>width: 1px</code> <code>hight: 1px</code>을 주어 최소 크기로 만들고</li>
<li><code>margin: -1px</code> 요소에 역마진을 부여함으로써 요소가 차지하는 공간을 제거한다.</li>
<li><code>clip: rect(0, 0, 0, 0)</code> : 요소를 클리핑하여 표시되지않게 한다</li>
<li><code>overflow: hidden</code> 속성으로 요소를 넘치지 않게 만들어준다.</li>
</ul>
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="VwOwvYo" data-user="So-An" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/So-An/pen/VwOwvYo">
  CSS 요소 숨기기2</a> by So-An (<a href="https://codepen.io/So-An">@So-An</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>]]></description>
        </item>
        <item>
            <title><![CDATA[인터넷과 웹의 역사 알아보기]]></title>
            <link>https://velog.io/@nemo-cat/%EC%9D%B8%ED%84%B0%EB%84%B7%EA%B3%BC-%EC%9B%B9%EC%9D%98-%EC%97%AD%EC%82%AC</link>
            <guid>https://velog.io/@nemo-cat/%EC%9D%B8%ED%84%B0%EB%84%B7%EA%B3%BC-%EC%9B%B9%EC%9D%98-%EC%97%AD%EC%82%AC</guid>
            <pubDate>Thu, 09 May 2024 04:27:17 GMT</pubDate>
            <description><![CDATA[<h1 id="인터넷internet">인터넷(Internet)</h1>
<h2 id="인터넷의-시작-arpanet">인터넷의 시작, ARPANET</h2>
<p>최초의 인터넷은 군사적인 목적으로 만들어졌다.
소련이 인류 최초의 인공위성을 발사한 후, 미국은 위협을 느끼고 핵 전쟁 등의 상황에 대비하기 위해 전체 통신 시스템에서 데이터를 안전하게 보관하고 전송할 수 있는 시스템을 개발하기 시작했습니다. 그것이 바로 ARPANET이었다.</p>
<p>ARPANET은 인터넷의 초기 형태로, 1969년에 미국 국방부의 주도 아래 개발되었습니다. 통신망 일부가 파괴되어도 네트워크가 계속해서 작동할 수 있는 분산형 아키텍처를 갖추고자 했던 것이 이 네트워크의 주요 목표 중 하나였다. 이렇게 ARPANET은 군사적인 필요성에서 출발하였으나, 이후에는 인터넷의 발전과 함께 학계와 산업에 큰 영향을 미치게 되었다.</p>
<h2 id="tcpip-프로토콜의-개발">TCP/IP 프로토콜의 개발</h2>
<p>TCP/IP 프로토콜은 현재 인터넷에서 가장 널리 사용되는 통신 프로토콜 중 하나다.
이는 데이터의 안정적인 전송을 보장하기 위해 개발된 프로토콜로, ARPANET을 위성 및 무선 네트워크와 연결할 수 있는 네트워킹 프로토콜을 발전시키는 과정에서 ‘TCP/IP’ 통신 프로토콜이 개발되었다.</p>
<ol>
<li>TCP(Transmission Control Protocol)</li>
</ol>
<ul>
<li>데이터를 안정적으로 전송하기 위한 프로토콜이다</li>
<li>데이터의 신뢰성과 흐름제어를 담당한다</li>
<li>데이터를 여러개의 패킷으로 분할하여 전송하고, 수신자가 다시 재조립하여 원본 데이터를 복원한다</li>
<li>데이터가 손실되지 않고 순서대로 도착할 수 있도록 보장한다</li>
</ul>
<ol start="2">
<li>IP(Internet Protocol)</li>
</ol>
<ul>
<li>컴퓨터간에 데이터를 주고 받기 위한 주소체계와 라우팅을 담당하는 프로토콜이다</li>
<li>각 컴퓨터와 네트워크 장치에는 IP주소가 할당되어 있으며, IP주소를 통해 데이터가 목적지까지 안전하게 전송된다</li>
<li>IP는 패킷의 출발지와 목적지를 정하고 최적의 경로를 선택하여 데이터를 전송한다.<blockquote>
<p>라우팅 : 네트워크상의 여러 경로중 최적의 경로로 데이터를 보내주는것</p>
</blockquote>
</li>
</ul>
<h1 id="웹web">웹(Web)</h1>
<h2 id="www의-등장">WWW의 등장</h2>
<p>1989년, 팀 버너스리가 인터넷 공간 안에서 문서가 서로 이동할수 있는 개념인 &#39;하이퍼링크&#39;를 제안하게 되고, 이 아이디어를 바탕으로 현재 오늘날 널리 쓰이는 World Wide Web이 나타나게 됩니다.
<a href="https://info.cern.ch/">최초의 웹사이트 보러가기</a></p>
<ol>
<li>WWW 주요 구성요소</li>
</ol>
<ul>
<li>HTTP : 웹 서버와 클라이언트 간에 데이터를 전송하는데 사용되는 프로토콜 </li>
<li>URL : 하이퍼링크가 가르키는 주소</li>
<li>HTML : 웹 페이지 작성을 위한 마크업언어</li>
<li>웹브라우저 :  페이지를 표시하고 사용자가 웹을 탐색할 수 있도록 해주는 응용 프로그램</li>
</ul>
<p>당시 W3C는 HTML 표준을 제정하지만 표준을 강제하지는 않았다.</p>
<h2 id="1차-웹-브라우저-전쟁">1차 웹 브라우저 전쟁</h2>
<p><img src="blob:https://velog.io/851e034d-a0b5-4432-86ac-4b983d2e5be5" alt="업로드중.."></p>
<ul>
<li>최초의 GUI( Graphical User Interface)를 갖춘 <code>모자이크</code>가 등장하게 됐다.</li>
<li>추후 모자이크는 <code>넷스케이프</code>로 이름을바꾸고 1994년 정식 배포를 시작했다</li>
<li>이 시기에 마이크로소프트에서 <code>인터넷 익스플로러</code>를 발표했다.</li>
<li><code>넷스케이프</code>와 <code>인터넷 익스플로러</code>는 둘 다 초기에는 W3C의 표준을 완전히 준수하지 않고 자체적으로 다양한 기능을 추가하여 경쟁을 벌였다.</li>
<li>하지만 이미 대부분의 사람들은 <code>넷스케이프</code>를 사용하고 있었기에 마이크로소프트는 <code>인터넷 익스플로러</code>를 윈도우 운영체제에 강제로 설치하게 된다.</li>
<li>뿐만아니라 애플과 계약을 통해 5년간 매킨토시의 기본 브라우저를 <code>인터넷 익스플로러</code>로 설정하게 된다.(당시 모든 컴퓨터의 브라우저를 <code>인터넷 익스플로러</code>로 설정해놓은것이다.)</li>
<li>이러한 행동으로 인해 <code>인터넷 익스플로러</code>의 점유율이 높아지고, <code>넷스케이프</code>의 점유율이 하락하는 추세를 보이게된다.</li>
</ul>
<h2 id="플러그인의-등장">플러그인의 등장</h2>
<ul>
<li>웹 브라우저 전쟁동안 웹은 엄청난 속도로 발전하기 시작했다</li>
<li>빠른 성장세에 정작 웹 표준을 지정하는 W3C는 대응을 하지 못했고, 이에 불만을 느낀 기업들이 <code>플러그인</code>을 제작하기 시작했다.</li>
<li>이때 <code>어도비 플래시(Adobe Flash)</code>와 <code>액티브 엑스(ActiveX)</code> 등 여러 플러그인이 제작되었고 웹을 점점 풍부한 공간으로 만들어주게 되었다.</li>
</ul>
<h2 id="웹-20">웹 2.0</h2>
<ul>
<li>플래시와 같은 플러그인의 발전으로 웹 어플리케이션 개발이 쉬워졌다.</li>
<li>기술의 발전으로 웹에서도 다양한 기능들을 구현할 수 있게 되었고, 이는 웹을 더욱 인터랙티브하고 다양한 경험을 제공할 수 있는 공간으로 만들어주었다.</li>
<li>이 시대에는 블로그, 소셜 미디어, 위키 등의 플랫폼이 대중화되면서 사용자들이 쉽게 콘텐츠를 발행할 수 있게 되었다.</li>
</ul>
<blockquote>
<h5 id="웹-10-읽기">웹 1.0 (읽기)</h5>
</blockquote>
<ul>
<li>1990년대부터 ~ 2004대까지의 구간</li>
<li>이 시기에는 정적인 컨텐츠를 제공하는 웹사이트가 주를 이루었습니다.</li>
<li>사용자들은 주로 정보를 소비하는 역할에 그쳤으며, 대부분의 웹사이트는 단방향 통신이었습니다.<h5 id="웹-20-읽기-쓰기">웹 2.0 (읽기, 쓰기)</h5>
</li>
<li>2004 전후로 페이스북과 유튜브같은 플랫폼들이 등장하기 시작했다.</li>
<li>읽기와 쓰기가 동시에 가능하는 양방향 소통이 가능하게 되었다.(참여와 공유가 가능한 형태)<h5 id="웹-30-읽기-쓰기-소유">웹 3.0 (읽기, 쓰기, 소유)</h5>
</li>
<li>인공지능과 블록체인을 기반으로 맞춤형 정보를 제공하고 데이터 소유를 개인화하는 3세대 인터넷</li>
<li>블록체인 기술을 사용하여 탈중앙화된 데이터 관리와 보안을 실현함으로써, 사용자들의 개인 정보와 데이터를 더욱 안전하게 보호하고 소유권을 강화</li>
<li><ul>
<li>탈 중앙화 : 중앙 집권을 벗어나 네트워크 참여자가 동등하게 권한을 가지고 자원을 관리함</li>
</ul>
</li>
</ul>
<h2 id="whatwg의-등장">WHATWG의 등장</h2>
<ul>
<li>인터넷 익스플로러의 점유율 상승으로 인해 대부분의 웹 사이트에 액티브 엑스가 사용되면서 웹의 무게가 증가하기 시작함.</li>
<li>이를막고자 2004년, 모질라 재단과 오페라 소프트웨어가 W3C에 새로운 HTML 표준 제안서를 제출했지만 거부당했다.</li>
<li>이에 따라 인터넷 익스플로러를 제외한 웹 브라우저 기업들은 <code>WHATWG</code>를 설립하여 새로운 웹 표준을 제안했습니다.(<code>Web Application 1.0</code>)</li>
<li>비슷한 시기에 W3C도 XHTML 2.0 표준을작성하지만, 기존의 표준과 너무 동떨어져있는 바람에 개발자들은 XHTML 2.0을 사용하지 않게 되었다.</li>
<li>결국 W3C는 <code>Web Application 1.0</code>을 <code>HTML5</code>표준으로 변경하고 <code>WHATWG</code>와 함께 <code>HTML5</code> 표준을 작성하게 되었다.</li>
</ul>
<h2 id="2차-웹-브라우저-전쟁">2차 웹 브라우저 전쟁</h2>
<ul>
<li>마이크로소프트와 W3C가 함께한 XHTML 2.0 표준이 붕괴되고 인터넷 익스플로러의 기능 문제가 대두되었다.</li>
<li>다른 웹 브라우저들은 모두 최신 표준을 준수하는 반면, <code>익스플로러만 표준을 지원하지 못하는</code> 상황이 발생하게 된것이다.</li>
<li>이러한 기회를 놓치지 않기 위해 모든 웹 브라우저들이 빠른 속도로 업데이트를 시작했고, 자체 마케팅을 다양한 방법으로 진행하였다.</li>
<li>일부 경우에는 특정 브라우저를 사용하지 않으면 서비스에 접근할 수 없도록 만들어서 사용을 강제하기도 했다.</li>
<li>결론적으로 제 2차 웹 브라우저 전쟁은 거의 구글의 크롬의 승리로 볼 수 있다.</li>
</ul>
<h2 id="마이크로소프트-인터넷-익스플로러-지원-중단">마이크로소프트, 인터넷 익스플로러 지원 중단</h2>
<ul>
<li>새로운 것이 등장한다고 해서 모든 사용자가 새로운 것을 쓰는 것은 아니다.</li>
<li>컴퓨터에 관심이 있는 사람들은 인터넷 익스플로러가 보안 측면에서 위험하고 성능도 좋지 않다는 것을 알고 최신 웹 브라우저를 설치하여 사용했지만, 대부분의 사람들은 컴퓨터에 기본으로 설치된 웹 브라우저를 계속 사용했다.</li>
<li>그러나 2016년 마이크로소프트는 인터넷 익스플로러 10 이하의 버전을 더 이상 지원하지 않기로 결정하고, 자동 업데이트를 통해 인터넷 익스플로러 11로 강제로 업데이트 했다.( 최종적으로 2022년 6월 15일 인터넷 익스플로러에 대한 지원이 종료되었고, 현재는 Edge가 되었다.)</li>
<li>이로 인해 HTML5를 본격적으로 사용할 수 있는 환경이 조성되었다.</li>
</ul>
<hr>
<h4 id="주인장의-생각-끄적이기">주인장의 생각 끄적이기</h4>
<p>생각보다 웹의 역사는 짧은것같다. 역사가 짧은것에 비해 단기간에 엄청나게 발전을 한게 참 신기하다. 대충 본인은 웹 2.0시대에 태어난 사람인데, 생각해 보면 어렸을때 플래시 게임같은걸 많이 했었다. 그리고 은행사이트 하나를 접속하더라도 액티브 엑스를 깔라고하고.. 이게 정말 킹받았던것 같다.
어느순간부터 자연스럽게 익스플로러를 쓰지 않게되고 크롬을 쓰고있었는데 지금 와서 돌이켜보니 그때가 제 2차 브라우저 전쟁의 시기였던것같다. 이제는 익스플로러는 고사하고 엣지도 쳐다도안본다.. 크롬에 너무 익숙해져버렸다. -끝-
아, 전체적인 내용은 <code>모던웹을 위한 HTML5+CSS3 바이블 3판</code>을 참고하였습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[검색엔진 최적화하기(SEO, OG, SearchAdvisor, Robots)]]></title>
            <link>https://velog.io/@nemo-cat/%EA%B2%80%EC%83%89%EC%97%94%EC%A7%84%EC%B5%9C%EC%A0%81%ED%99%94</link>
            <guid>https://velog.io/@nemo-cat/%EA%B2%80%EC%83%89%EC%97%94%EC%A7%84%EC%B5%9C%EC%A0%81%ED%99%94</guid>
            <pubDate>Wed, 08 May 2024 09:39:45 GMT</pubDate>
            <description><![CDATA[<h2 id="seo에-대해-알아보자">SEO에 대해 알아보자!</h2>
<blockquote>
<h3 id="seosearch-engine-optimization란">SEO(Search Engine Optimization)란?</h3>
</blockquote>
<p>SEO는 검색 엔진 최적화를 말하는것으로, 구글이나 네이버 같은 검색 엔진이 웹사이트를 이해하고 인덱싱하여 사용자가 검색할 때 해당 사이트를 노출시키도록 도와주는 프로세스를 말한다. 이를 통해 사용자가 웹사이트를 찾고 방문할 수 있도록 도와줍니다.
(대충 검색엔진이 내 사이트를 잘 찾을 수 있도록 하는것이다!)</p>
<blockquote>
<h3 id="google-크롤러-작동단계">Google 크롤러 작동단계</h3>
</blockquote>
<p>대표적으로 구글의 크롤러 작동 단계는 다음과같다. 근데 다른 검색엔진들도 비슷하게 작동한다.</p>
<ul>
<li>1단계 크롤링 : 크롤러가 인터넷에서 발견한 페이지의 내용을 모두 다운로드한다</li>
<li>2단계 색인 생성 : 크롤러가 수집한 데이터를 분석하여 관련된 내용으로 인덱싱을 한다.</li>
<li>3단계 검색결과 게재 : 사용자가 google검색을 하면 검색어와 관련된 정보를 반환한다.
<a href="https://developers.google.com/search/docs/fundamentals/how-search-works?hl=ko">자세히 알아보기</a></li>
</ul>
<blockquote>
<h3 id="검색엔진-최적화를-위한-방법">검색엔진 최적화를 위한 방법</h3>
</blockquote>
<ol>
<li><code>&lt;meta&gt;</code>태그 활용하기<pre><code class="language-html">&lt;!--  검색 엔진을 위한 키워드 --&gt;
&lt;meta name=&quot;keyword&quot; content=&quot;고양이, 네모, 네모빔&quot;&gt;
</code></pre>
</li>
</ol>
<!--  웹 페이지에 대한 설명 -->
<meta name="description" content="당신은 네모네모 빔에 맞았습니다">

<!--  문서의 저자 -->
<meta name="author" content="NemoCat">

<pre><code>2. 문법에 맞는 HTML 작성 - 시맨틱 마크업
3. `&lt;img&gt;`에 `alt`속성 기재하기
4. 모바일 친화적인 사이트 구축 - 모바일 사용자의 경험 개선
5. 사이트 속도 최적화
3. https 사용 권장 - 동일한 사이트라면 http보다 https가 가산점이 있음

이외에도 SEO를 위한 방법은 다양하게 있다.

---
## 그 외 검색 최적화 방법
&gt;### 링크 미리보기, OG(Open Graph)

카카오톡으로 링크를 공유하면 썸네일 이미지와 함께, 게시물의 제목, 내용등이 간략하게 나온다.
Oepn Graph 프로토콜을 사용하면 원하는 제목과 설명, 이미지등을 지정할 수 있다.
![](https://velog.velcdn.com/images/nemo-cat/post/d74cd1a0-4b02-4f5c-8f10-788a6a2cf6d2/image.png)

```html
&lt;!-- 기본 사용법 --&gt;
&lt;meta property=&quot;속성 이름&quot; content=&quot;속성 값&quot;&gt;</code></pre><p>Oepn Graph의 기본 속성은 <code>og:title</code> <code>og:url</code> <code>og:imgae</code> <code>og:type</code>이 있다.</p>
<pre><code>&lt;!-- 사용 예시 --&gt;
&lt;head&gt;
    &lt;meta property=&quot;og:url&quot; content=&quot;이동할 url&quot;&gt;
      &lt;meta property=&quot;og:title&quot; content=&quot;제목&quot;&gt;
      &lt;meta property=&quot;og:type&quot; content=&quot;website&quot;&gt;
      &lt;meta property=&quot;og:image&quot; content=&quot;썸네일 경로&quot;&gt;
      &lt;meta property=&quot;og:description&quot; content=&quot;설명&quot;&gt;
&lt;/heade&gt;</code></pre><blockquote>
<h3 id="네이버-searchadvisor">네이버 SearchAdvisor</h3>
</blockquote>
<p>국내 사람들은 구글도 많이 이용하지만 국내 포털인 네이버, 다음 등도 많이 사용한다. 네이버에도 네이버만의 검색엔진최적화를 위한 SearchAdvisor가 있다.
노출시키고 싶은 홈페이지를 SearchAdvisor에 등록하여 사용하면 된다.
<a href="https://searchadvisor.naver.com/">&gt; 네이버 검색기초 보러가기</a></p>
<blockquote>
<h3 id="robotstxt">robots.txt</h3>
</blockquote>
<p>robots.txt는 본인의 웹사이트에 크롤러 같은 로봇들의 접근을 제어하는 파일이다.
웹사이트의 어떤 부분을 크롤링하거나 색인화(인덱싱)해야하는지에 대해 작성이 가능하며 특정 로봇의 방문을 막을 수 있다.</p>
<h4 id="대표적인-로봇">대표적인 로봇</h4>
<pre><code>- Google : Googlebot
- Google image : Googlebot-image
- Naver : Yeti
- Bing : BingBot
- Daum: Daumoa</code></pre><h4 id="기본-형식">기본 형식</h4>
<pre><code>User-agent: [로봇 이름 or &#39;*&#39;(모든 로봇)]
Disallow: [크롤링을 허용하지 않을 디렉토리 또는 페이지 경로]
Allow: [특정 로봇에 대해 허용하는 디렉토리 또는 페이지 경로]</code></pre><h4 id="모든-로봇에게-모든-페이지-접근-허가">모든 로봇에게 모든 페이지 접근 허가</h4>
<pre><code>User-agent: *
Allow: /</code></pre><h4 id="모든-로봇의-접근-거부">모든 로봇의 접근 거부</h4>
<pre><code>User-agent: *
Disallow: /</code></pre><h4 id="특정-로봇에게-특정-디렉토리의-접근-거부">특정 로봇에게 특정 디렉토리의 접근 거부</h4>
<pre><code>User-agent: Googlebot
Disallow: /private/</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Uncaught TypeError: Cannot read properties of null(reading: 'push')]]></title>
            <link>https://velog.io/@nemo-cat/Uncaught-TypeError-Cannot-read-properties-of-nullreading-push</link>
            <guid>https://velog.io/@nemo-cat/Uncaught-TypeError-Cannot-read-properties-of-nullreading-push</guid>
            <pubDate>Fri, 03 May 2024 06:15:46 GMT</pubDate>
            <description><![CDATA[<p>예전에 만들었던 Todo List를 로컬스토리지로 변경하고 싶어서 변경하던 중 초반부터 난관에 봉착해벌임..
할일입력하는 칸에 입력하고 추가 버튼을 누르는순간 나타나는 귀여운 에러!!
대충 새로운 todo를 만들어서 todoList에 추가를 하다가 에러가난것같다.
<img src="https://velog.velcdn.com/images/nemo-cat/post/156e5135-fea6-4a50-8d04-03ceee47a05e/image.png" alt="">
에러난 부분의 코드는 아래와 같다.</p>
<h4 id="기존코드1">기존코드1</h4>
<pre><code class="language-javascript">let todoList = [];
let key = 0;

function addTodo()
{
    let text = $(&quot;#todo&quot;).val(); //input에 입력된 값 저장
    let currentDate = new Date(); //현재 날짜 생성

    //새로운 투두 생성
    let newTodo = {
        index: key,
        text: text,
        checked: false,
        date: writeDate
    }

    todoList.push(newTodo);
    key++;
}
</code></pre>
<p>그래서 뭐가 문제인가하고 슬쩍봤는데..
음..? 도대체 어디서 에러가 난건지 감이 안잡힌다 ㅠㅠ
중간중간에 console.log를 찍어보았는데, 어느순간 todoList가 null로 바뀌어있더라..?</p>
<p>그래서 이 부분이 문제가 아닌듯하여 다른 코드를 살펴보기 시작했다.</p>
<h4 id="기존코드2">기존코드2</h4>
<pre><code class="language-js">// 이전에 작성한 투두리스트를 불러오는 함수
function loadTodoList()
{
    let checking = window.localStorage.getItem(&quot;todoList&quot;); //로컬스토리지의 todoList를 가져옴
    let changeData = JSON.parse(checking); //가져온 todoList를 object형태로 변경;
    todoList = changeData; //todoList를 changeData로 변경 &lt;-얘가 문제

    //로컬스토리지에 데이터 있으면 추가
    if(checking)
    {
        //html에 todoList추가
        for(let i = 0; i &lt; todoList.length; i++)
        {
            $(&quot;#todoList&quot;).append(appendTodoList(todoList[i].index, todoList[i].text, todoList[i].checked));
        }
    }
}</code></pre>
<p>투두 리스트 페이지가 열리면 loadTodoList()가 실행되게 해놨는데,
초기에는 로컬스토리지에 데이터가 없으니 todoList에 null값이 저장되는것이였다.
단순 실수!</p>
<h4 id="수정코드">수정코드</h4>
<pre><code class="language-js">function loadTodoList()
{
    let checking = window.localStorage.getItem(&quot;todoList&quot;); //로컬스토리지의 todoList를 가져옴
    let changeData = JSON.parse(checking); //가져온 todoList를 object형태로 변경;

    //로컬스토리지에 데이터 있으면 추가
    if(checking)
    {
        todoList = changeData; //todoList를 changeData로 변경
        //html에 todoList추가
        for(let i = 0; i &lt; todoList.length; i++)
        {
            $(&quot;#todoList&quot;).append(appendTodoList(todoList[i].index, todoList[i].text, todoList[i].checked));
        }
    }
}</code></pre>
<p>요렇게 todoList = changeData위치를 if(checking)안으로 바꿔줬더니 오류가 해결됐다.</p>
<p>사실 이렇게 수정하고나니 별거아닌것같은데..
오류가 나고 수정까지의 시간은 고통의 시간이었다 ㅠ</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/65acf0a0-d52b-4671-93d6-e207b4e647cc/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Todo List를 만들어보았다(근데이제 문제를 곁들인)]]></title>
            <link>https://velog.io/@nemo-cat/todolist</link>
            <guid>https://velog.io/@nemo-cat/todolist</guid>
            <pubDate>Tue, 16 Jan 2024 06:22:32 GMT</pubDate>
            <description><![CDATA[<h2 id="서론">서론</h2>
<p>어쩌다가 지나가던 백엔드 개발자한테 붙들려서 서버와 통신하는 법을 배우게 되었다.
http, udp, tcp등에 대해서 알려주더니 냅다 ajax와 json란걸 보여주더니 냅다 todo-list를 만들어보란다(예?)
약간 abcd 알려줘놓고 토익시험을 치라는것같은 느낌이었다.</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/a08309c1-5a7b-4df0-a32b-47cfcb5b7cd5/image.png" alt=""></p>
<p>그래도 하라하면 또 하는 성격인지라.. 군말없이 일단 하기는 했다.
하다보니 아래와 같은 todo-list를 만들게 되었다.(완성작이다.)
<img src="https://velog.velcdn.com/images/nemo-cat/post/37553f7c-0cd9-4599-adc9-5ce5697a2637/image.png" alt=""></p>
<p>자 사실 퍼블리싱 자체는 문제가 되지 않는다. 어떻게든 하니까..
근데 이제 평소에 퍼블리싱 공부를 할때에는 저런 할일 리스트 목록이면 html에 ul &gt; li로 직접 쳐서 바로 브라우저에 보여질 수 있게만 했다.</p>
<p>근데 이제는 input[type=&#39;text&#39;]에 내용 입력하면 -&gt; 내용을 데이터 형식에 맞게끔 담아 서버에 보낸다 -&gt; 서버에서 다시 데이터를 보내준다 -&gt; 서버에서 받은 데이터로 li 요소를 생성한다.
이런식으로 서버와 통신을 하며 데이터를 보내고, 화면에 뿌리는(?) 걸 해보게 되었다.</p>
<p>자, 다 좋은데 문제가 발생했다!!
<img src="https://velog.velcdn.com/images/nemo-cat/post/018af86f-2643-4e25-874d-9f8ccb8e985d/image.png" alt=""></p>
<h2 id="문제">문제</h2>
<p>todo list의 핵심 기능은 완료한 항목은 체크표가 되어야한다는 것이다.
처음에는 디자인을 딱히 정하지 않고 냅다 html로만 만들어놨어서, 냅다 input[type=&#39;checkbox&#39;]를 클릭하면 체크된 상태를 서버로 보내게 만들었는데,
막상 디자인을 하고 나니까 input[type=&#39;checkbox&#39;]를 누를 수 없는 상태가 되었다! (체크박스는 css로 디자인이 안된다.)</p>
<blockquote>
<p>맨 처음 코드(label 사용 x)
체크박스를 직접 클릭하여 함수를 실행시켰기 때문에 문제가 안됐었음</p>
</blockquote>
<pre><code class="language-html">&lt;ul&gt;
    &lt;li&gt;
        &lt;input id=&quot;checkList##&quot; type=&quot;checkbox&quot; onclick(todoChekced(this, index))&gt;
        일어나서 밥먹기
        &lt;button&gt;삭제&lt;/button&gt;                                      
      &lt;/li&gt;
&lt;/ul&gt;

&lt;script&gt;
  function todoChecked(e, index) {
      /* 체크 박스가 checked 되어있는지 확인 */
      let checkbox = e.checked;
      /* 서버로 보낼 체크박스 상태 0이면 체크안됨, 1이면 체크됨으로 정했음 */
      let checkedStatus = &quot;&quot;;
      /* 체크박스 상태와 함께 할일 리스트 인덱스번호도 같이 보냄 */
      let deleteIdx = inedx;

      if (checkbox == false) {
          checkedStatus = 0;
      } else {
          checkedStatus = 1;
      }

      $.ajax({
          생략..
      });
 &lt;/script&gt;
</code></pre>
<p>그래도 이때까진 큰 문제라 생각하지 않아서 label요소를 추가해서 label과 checkbox를 연결하게된다. 그래서 결국 label을 누르면 checkbox가 checked가 되니까? 서버에는 똑같이 체크여부가 넘어갈것이라 생각하게 된다.</p>
<p>이렇게 아름답게 끝나면 얼마나 좋을까..</p>
<ul>
<li>내가 생각한것 : label을 누른다 -&gt; checkbox가 checked상태가 된다 -&gt; 서버에 checkbox 상태를 보낸다.</li>
<li>실제로 동작된것 : label을 누른다 -&gt; 서버에 checkbox 상태를 보낸다 -&gt; checkbox가 checked상태가 된다.</li>
</ul>
<p>처음에는 실제 작동된 순서를 알아채는데도 오래걸렸다.
자꾸 마음처럼 안되서 함수안에서 alert으로 찍어보니까 그제서야 서버에 check되기 전 상태가 먼저 간다는걸 깨닫게 된것이다.</p>
<h2 id="수정1">수정1</h2>
<p>자, 이제 동작의 순서가 잘못된걸 깨닫게 되었으니 수정을 해야한다.
하지만 아무리 생각해도 좋은 방법이 떠오르지 않았다.
그러다가 문득 생각난게 바로 setTimeout이다. 
setTimeout을 이용해서 함수 실행을 늦춘다면, checkbox가 checked로 바뀌는 시간을 벌 수 있을것 같다는 생각이 들었다.</p>
<blockquote>
<p>수정1) setTimeout을 이용하여 인위적으로 함수를 늦게 실행시킴</p>
</blockquote>
<pre><code class="language-html">&lt;ul&gt;
    &lt;li&gt;
        &lt;input id=&quot;checkList##&quot; type=&quot;checkbox&quot;&gt;
        &lt;label for=&quot;checkList##&quot; onclick(todoChekced(this, index))&gt;일어나서 밥먹기&lt;/label&gt;
        &lt;button&gt;삭제&lt;/button&gt;                                      
      &lt;/li&gt;
&lt;/ul&gt;


&lt;script&gt;
  function todoChecked(e, index) {
        setTimeout(function () {
          /* this가 label이 되었기때문에 label의 앞 형제(checkbox)의 체크여부 확인 */
          let checkbox = e.previousSibling.checked;

          let checkedStatus = &quot;&quot;;
          let deleteIdx = inedx;

          if (checkbox == false) {
              checkedStatus = 0;
          } else {
              checkedStatus = 1;
          }

          $.ajax({
              생략..
          });
      }, 500);
 &lt;/script&gt;</code></pre>
<p>그리하여 수정된 코드가 이것이다.
일단 원하는대로 작동은 되니까 기분은 좋았다.
수정을 해놓고 서버를 만들어준 개발자에게 문제가 생겼고, 이렇게 해결했다라고 자진신고를 했다.
내 얘기를 듣더니 delay를 주는건 그닥 좋은 방법은 아니라고 하더라.
그러면서 다른 방법을 살짝 귀띔해주었다.</p>
<h2 id="수정2">수정2</h2>
<blockquote>
<p>수정2) checkbox의 index를 통해서 n번째 checkbox의 상태를 반대로 바꿔주기</p>
</blockquote>
<pre><code class="language-html">&lt;ul&gt;
    &lt;li&gt;
        &lt;input id=&quot;checkList##&quot; type=&quot;checkbox&quot;&gt;
        &lt;label onclick(todoChekced(index))&gt;일어나서 밥먹기&lt;/label&gt;
        &lt;button&gt;삭제&lt;/button&gt;                                      
      &lt;/li&gt;
&lt;/ul&gt;


&lt;script&gt;
  function todoChecked(index) {
        /* 체크표시하고 싶은 체크리스트를 변수에 저장 */
      let chkIdx = $(&#39;#checkList&#39;+index);

        /* 체크리스트의 checked 상태를 반대로 설정 */
        chkIdx.prop(&#39;checked&#39;,!chkIdx.is(&#39;:checked&#39;);

      /* 현재 checked상태 확인해서 서버에 보내주기 */
      let checkbox = chkIdx.is(&#39;:checked&#39;);
      let checkedStatus = &quot;&quot;;      let deleteIdx = index;

      if (checkbox == false) {
          checkedStatus = 0;
      } else {
        checkedStatus = 1;
      }

      $.ajax({
          생략..
});
 &lt;/script&gt;</code></pre>
<p>두번째로 수정한것은 checkbox의 상태를 반대로 저장해버리는 것이다.</p>
<p>체크박스는 1. 체크 됨 2. 체크안됨 둘중하나니까.. 현 상태의 반대로 저장하면 원하는 대로 되는것이더라. 간단한건데 왜 이런 생각은 못했을까?</p>
<p>그래서 label을 누르면 NOT 연산자(!)를 통해서 체크상태를 반대로 바꿀 수 있게 해주었다.
그러면서 원래는 매개변수값으로 e, index 두개를 받았는데 굳이 e는 필요없을것 같아 삭제해주었고 index만으로 원하는 할일리스트 index의 상태를 바꿀 수 있게 했다.</p>
<p>그런데 사실 저 코드에서 더 정리가 될 것같기도 한데 현 상황에선 잘 모르겠다.
나중에 조금더 레벨업을 한 다음에 다시 수정을 해봐야겠다.</p>
<h2 id="마치며">마치며</h2>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/72694474-6ad0-4281-b088-5a6a50b1c2f8/image.png" alt=""></p>
<p>어쨌든 checked 상태때문에 생각보다 시간이 오래걸렸다.
이게 해결하고 나서 보니까 진짜 별거 아닌것같은데 괜히 혼자 시간버려가며 삽질했나 싶었는데
개발자 친구는 삽질하면서 배워 나가는거니 너무 크게 마음쓰지 말라고 하더라.
ㄴr 이렇게 성장해 나가는 걸ㄲr...
todo list 다만들었다고 개발자한테 자랑하니까 대충 잘했다며 갑자기 이번엔 게시판을 만들어보잰다
서버는 나중에 만들어줄테니 퍼블리싱 먼저 하란다(이게맞나)
하라니까 또 하러 갑니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[탭메뉴 만들기]]></title>
            <link>https://velog.io/@nemo-cat/CSS-%ED%83%AD%EB%A9%94%EB%89%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@nemo-cat/CSS-%ED%83%AD%EB%A9%94%EB%89%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Fri, 12 Jan 2024 15:42:25 GMT</pubDate>
            <description><![CDATA[<p>오늘 탭메뉴를 만들다가 살짝 헤매서 기록용으로 글을 남긴다.
기록이 모이다 보면.. 뭐든... 되겠지...</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/d779bf14-b871-4dbf-9f17-fc109a586164/image.png" alt=""></p>
<p>원래 만들고 싶은 메뉴는 위의 그림과 같은 메뉴이다.
평상시 웹 사이트에서 많이 볼 수 있는 디자인이다.</p>
<hr>
<h2 id="처음-작성한-css">처음 작성한 CSS</h2>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/758b74c2-5f0b-44fb-bc22-3719eecc4c7e/image.png" alt=""></p>
<p>얼핏보면 맞게 만든것 같다.
하지만 자세히 보면 문제가 있는데, li.active가 됐을때 메뉴1의 오른쪽 선이 보이면 안되는데 그대로 있는것이다 :-(</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/12d6b692-24dc-4433-9c51-05a12f27db20/image.png" alt="">
이런식으로 선이 겹쳐져서 보인다.
내가 원하던 디자인이 안나왔다.</p>
<pre><code class="language-css">/* css 코드 */

.tab_menu li {
    background: #fafafa;
    border: 1px solid #e4e8eb;
}

.tab_menu li ~ li {
    border-left: none;
}

.tab_menu li.active {
    position: relative;
    background: #fff;
    border: 1px solid #000;
}</code></pre>
<blockquote>
<h3 id="여기서-tmi-일반형제선택자--">여기서 TMI) 일반형제선택자 &quot; ~ &quot;</h3>
<p>요소들의 부모가 같을때(형제일때) A ~ 다음 형제를 모두 선택한다.
말로 설명하기엔 어려운데, 예시로 p ~ span 이면 <span style="color: red">p</span>의 형제인 <span style="color: red">span</span>을 모두 선택하는 선택자이다.
위 코드를 보면, 나는 li ~ li으로 사용했기 때문에, li의 형제인 li을 선택하는 것이라, 맨 첫번째 li를 제외한 다른 li의 border-left를 none으로 처리한것이다.</p>
</blockquote>
<hr>
<h2 id="보완한-css">보완한 CSS</h2>
<pre><code class="language-css">/* css 코드 */

.tab_menu2 li {
  margin-left: -1px;
  background: #fafafa;
  border: 1px solid #e4e8eb;
}

.tab_menu2 li.active {
  position:relative;
  background: #fff;
  border: 1px solid #000;
} 
</code></pre>
<p>이번에는 li에 <strong style="color: red">margin</strong>값을 <strong style="color: red">마이너스</strong>로 줘서 선이 겹치게끔 만들었다.
이렇게 하니까 li.active가 됐을때 position: relative의 영향을 받아 본인 자리를 유지하면서 z축으로 올라오게 되어 원하는 디자인을 만들 수 있게 되었다.
<img src="https://velog.velcdn.com/images/nemo-cat/post/b53b6500-672d-48e8-9e71-e291cce99298/image.png" alt=""></p>
<h2 id="결과">결과</h2>
<p>!codepen[So-An/embed/BabQoKV?default-tab=css%2Cresult]</p>
<blockquote>
<h3 id="여기서-tmi2-inline-inline-block의-여백">여기서 TMI2) inline, inline-block의 여백</h3>
<p>display 속성값이 inline이나 inline-block인 요소들은 각 요소 사이에 여백이 생긴다.
제일 쉽고 간단한 방법은 부모 요소에 <span style="color: red">font-size: 0;</span>을 주면된다.
그 뒤에 자식한테 다시 font-size를 줘야 텍스트가 보이니 주의하자.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[웹디자인기능사]2023년 웹디자인기능사 3회 실기 시험 후기]]></title>
            <link>https://velog.io/@nemo-cat/%EC%A0%9C3%ED%9A%8C-%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC-%EC%8B%A4%EA%B8%B0-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@nemo-cat/%EC%A0%9C3%ED%9A%8C-%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC-%EC%8B%A4%EA%B8%B0-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Thu, 24 Aug 2023 11:06:14 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>웹디자인기능사 실기 후기</p>
</blockquote>
<h3 id="시험신청후기">시험신청후기</h3>
<p>큐넷에서 실기시험은 처음 신청해보는거라 시험 신청이 이렇게 빡셀줄은 꿈에도 몰랐다..
첫날에 시험 신청에 실패하고 울면서 4회차 시험을 봐야하나 하다가 후기를 보니 다른날에도 조금씩 풀린대서 틈틈히 들어가다가 겨우 한자리 얻었다!</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/c2c77bf1-3783-4f5d-b9d9-38a83ca77738/image.png" alt=""></p>
<p>시험장소는 휘경동에 있는 한국산업인력공단 서울지역본부였다. 휘경동이 집에서 먼건 아니지만 교통편이 애매해서 7시 30분에 출발해서 8시 10분쯤 도착했다. ( 버스에서 내려서 10분~ 15분정도 걸어갔다 )
수험자 대기실에 앉아있는데 입실 마감시간이 다가오도록 사람이 별로 오지 않았다.
최종적으로 8명? 정도 온것같다.
시험자리 잡기가 힘들었기 때문에 안보러올거면 애초에 신청을 하지 말지라는 생각도 들었다..</p>
<hr>
<h3 id="시험-후기">시험 후기</h3>
<p>8시 30분에 감독관님의 지시에 따라 전자기기를 모두 종료하고 시험 장소로 이동했다.
시험장소에 들어가니까 에코백(?)같은곳에 비번호를 넣어두고 하나 뽑아달라 하셨다.
첫번째 순서로 뽑았는데 비번호 1번이 뽑혔다. 그 후 본인 확인과 함께 자리에 앉았다.</p>
<p>8시 30분부터 9시까지 감독관님이 수험자 유의사항, 답안 제출은 어떤식으로 하는지 등등 시험에 관한 모든걸 친절하게 알려주셨고, 9시부터 시험을 보기 시작했다.</p>
<p>이번에 받은 시험은 A-1 JUST 쇼핑몰이 나왔다.
A유형은 정말 베이직하다고 생각하는 유형이기에 쉽게 느껴졌다.</p>
<p>시험 시작하자마자 html 마크업을 끝내고, css 작업하면서 중간중간 이미지가 필요하면 그때그때 포토샵으로 이미지 작업을 해줬다.
마지막으로 제이쿼리를 이용해서 기능들을 구현해주었다.
다 만들고 크롬과 엣지에서 동일하게 작동하는지, 표현되는지 확인 했고 한번더 시험지를 훑어 본 후 첫번째로 제출하고 나왔다. 소요시간은 1시간 40분정도 걸렸다</p>
<p>다 만든 후 자리에서 손을 들면 감독관님이 오셔서 답안 폴더를 감독관 컴퓨터로 전송해주신다. 나가기 전에 감독관 컴퓨터에서 제대로 작동하는지 확인하고 나오면 된당 :-D</p>
<p>합격발표는 9월 13일에 나온다고 하니, 혹시 합격하면 따로 합격한거 첨부해놔야겠다 </p>
<hr>
<h3 id="합격-인증">합격 인증</h3>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/ac40bc5c-8e8b-44eb-a4a0-dc33e40dd02c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[웹디자인기능사]A~E 유형 연습]]></title>
            <link>https://velog.io/@nemo-cat/%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC-AE%EC%9C%A0%ED%98%95</link>
            <guid>https://velog.io/@nemo-cat/%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC-AE%EC%9C%A0%ED%98%95</guid>
            <pubDate>Fri, 21 Jul 2023 13:36:29 GMT</pubDate>
            <description><![CDATA[<p>웹디자인 기능사 각 유형별 문제는 겹치는 부분이 많아서 풀고싶은 것만 풀어 봤다!</p>
<h1 id="a유형-연습">A유형 연습</h1>
<h2 id="a유형-1">A유형-1</h2>
<blockquote>
<p>A-1 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/772d6885-ac6c-4dd8-ad02-23ce44d38813/image.png" alt=""></p>
<blockquote>
<p>A-1 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/c51e8332-beab-496c-a453-a01d37380a75/image.png" alt=""></p>
<blockquote>
<p>A-1 코드</p>
</blockquote>
<p>!codepen[So-An/embed/zYMLYBW?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<h2 id="a유형-2">A유형-2</h2>
<blockquote>
<p>A-2 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/f82e0bba-6af2-41a7-82e1-536f790134bc/image.png" alt=""></p>
<blockquote>
<p>A-2 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/635736f3-f4d6-4b1d-a688-a394b2f155c3/image.png" alt=""></p>
<blockquote>
<p>A-2 코드</p>
</blockquote>
<p>!codepen[So-An/embed/VwVovZB?default-tab=html%2Cresult]</p>
<h2 id="a유형-3">A유형-3</h2>
<blockquote>
<p>A-3 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/a0e4568f-85d3-4377-8235-82cbe681522b/image.png" alt=""></p>
<blockquote>
<p>A-3 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/0f2f6ed8-5b45-4a30-b1a7-bb606fb6ce25/image.png" alt=""></p>
<blockquote>
<p>A-3 코드</p>
</blockquote>
<p>!codepen[So-An/embed/wvRwqVP?default-tab=html%2Cresult]</p>
<h2 id="a유형-4">A유형-4</h2>
<blockquote>
<p>A-4 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/31f68f59-9407-48a4-a719-015db216198b/image.png" alt=""></p>
<blockquote>
<p>A-4 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/faf22e83-8e74-4af9-816d-2ef24a3861c2/image.png" alt=""></p>
<blockquote>
<p>A-4 코드</p>
</blockquote>
<p>!codepen[So-An/embed/bGObxog?default-tab=html%2Cresult]</p>
<hr>
<h1 id="b유형-연습">B유형 연습</h1>
<h2 id="b유형-1">B유형-1</h2>
<blockquote>
<p>B-1 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/297dd7bb-f299-431c-af1b-34becfe3c58b/image.png" alt=""></p>
<blockquote>
<p>B-1 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/30cc7697-f896-4742-bbce-6edfb0a02d54/image.png" alt=""></p>
<blockquote>
<p>B-1 완성코드</p>
</blockquote>
<p>!codepen[So-An/embed/VwqLOBw?default-tab=html%2Cresult]</p>
<h2 id="b유형-2">B유형-2</h2>
<blockquote>
<p>B-2 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/7b5b0ace-7a0b-4a60-aee5-bee3ddf20808/image.png" alt=""></p>
<blockquote>
<p>B-2 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/621adcc7-f7bc-4f6e-a4a3-a36fa50d2fd4/image.png" alt=""></p>
<blockquote>
<p>B-2 코드</p>
</blockquote>
<p>!codepen[So-An/embed/xxmGNoo?default-tab=html%2Cresult]</p>
<hr>
<h1 id="c유형-연습">C유형 연습</h1>
<h2 id="c유형-1">C유형-1</h2>
<blockquote>
<p>C-1 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/fea74cb5-e932-4e5a-9eac-b5ec78b78928/image.png" alt=""></p>
<blockquote>
<p>C-1 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/43358aa4-ad64-4ddf-90c5-3a8b3b32ff83/image.png" alt=""></p>
<blockquote>
<p>C-1 코드</p>
</blockquote>
<p>!codepen[So-An/embed/eYbNeKY?default-tab=html%2Cresult]</p>
<hr>
<h1 id="d유형-연습">D유형 연습</h1>
<h2 id="d유형-1">D유형-1</h2>
<blockquote>
<p>D-1 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/236308ea-9bbb-42e6-a1c7-ac3f09d3c6e9/image.png" alt=""></p>
<blockquote>
<p>D-1 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/6e42de9b-e67e-4948-9fc2-5c4ad45a5d03/image.png" alt=""></p>
<blockquote>
<p>D-1 코드</p>
</blockquote>
<p>!codepen[So-An/embed/MWZYjvm?default-tab=html%2Cresult]</p>
<h2 id="d유형-3">D유형-3</h2>
<blockquote>
<p>D-3 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/d7fc7377-e591-4ca9-a52d-1d74fe6c2e7a/image.png" alt=""></p>
<blockquote>
<p>D-3 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/942e2725-02a7-4062-9737-27a2e06420df/image.png" alt=""></p>
<blockquote>
<p>D-3 코드</p>
</blockquote>
<p>!codepen[So-An/embed/jOXPyad?default-tab=html%2Cresult]</p>
<hr>
<h1 id="e유형-연습">E유형 연습</h1>
<h2 id="e유형-1">E유형-1</h2>
<blockquote>
<p>E-1 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/1cddcbaf-cc6a-4691-9e05-bdd4be392301/image.png" alt=""></p>
<blockquote>
<p>E-1 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/ab6c0d6a-01d1-4ae8-aa15-8f41895196a9/image.png" alt=""></p>
<blockquote>
<p>E-1 코드</p>
</blockquote>
<p>!codepen[So-An/embed/NWePvax?default-tab=html%2Cresult]</p>
<h2 id="e유형-2">E유형-2</h2>
<blockquote>
<p>E-2 와이어프레임</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/fe314e7c-288b-4bb3-a100-30d2f0ccf90b/image.png" alt=""></p>
<blockquote>
<p>E-2 완성이미지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/16fcc3be-9710-4bea-9356-a9a9be899a23/image.png" alt=""></p>
<blockquote>
<p>E-2 코드</p>
</blockquote>
<p>!codepen[So-An/embed/PoXwrrX?default-tab=html%2Cresult]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[웹디자인기능사]탭 메뉴 구현하기]]></title>
            <link>https://velog.io/@nemo-cat/%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC%ED%83%AD%EB%A9%94%EB%89%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@nemo-cat/%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC%ED%83%AD%EB%A9%94%EB%89%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Fri, 21 Jul 2023 11:56:10 GMT</pubDate>
            <description><![CDATA[<h2 id="탭메뉴-만들기">탭메뉴 만들기</h2>
<p>!codepen[So-An/embed/oNQyKVZ?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<blockquote>
<p>탭메뉴 포인트</p>
</blockquote>
<ul>
<li>탭 메뉴는 크게 <code>tab-nav</code>와 <code>tab-contents</code>로 나누어 작성 ( 클래스명은 편한대로.. )</li>
<li>현재 클릭한 <code>tab-nav li</code>의 <code>index</code>를 이용하여, 알맞는 <code>tab-content</code>를 나타나게 한다.</li>
<li><code>active</code>라는 클래스를 가진 요소에 <code>dispaly: block</code>를 주어 나타나게 함</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[웹디자인기능사]팝업레이어 구현하기]]></title>
            <link>https://velog.io/@nemo-cat/%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC%ED%8C%9D%EC%97%85%EB%A0%88%EC%9D%B4%EC%96%B4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@nemo-cat/%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC%ED%8C%9D%EC%97%85%EB%A0%88%EC%9D%B4%EC%96%B4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 21 Jul 2023 09:47:19 GMT</pubDate>
            <description><![CDATA[<h2 id="팝업레이어-구현하기">팝업레이어 구현하기</h2>
<p>!codepen[So-An/embed/ZEmRNML?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<hr>
<h2 id="팝업레이어-포인트">팝업레이어 포인트</h2>
<pre><code class="language-css">.bg {
  display: none;
  position: absolute;
  z-index: 1;
  /* 생략 */
}

.popUp {
  display: none;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  /* 생략 */
}</code></pre>
<ul>
<li>뒷 배경과 팝업레이어에 <code>z-index</code>값을 주어 가장 앞에 위치하도록 해야함</li>
<li>뒷 배경보다 팝업레이어의 <code>z-index</code>값이 더 커야함</li>
<li>뒷 배경과 팝업레이어 모두 <code>position: absolute</code> 적용</li>
<li>팝업 레이어를 화면의 정중앙에 오게 하려면<code>top: 50%</code>, <code>left: 50%</code>, <code>transfrom: translate(-50%, -50%)</code>적용하면 됨</li>
</ul>
<blockquote>
<p>transfrom: translate(-50%, -50%)를 주는 이유</p>
</blockquote>
<p>팝업 레이어에 <code>top: 50%</code>, <code>left: 50%</code> 만 주게 된다면 아래 그림처럼 팝업레이어의 왼쪽 상단 꼭지점이 <code>top: 50%</code>, <code>left: 50%</code> 위치에 위치하게된다.
<img src="https://velog.velcdn.com/images/nemo-cat/post/5a62340e-78c6-48cf-a6a7-3b8d5b89bb94/image.png" alt=""></p>
<p>이 상태에서 <code>transfrom: translate(-50%, -50%)</code>를 주게 된다면, 요소(팝업레이어)를 기준으로 z축에서 -50%, y축에서 -50%씩 이동하게 되어 정 중앙에 위치하게 된다.</p>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/0c0c74d6-47c9-4230-a968-e038da7f871d/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[웹디자인기능사]슬라이드 구현하기]]></title>
            <link>https://velog.io/@nemo-cat/%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%93%9C-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@nemo-cat/%EC%9B%B9%EB%94%94%EC%9E%90%EC%9D%B8%EA%B8%B0%EB%8A%A5%EC%82%AC%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%93%9C-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 21 Jul 2023 08:28:21 GMT</pubDate>
            <description><![CDATA[<p>슬라이드 유형은 다음과 같다</p>
<ul>
<li><code>좌/우</code> 슬라이드</li>
<li><code>상/하</code> 슬라이드</li>
<li><code>fadeIn/fadeOut</code>슬라이드</li>
</ul>
<blockquote>
<p><code>좌/우</code>,<code>상/하</code> 슬라이드의 기본</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/5a0d474a-d1cc-47be-9b1e-476a2e9ad7da/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/nemo-cat/post/bb86e990-5caa-4dcd-bbc4-2494d7e01abf/image.jpg" alt=""></p>
<p>좌/우, 상/하 슬라이드는 다음과 같이 구성된다.</p>
<ul>
<li>실제 슬라이드가 보이는 영역</li>
<li>슬라이드를 나열할 수 있는 띠지</li>
<li>슬라이드</li>
</ul>
<p>띠지가 좌/우, 상/하로 움직이면서 슬라이드 되는 효과를 나타내게 된다.</p>
<blockquote>
<p><code>fadeIn/fadeOut</code> 슬라이드의 기본</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/3165c482-7c46-4bde-9d1d-b25d3999bf54/image.jpg" alt=""></p>
<p>fadeIn/fadeOut 슬라이드는 <code>position: absolute</code>를 이용하여 슬라이드를 공중에 띄워 하나로 겹치게 한다. 이후 보여줄 슬라이드에 <code>fadeIn()</code>을 주고 나머지에는 <code>fadeOut()</code>을 주어 슬라이드 효과를 나타낸다.</p>
<hr>
<h2 id="좌우-슬라이드">좌/우 슬라이드</h2>
<p>!codepen[So-An/embed/MWzXVLB?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<h2 id="상하-슬라이드">상/하 슬라이드</h2>
<p>!codepen[So-An/embed/MWzXRqM?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<p>좌/우, 상/하 슬라이드의 기본 원리는 동일하다! <code>슬라이드 띠지</code>의 방향과 <code>animate</code> 방향만 바꿔주면 원하는 슬라이드를 만들 수 있다.
결과 화면을 보면 슬라이드 1번과 3번은 마지막 슬라이드를 만나면 첫번째 슬라이드로 돌아가는 모션이 보이고, 2번과 4번은 자연스럽게 첫번째 슬라이드가 나오는것을 확인할 수 있다.</p>
<blockquote>
<p>첫번째로 돌아가는 슬라이드</p>
</blockquote>
<pre><code class="language-js">let slideCount1 = 0; //현재 슬라이드 순서를 카운트하는 변수
setInterval(slideLeft1, 3000); //3초 간격으로 slideLeft1 함수 실행

function slideLeft1() {
  slideCount1++; // 함수가 실행될때마다 1씩 증가
  if (slideCount1 == 3) {
    slideCount1 = 0; // 변수값이 3이 되면 0으로 초기화(슬라이드 첫번째로 이동)
  }
  /* 0.5초의 속도로 top값 이동 */
  $(&quot;.slide-inner01&quot;).animate({ top: slideCount1 * -250 + &quot;px&quot; }, 500);
}</code></pre>
<blockquote>
<p>자연스럽게 이어지는 슬라이드</p>
</blockquote>
<pre><code class="language-js">let slideCount2 = 0;
setInterval(slideLeft2, 3000);
/* 첫번째 슬라이드를 복제하여 slide-inner의 마지막에 추가함
   슬라이드1(0px) -&gt; 슬라이드2(-250px) -&gt; 슬라이드3(-500px) -&gt; 슬라이드1(-750px) 순서가 됨*/
$(&quot;.slide-inner02 .slide&quot;).eq(0).clone().appendTo(&quot;.slide-inner02&quot;);

function slideLeft2() {
  slideCount2++;
   /* slideCount가 3이되면 top이 -750px으로 이동한 후,
   if문을 만나면서 slideCount가 0으로 초기화됨 */
  $(&quot;.slide-inner02&quot;).animate({ top: slideCount2 * -250 + &quot;px&quot; }, 500);
  if (slideCount2 == 3) {
    slideCount2 = 0;
    /* 0초의 속도로 top을 0px으로 이동
       맨 마지막 요소와 맨 첫번째 요소가 자연스럽게 이어지게 됨 */
    setTimeout(function () {
      $(&quot;.slide-inner02&quot;).animate({ top: &quot;0&quot; }, 0);
    }, 500);
  }
}</code></pre>
<hr>
<h2 id="fadeinfadeout-슬라이드">fadeIn/fadeOut 슬라이드</h2>
<p>!codepen[So-An/embed/XWyYQvX?default-tab=js%2Cresult&amp;theme-id=dark]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[웹디자인기능사]메뉴 구현하기]]></title>
            <link>https://velog.io/@nemo-cat/jQuery%EB%A9%94%EB%89%B4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@nemo-cat/jQuery%EB%A9%94%EB%89%B4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 20 Jul 2023 13:54:45 GMT</pubDate>
            <description><![CDATA[<p>웹디자인 기능사 실기시험을 준비하면서 공부한 것들을 정리해보려고 한다.</p>
<hr>
<h2 id="메뉴-모음">&lt;메뉴 모음&gt;</h2>
<h3 id="가로메뉴">가로메뉴</h3>
<blockquote>
<h4 id="1-가로메뉴---전체-드롭다운-메뉴">1. 가로메뉴 - 전체 드롭다운 메뉴</h4>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/123d5328-6521-417a-904b-2ba71cc5c9c9/image.png" alt=""></p>
<p>!codepen[So-An/embed/GRwGyjE?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<blockquote>
<h4 id="2-가로메뉴---개별-드롭다운-메뉴">2. 가로메뉴 - 개별 드롭다운 메뉴</h4>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/e4f6a18f-3966-46ae-9cb9-969bbb4d0c2a/image.png" alt=""></p>
<p>!codepen[So-An/embed/gOQKoGo?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<h3 id="세로메뉴">세로메뉴</h3>
<blockquote>
<h4 id="3-세로메뉴---개별-드롭다운-메뉴">3. 세로메뉴 - 개별 드롭다운 메뉴</h4>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/93a3aa8d-0fed-4adc-b4e3-4d54801406e6/image.png" alt=""></p>
<p>!codepen[So-An/embed/vYQrpWZ?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<blockquote>
<h4 id="4-세로메뉴---오른쪽-top">4. 세로메뉴 - 오른쪽 TOP</h4>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/6a99417b-56dc-4026-a332-4539562c33be/image.png" alt=""></p>
<p>!codepen[So-An/embed/vYQrpdJ?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<blockquote>
<h4 id="5-세로메뉴---오른쪽-개별">5. 세로메뉴 - 오른쪽 개별</h4>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/12f19cea-a921-4cc5-95a7-4b0188c1ab1c/image.png" alt=""></p>
<p>!codepen[So-An/embed/vYQrpRJ?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<blockquote>
<h4 id="6-세로메뉴---오른쪽-전체">6. 세로메뉴 - 오른쪽 전체</h4>
</blockquote>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/b89c389d-b857-4357-a409-166ead433c14/image.png" alt=""></p>
<p>!codepen[So-An/embed/mdQKpLq?default-tab=js%2Cresult&amp;theme-id=dark]</p>
<hr>
<h2 id="메인메뉴-효과">&lt;메인메뉴 효과&gt;</h2>
<p><img src="https://velog.velcdn.com/images/nemo-cat/post/32e97549-fda1-4475-b14d-121151552e8b/image.png" alt="">
메인메뉴에 <code>mouseover</code>시 하이라이트가 되고, <code>mouseout</code>되면 하이라이트가 사라져야 한다.
나는 아래 두가지 방법을 이용하여 작성해 보았다.</p>
<ul>
<li><code>main menu &gt; li:hover</code>시 <code>a</code>에 하이라이트 효과 주기<pre><code>&lt;!-- CSS --&gt;
&lt;style&gt;
.main-menu01 li:hover &gt; a {
 background-color: blue;
 color: #fff;
}
&lt;/style&gt;
</code></pre></li>
</ul>
<!-- HTML -->
<ul class="main-menu01">
  <li>
    <a href="#none">menu1</a>
    <ul class="sub-menu01">
      <li><a href="#none">sub1-1</a></li>
      <li><a href="#none">sub1-2</a></li>
      <li><a href="#none">sub1-3</a></li>
      <li><a href="#none">sub1-4</a></li>
    </ul>
  </li>
  <li>
    <!-- 생략 -->
  </li>
</ul>
```
- 메인메뉴에 `mouseover`시 `main menu > li > a`에 클래스명을 부여하여 하이라이트 효과 주기
```
<!-- CSS -->
<style>
.main-menu01 > li > a.active {
  background-color: blue;
  color: #fff;
}
</style>

<!-- HTML -->
<ul class="main-menu01">
  <li>
    <a href="#none">menu1</a>
    <ul class="sub-menu01">
      <li><a href="#none">sub1-1</a></li>
      <li><a href="#none">sub1-2</a></li>
      <li><a href="#none">sub1-3</a></li>
      <li><a href="#none">sub1-4</a></li>
    </ul>
  </li>
  <li>
    <!-- 생략 -->
  </li>
</ul>

<!-- jQuery -->
<script>
  $(".main-menu01 > li").mouseover(function () {
      //기존에 클래스명이 남아있을수도 있으므로 전부 삭제
    $(".main-menu01 > li > a").removeClass("active");
    //현재 mouseover한 li의 자식 a에게 active라는 클래스명을 부여함
    $(this).children("a").addClass("active");
  });

  $(".main-menu01 > li").mouseleave(function () {
      //li에서 mouseleave되면 active라는 클래스명 삭제
    $(".main-menu01 > li > a").removeClass("active");
  });
</script>
<p>```</p>
]]></description>
        </item>
    </channel>
</rss>