<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>munju_dev.log</title>
        <link>https://velog.io/</link>
        <description>Web publisher</description>
        <lastBuildDate>Thu, 27 Apr 2023 08:53:57 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>munju_dev.log</title>
            <url>https://velog.velcdn.com/images/munju_dev/profile/42ad2b4f-8f8c-4b3a-bb34-929db1faf0d6/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. munju_dev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/munju_dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[JS] 삼항연산자]]></title>
            <link>https://velog.io/@munju_dev/JS-%EC%82%BC%ED%95%AD%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@munju_dev/JS-%EC%82%BC%ED%95%AD%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Thu, 27 Apr 2023 08:53:57 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>조건(삼항)연산자, <a href="https://mesonia.tistory.com/138">[ javascript ] 삼항연산자</a>
사이트를 참고하여 작성하였습니다.</p>
</blockquote>
<p>if문을 아래와 같은 형식으로 사용해왔다.</p>
<pre><code>if(조건){ 
    //조건이 참일때 
}else{ 
    //조건이 거짓일때 
}</code></pre><p>삼항연산자는 if 조건문의 대체제로 간결하게 비교구문을 작성할 수 있다.</p>
<blockquote>
<p>삼항연산자는 조건에 따라 값을 할당 하거나, 조건에 따라 연산을 진행 할 때 사용한다.</p>
</blockquote>
<h2 id="삼항연산자-구문">삼항연산자 구문</h2>
<p>mdn 사이트에서 나와 있는 설명을 가져와봤다. </p>
<blockquote>
<p> condition ? exprIfTrue : exprIfFalse</p>
</blockquote>
<p> condition
조건문으로 사용되는 표현식</p>
<p>exprIfTrue
condition이 truthy한 값으로 평가될 경우 실행되는 표현식
(true와 같거나, true로 치환될 수 있는 값)</p>
<p>exprIfFalse
condition이 falsy한 값으로 평가될 경우 실행되는 표현식 
(false와 같거나, false로 치환될 수 있는 값)</p>
<p>설명
false 이외의 falsy한 표현식에는 null, NaN, 0, 비어있는 문자열 (&quot;&quot;), 그리고 undefined가 있습니다. condition이 이 중 하나일 경우 조건 연산자의 결괏값은 exprIfFalse 표현식을 실행한 결괏값입니다.</p>
<h2 id="예제">예제</h2>
<ol>
<li>조건에 따라 값을 할당한다.</li>
</ol>
<pre><code>&lt;script&gt;

  const a = 1; 
  const b = (a===1)?&#39;a입니다&#39;:&#39;b입니다&#39;; 
  console.log(b) //a입니다

&lt;/script&gt;</code></pre><ol start="2">
<li>조건에 따라 연산한다.</li>
</ol>
<pre><code>&lt;script&gt;

  const a = 1; 
  const text; 
  (a === 1) ? text=&#39;a입니다&#39; : text=&#39;b입니다&#39;; 
  console.log(text) //a입니다

&lt;/script&gt;</code></pre><h2 id="es6에서의-삼항연산자-사용">ES6에서의 삼항연산자 사용</h2>
<h3 id="1-삼항연산자-조건--참거짓">1. 삼항연산자 (조건) ? 참:거짓</h3>
<pre><code>&lt;script&gt;

    let a = true;

    let ex1 = a === true ? &quot;참&quot; : &quot;거짓&quot;;

    console.log(`결과: ${ex1}`);

&lt;/script&gt;</code></pre><p>위 예제에서 a의 값이 true 인가? 맞으면 &quot;참&quot;, 틀리면 &quot;거짓&quot;을 비교하는 구문이다.
결과값은 결과: 참 으로 콘솔창에 출력된다.</p>
<h3 id="2--같다-조건--참결과">2. === 같다, 조건 &amp;&amp; 참결과</h3>
<pre><code>&lt;script&gt;

    let b = false;

    let ex2 = b === false &amp;&amp; &quot;거짓&quot;;

    console.log(`결과: ${ex2}`);

&lt;/script&gt;</code></pre><p>b는 false 로 선언된 변수이다. b라는 변수가 false인것이 참일 경우 결과 값에 &quot;결과&quot;라는 값을 출력하라는 조건문이다.<br>&amp;&amp; 연산자는 참의 결과를 나타내기때문에, 콘솔창에는 &quot;결과: 거짓&quot; 라는 값이 출력된다.</p>
<h3 id="3--조건--거짓undefined">3. === 조건 || 거짓(undefined)</h3>
<pre><code>&lt;script&gt;

    let c = false;
    //변수 c 는 false이다.

    let ex3 = c === true || &quot;거짓의결과&quot;;
    //변수 c 는 === 같냐, 트루 또는 거짓의 결과
    //-&gt; 변수 C가 true가 아니고 false이기 때문에, 뒤에 있는 &quot;거짓의 결과&quot; 값을 반환한다.
    console.log(`결과: ${ex3}`);

&lt;/script&gt;</code></pre><p>2번과 동일한 유형으로, &amp;&amp;이 아닌 ||를 사용한 예제이다.
|| 연산자를 써서 비교할 경우 거짓의 결과가 반환된다.콘솔창에는 변수 c가 false이기때문에,
&quot;결과: 거짓의 결과&quot;가 출력된다. 변수 c에 undefined값을 넣어도 true가 아니기때문에, 
|| 뒤에 있는 &quot;거짓의 결과&quot;가 출력될 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[웹접근성] WAI-ARIA]]></title>
            <link>https://velog.io/@munju_dev/%EC%9B%B9%EC%A0%91%EA%B7%BC%EC%84%B1-WAI-ARIA</link>
            <guid>https://velog.io/@munju_dev/%EC%9B%B9%EC%A0%91%EA%B7%BC%EC%84%B1-WAI-ARIA</guid>
            <pubDate>Fri, 14 Apr 2023 05:58:21 GMT</pubDate>
            <description><![CDATA[<p>웹 접근성 마크를 취득해야하거나 지침가이드를 따라야하는 프로젝트가 아닌이상 접근성 개선작업이나 관련된 제작 업무를 해본 경험이 없었다. 하지만 기본적으로 숙지해놓고 있어야하는 웹접근성에
대해 무지할수없어 정리를 해보았다.</p>
<p>아직도 알아야 할 내용들이 많지만 , 오늘은 WAI-ARIA 에 대해 알아보도록 하겠다.</p>
<h2 id="wai-aria">WAI-ARIA</h2>
<blockquote>
<p>Web Accessibility Initiative – Accessible Rich Internet Applications</p>
</blockquote>
<p><em>WAI는 W3C에서 웹 접근성을 담당하는 기관으로
ARIA는 RIA 환경의 웹 접근성에 대한 표준 기술 규격을 의미한다.</em></p>
<p>( RIA : 정적인 HTML, 단순한 자바스크립트 환경의 웹이 아닌 동적인 자바스크립트와 Ajax와 같은 기술을 사용한 환경에서 수준 높은 UX(User eXperience)를 제공하는 웹 애플리케이션 )</p>
<h2 id="wai-aria를-사용해야하는-이유">WAI-ARIA를 사용해야하는 이유</h2>
<p>RIA(Rich Internet Applications)는 화려하고 편리한 웹 애플리케이션이지만 스크린리더와 같은 보조기술을 사용하는 장애인들이 접근하기에 취약한 부분이다.
스크린리더 및 보조기기 등에서 접근성 및 상호 운용성을 향상 시키기 위한 목적으로 나왔으며, 
웹애플리케이션 역할(Role), 속성(Property) 정보를 추가하여 개선 할 수 있도록 제공하고 있다.</p>
<p> WAI-ARIA 를 이용해서 개발자가 의도한 유저 인터페이스 행동이나 구조적인 정보를 
스크린 리더와 같은 보조 기술에 전달하여 시각/인지 장애인들에게 일반 사용자들과 동일한 정보를 제공하여 웹페이지 탐색을 돕는 UX를 제공한다.</p>
<h2 id="wai-aria-사용-방법">WAI-ARIA 사용 방법</h2>
<ol>
<li>HTML5 Section 요소와 중복하여 사용하지 않는다.
: HTML5 에서 추가된 시멘틱 태그를 먼저 사용하고 의미를 부가적으로 주어야 할 때 role을 추가한다.</li>
</ol>
<pre><code>&lt;!-- X --&gt;
&lt;h1 role=&quot;button&quot;&gt;바로가기&lt;/h1&gt;
&lt;!-- △ --&gt;
&lt;h1&gt;&lt;span role=&quot;button&quot;&gt;바로가기&lt;/span&gt;&lt;/h1&gt;
&lt;!-- ○ --&gt;
&lt;h1&gt;&lt;button&gt;바로가기&lt;/button&gt;&lt;/h1&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/2fe23b0c-9a86-434e-aacc-d44527576664/image.png" alt=""></p>
<ol start="2">
<li>만약 <code>&lt;button&gt;</code> , <code>&lt;input&gt;</code> 요소들처럼 키보드 지원이 되는 요소를 <code>&lt;div&gt;</code>와 WAI-ARIA로 작업해야 한다면, 동일하게 작업할 것</li>
</ol>
<pre><code>&lt;!-- html5 --&gt;
&lt;button&gt;버튼&lt;button&gt;

&lt;!-- div + WAI-ARIA --&gt;
&lt;div role=&quot;button&quot; tabindex=&quot;0&quot;&gt;버튼&lt;/div&gt;</code></pre><ol start="3">
<li>사용자의 브라우저와 디바이스가 WAI-ARIA를 지원하는 지 확인할 것
: WAI-ARIA는 우리가 사용하는 크롬, 인터넷 익스플로러, 사파리 등의 최신 버전 브라우저들은 대체로 지원을 합니다. 아래의 이미지는 Can I Use에서 확인할 수 있다.</li>
</ol>
<p>WAI-ARIA 지원 브라우저 현황 (출처 : <a href="https://caniuse.com/?search=wai-aria">https://caniuse.com/?search=wai-aria</a>)
<img src="https://velog.velcdn.com/images/munju_dev/post/d092cb4d-2ac6-4a49-9931-d270d770e3fd/image.png" alt=""></p>
<h2 id="wai-aria-구조">WAI-ARIA 구조</h2>
<p>WAI-ARIA를 구성하는 역할, 속성, 상태 기능은 HTML 요소에 보충하여 사용되는데, 
여기서 role에 대해 알아보겠다.</p>
<ol>
<li>역할(Role) 컴포넌트나 요소 내의 역할을 정의</li>
</ol>
<p>대체로 이미지나 텍스트를 봤을때 이곳을 누르면 탭이라는 것을 인지할 것이다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/c2218e58-9832-4c7a-ba69-8c3ab37d2353/image.png" alt=""></p>
<p>탭버튼을 작업할때는 주로 <code>&lt;ul&gt;</code> ,<code>&lt;li&gt;</code> ,<code>&lt;a&gt;</code> 태그들로 탭을 구성하는데, 
WAI-ARIA role=&quot;tabList&quot;,  role=&quot;tab&quot;,  role=&quot;tabpanel&quot;로 스크린 리더기 사용자에게 더 정확한 정보를 제공할 수 있다.</p>
<pre><code>&lt;!-- 일반적인 작업 --&gt;
&lt;ul class=&quot;btnList&quot;&gt;
  &lt;li&gt;
    &lt;a href=&quot;#&quot; class=&quot;on&quot;&gt;정보1&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href=&quot;#&quot;&gt;정보2&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href=&quot;#&quot;&gt;정보3&lt;/a&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;wrap-tab-contents&quot;&gt;
  &lt;div id=&quot;tabpanel01&quot; class=&quot;tab-contents on&quot;&gt;&lt;p&gt;정보1 콘텐츠&lt;/p&gt;&lt;/div&gt;
  &lt;div id=&quot;tabpanel02&quot; class=&quot;tab-contents&quot;&gt;&lt;p&gt;정보2 콘텐츠&lt;/p&gt;&lt;/div&gt;
  &lt;div id=&quot;tabpanel03&quot; class=&quot;tab-contents&quot;&gt;&lt;p&gt;정보3 콘텐츠&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;!-- WAI-ARIA 적용 --&gt;
&lt;ul class=&quot;btnList&quot; role=&quot;tabList&quot;&gt;
  &lt;li&gt;
    &lt;a href=&quot;#&quot; id=&quot;tab01&quot; class=&quot;on&quot; role=&quot;tab&quot; aria-selected=&quot;true&quot; aria-controls=&quot;tabpanel01&quot;&gt;정보1&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href=&quot;#&quot; id=&quot;tab02&quot; role=&quot;tab&quot; aria-selected=&quot;false&quot; aria-controls=&quot;tabpanel02&quot;&gt;정보2&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href=&quot;#&quot; id=&quot;tab03&quot; role=&quot;tab&quot; aria-selected=&quot;false&quot; aria-controls=&quot;tabpanel03&quot;&gt;정보3&lt;/a&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;wrap-tab-contents&quot;&gt;
  &lt;div id=&quot;tabpanel01&quot; class=&quot;tab-contents&quot; role=&quot;tabpanel&quot; aria-labelledby=&quot;tab01&quot; tabindex=&quot;0&quot;&gt;
    &lt;p&gt;정보1 콘텐츠&lt;/p&gt;
  &lt;/div&gt;
  &lt;div id=&quot;tabpanel01&quot; class=&quot;tab-contents&quot; role=&quot;tabpanel&quot; aria-labelledby=&quot;tab02&quot; tabindex=&quot;0&quot; hidden=&quot;true&quot;&gt;
    &lt;p&gt;정보2콘텐츠&lt;/p&gt;
  &lt;/div&gt;
  &lt;div id=&quot;tabpanel01&quot; class=&quot;tab-contents&quot; role=&quot;tabpanel&quot; aria-labelledby=&quot;tab03&quot; tabindex=&quot;0&quot; hidden=&quot;true&quot;&gt;
    &lt;p&gt;정보3 콘텐츠&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre><p>위 코드를 NVDA(NonVisual Desktop Access)라는 스크린 리더기 프로그램으로 들어보면 의미가 다르게 전달되는 것을 알 수 있는데, </p>
<p>결과</p>
<p>탭 메뉴 WAI-ARIA 적용 전</p>
<ul>
<li>불릿 [링크] 정보1</li>
<li>불릿 [링크] 정보2</li>
<li>불릿 [링크] 정보3
페이지를 이동하는 링크 태그로, 의미만을 정보정달해준다.</li>
</ul>
<p>탭 메뉴 WAI-ARIA 적용 후</p>
<ul>
<li>불릿 [탭] 정보1</li>
<li>불릿 [탭] 정보2</li>
<li>불릿 [탭] 정보3
버튼의 역할이 탭이라고 명시해주고 선택된 요소 정보도 함께 전달해줄 수 있다.</li>
</ul>
<ol start="2">
<li>속성(Property) 컴포넌트의 특징이나 상황을 정의</li>
</ol>
<p>시각 정보를 이용할 수 없는 사용자는 만약 검색이라는 안내 텍스트 없이 버튼을 나타낼 때 어떤 버튼인지 알 수가 없다.</p>
<blockquote>
<ul>
<li>폼요소의 필수 요소와 관련된 aria-required</li>
<li>텍스트 레이블 없이 이미지로 표현될 때 정보를 부여하여 설명해주는 aria-label</li>
<li>업데이트된 정보의 상황 aria-live</li>
</ul>
</blockquote>
<p>예를 들어 &#39;검색&#39; 이라는 아이콘을 안내 텍스트 없이 나타낸다면, 시각 정보를 이용할 수 없는 사용자는 어떤 버튼인지 알 수 없다.</p>
<p>대체텍스트를 이용할 수 있지만, aria-label을 이용하여 버튼 요서에 검색이라느 설명을 추가 할 수 있다.</p>
<pre><code>&lt;button class=&quot;btn_search&quot;&gt;&lt;/button&gt;

&lt;!-- 숨김 텍스트 이용 --&gt;
&lt;button class=&quot;btn_search&quot;&gt;
  &lt;span class=&quot;hidden&quot;&gt;검색&lt;/span&gt;
&lt;/button&gt;
&lt;!-- WAI-ARIA 적용 --&gt;
&lt;button class=&quot;btn_search&quot; aria-label=&quot;검색&quot;&gt;&lt;/button&gt;</code></pre><ol start="3">
<li>상태(State) 컴포넌트의 상태 정보를 정의</li>
</ol>
<ul>
<li>메뉴의 활성 여부를 알려주는 <code>aria-expanded</code>, <code>aria-selected</code></li>
<li>폼 요소 유효성 검증과 관련 있는 <code>aria-invalid</code> 
텍스트를 노출함으로 사용성을 높여줄 수 있다.</li>
<li>상태가 변화 될때 확장됨/축소됨/눌림/눌리지않음 의 상태값을 음성으로 알려주며
aria-invalid 상태에 따라 에러 텍스트를 노출시킴으로 사용성을 높여줄 수 있다.</li>
</ul>
<pre><code>&lt;ul class=&quot;btnList&quot;&gt;
  &lt;li&gt;
    &lt;button id=&quot;accordion01&quot; aria-controls=&quot;accordion-region01&quot;
    aria-expanded=&quot;true&quot; &gt;munju_dev&lt;/button&gt;

    &lt;div id=&quot;accordion-region01&quot; role=&quot;region&quot; aria-labelledby=&quot;accordion01&quot;&gt;munju_dev&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;button id=&quot;accordion02&quot; aria-controls=&quot;accordion-region02&quot;&gt;
    UX Engineer&lt;/button&gt;
    &lt;div id=&quot;accordion-region02&quot; role=&quot;region&quot; aria-labelledby=&quot;accordion02&quot;&gt;UX Engineer&lt;/div&gt;
  &lt;/li&gt;

&lt;/ul&gt;

&lt;style&gt;
  li {
    background-image: url(arrow_down.png);
  }
  li button[aria-expanded=&#39;true&#39;] {
    background-image: url(arrow_up.png);
  }
&lt;/style&gt;
</code></pre><p>웹접근성을 준수해서 코드를 작성하기 위해서는 앞으로 더 많이 웹접근성 지침 가이드나 규칙을 
알아야겠다고 느꼈다. </p>
<p>추후에 계속 학습된 내용을 포스팅하도록 하겠다.</p>
<blockquote>
<p>참고한곳
<a href="https://www.biew.co.kr/entry/WAI-ARIA-%EC%9B%B9%ED%8D%BC%EB%B8%94%EB%A6%AC%EC%8B%B1">https://www.biew.co.kr/entry/WAI-ARIA-%EC%9B%B9%ED%8D%BC%EB%B8%94%EB%A6%AC%EC%8B%B1</a>,
<a href="https://y00eunji.tistory.com/entry/HTML-WAI-ARIA-aria-hidden#article-1--%EC%82%AC%EC%9A%A9-%EC%9D%B4%EC%9C%A0">https://y00eunji.tistory.com/entry/HTML-WAI-ARIA-aria-hidden#article-1--%EC%82%AC%EC%9A%A9-%EC%9D%B4%EC%9C%A0</a>,
<a href="https://story.pxd.co.kr/1588">https://story.pxd.co.kr/1588</a>, 
<a href="https://nuli.navercorp.com/community/article/1132879">https://nuli.navercorp.com/community/article/1132879</a>,
<a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques">https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques</a>
이미지출처: <a href="https://story.pxd.co.kr/1588">https://story.pxd.co.kr/1588</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] IR 기법(Image Replacement)]]></title>
            <link>https://velog.io/@munju_dev/CSS-IR-%EA%B8%B0%EB%B2%95Image-Replacement</link>
            <guid>https://velog.io/@munju_dev/CSS-IR-%EA%B8%B0%EB%B2%95Image-Replacement</guid>
            <pubDate>Thu, 13 Apr 2023 09:59:21 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 포스팅은 <a href="https://uxkm.io/publishing/css/03-cssMiddleclass/05-css_ir#gsc.tab=0">css 중급</a>, <a href="https://nuli.navercorp.com/community/article/1132804?email=true">스크린리더 사용자를 위한 기법과 추가 설명 제공하기</a> 사이트를 참고하여 작성하였습니다.</p>
</blockquote>
<p>IR(Image Replacement) 기법은 이미지 대체텍스트 제공을 위한 CSS 기법으로
다양한 CSS기법을 사용하여 이미지의 대체텍스트를 제공할 수가 있다.</p>
<p>의미가 포함되어 있는 image를 배경으로 표현하고, 그에 상응하는 내용을 text로 전경에 기입하는 방법으로,</p>
<p>시각이 있는 사용자는 이미지로 처리된 화면을 볼 수 있지만 &quot;화면 낭독기를 사용하는 시각 장애인, CSS제거 및 인쇄&quot;시에는 문자에 접근하거나 문자를 볼 수 있는 형태로 설계 하는 기법을 말한다.</p>
<h2 id="1-스프라이트-이미지를-이용한-ir-기법">1. 스프라이트 이미지를 이용한 IR 기법</h2>
<p>지난번 포스팅하면서 배운 이미지스프라이트와 함께 사용을 많이 한다.
이미지 스프라이트 기법은 css의 background-position 속성으로 제어하는데,</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;이미지 스프라이트 기법 사용하기&lt;/title&gt;
    &lt;/head&gt;
    &lt;style&gt;
        a { display: inline-block; }
        a::after {

            content: &quot;&quot;;
            display: block;
            width: 28px;
            height: 28px;
            background-image: url(./css_sprites.png);
        }

        .css::after {
            width: 120px; height: 170px;
            background: url(&#39;css_sprites.png&#39;) -10px -10px;
        }

        .js::after {
            width: 120px; height: 170px;
            background: url(&#39;css_sprites.png&#39;) -290px -10px;
        }

        .html::after {
            width: 120px; height: 170px;
            background: url(&#39;css_sprites.png&#39;) -150px -10px;
        }
    &lt;/style&gt;


    &lt;body&gt;
        &lt;a href=&quot;#&quot; class=&quot;css&quot;&gt;CSS&lt;/a&gt;
        &lt;a href=&quot;#&quot; class=&quot;js&quot;&gt;JS&lt;/a&gt;
        &lt;a href=&quot;#&quot; class=&quot;html&quot;&gt;HTML&lt;/a&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/45ffee81-56b8-438d-b267-d295e5cca99c/image.png" alt=""></p>
<p>이미지 스프라이트 포스팅에서 봤던것과 같이 background-position 속성으로 이미지의 위치값을 설정하여 이미지의 일부만 표시하게 할 수 있다. </p>
<h2 id="2-text-indent">2. text-indent</h2>
<p>css 에서 text-indent는 IR기법을 가장 손쉽게 사용할 수 있는 방법이자, 
Phark Method 권장사항으로 이미지로 대체할 요소에 배경이미지를 설정하고, 
글자는 <code>text-indent</code>를 이용하여 화면 바깥으로 보이지 않게 하는 방법이다.
(-9999px만큼)</p>
<ul>
<li>스크린 리더기 읽어줌</li>
<li>추가적인 요소를 사용 안함</li>
</ul>
<p>사용하기 간편하지만 사용자의 디바이스에 따라 이미지가 제대로 로드 되지 않았을때
스크린리더 사용자가 아니라 하더라도 이미지를 설명하는 텍스트를 보고 콘텐츠 내용을 
확인해야하는 단범이 있으며, 웹페이지 로드 시 위치값을 계산해야하기 때문에 성능저하를 
불러올 수 있다.</p>
<p>Daum CSS Convention 에서 명시한 방법을 살펴보겠다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
  &lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
      &lt;meta charset=&quot;UTF-8&quot;&gt;
      &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
      &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
      &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;

  &lt;button type=&quot;button&quot;&gt;검색&lt;/button&gt;
  &lt;a href=&quot;#&quot;&gt;검색&lt;/a&gt;

  &lt;style&gt;
    button {
      display:block; width:49px; height:36px; margin:0; padding:0;
      text-indent:-9999px; /* 들여쓰기를 -9999px만큼 지정하여 글자를 버튼 밖으로 숨김 처리 , overflow:hidden을 통해 밖으로 내보낸것 히든처리 */
      background:url(&#39;btn_search.gif&#39;) no-repeat;
      border:none;
    }
    a {
      display:block; overflow:hidden; float:left; width:49px; height:36px;
      text-indent:-9999px; /* 들여쓰기를 -9999px만큼 지정하여 글자를 버튼 밖으로 숨김 처리 
, overflow:hidden을 통해 밖으로 내보낸것 히든처리*/
      background:url(&#39;btn_search.gif&#39;) no-repeat;
    }
  &lt;/style&gt;


  &lt;/body&gt;
&lt;/html&gt;</code></pre><h2 id="3-position-relative-z-index--1">3. position: relative, z-index: -1</h2>
<p><a href="http://www.wa.or.kr/m1/sub1.asp">WA IR 권장</a></p>
<p>해당 기법을 사용할 경우, 스크린 리더기가 읽을 수 있다.
이미지로 대체할 요소에 배경이미지로 설정 한 후 글자는 <code>&lt;span&gt;</code> 으로 감싸고, 
<code>position:relative</code>,<code>z-index:-1</code>을 이용하여 (음수 값) 안보이게 처리한다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;Document&lt;/title&gt;
    &lt;/head&gt;
    &lt;style&gt;
        button {
            width:71px; height:71px; margin:0; padding:0;
            background:url(./ico02.png)  no-repeat;
            border:none;
        }
        a {
            display:block; width:49px; height:36px;
            text-decoration:none;
            background:url(./ico02.png) no-repeat;
        }
        span {
            position:relative; z-index:-1;
        }
    &lt;/style&gt;

    &lt;body&gt;

        &lt;button type=&quot;button&quot;&gt;&lt;span&gt;검색&lt;/span&gt;&lt;/button&gt;
        &lt;a href=&quot;#&quot;&gt;&lt;span&gt;검색&lt;/span&gt;&lt;/a&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/cc1727cc-d750-4cc5-a8e2-e8583996aae9/image.png" alt=""></p>
<p>아이콘 뒤에는 대체 텍스트인 검색 이란 글자가 z-index 설정으로 가려져 있는 것을 알 수 있다.</p>
<h2 id="4-width0-height-0">4. width:0; height: 0;</h2>
<p>이 방법은 대체 텍스트 글자가 들어가는 등의 요소의 <code>width</code> 와 <code>height</code> 값을 0으로 지정하는 방법이다. 대체할 텍스트 요소에 BackGround 이미지를 설정한 다음 대체 텍스트가 포함되는 요소의 높이와 너비를 0으로 지정하여 글자를 숨길 수 있다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;Document&lt;/title&gt;
    &lt;/head&gt;
    &lt;style&gt;
        button {
          width:71px; height:71px; margin:0; padding:0;
          background:url(&#39;./ico02.png&#39;) no-repeat;
          border:none;
        }
        a {
          display:block; width:71px; height:71px;
          text-decoration:none;
          background:url(&#39;./ico02.png&#39;) no-repeat;
        }
        span {
          display:block; overflow:hidden;
          width:0; height:0;
        }
      &lt;/style&gt;

    &lt;body&gt;
        &lt;button type=&quot;button&quot;&gt;&lt;span&gt;버튼&lt;/span&gt;&lt;/button&gt;
        &lt;a href=&quot;#&quot;&gt;&lt;span&gt;a태그&lt;/span&gt;&lt;/a&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/f7006a82-dfe6-4e5c-90b6-64e2bd387c4d/image.png" alt=""></p>
<p>+추가 내용을 다시 기록하도록 하겠다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] 박스 크기 설정 box-sizing: border-box , content-box]]></title>
            <link>https://velog.io/@munju_dev/CSS-%EB%B0%95%EC%8A%A4-%ED%81%AC%EA%B8%B0-%EC%84%A4%EC%A0%95-box-sizing-border-box-content-box</link>
            <guid>https://velog.io/@munju_dev/CSS-%EB%B0%95%EC%8A%A4-%ED%81%AC%EA%B8%B0-%EC%84%A4%EC%A0%95-box-sizing-border-box-content-box</guid>
            <pubDate>Wed, 12 Apr 2023 09:49:14 GMT</pubDate>
            <description><![CDATA[<h2 id="css-box-model">CSS Box Model</h2>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/d627ba47-f7a7-4014-88a4-2a0a47c41ebf/image.png" alt=""></p>
<p>개발자 도구에서 css 적용된 것을 보면 박스 모델에 대해 쉽게 접할 수 있다.</p>
<ul>
<li>content : 글씨가 삽입되는 영역</li>
<li>border : 테두리 영역</li>
<li>padding : content와 border 사이</li>
<li>margin : border와 다른 태그 영역 사이</li>
</ul>
<h2 id="css-box-sizing-속성">CSS box-sizing 속성</h2>
<p>박스의 크기를 설정할 때 높이를 지정할 경우도 생기고, 내가 지정하고 싶은 영역의 높이나 너비가
이미 패딩이나 마진, 보더로 인해 넘어가는 경우도 발생한다.</p>
<p>이럴때 css box-sizing 속성을 사용하면 요소의 너비와 높이를 균일하게 유지하도록 해준다.
즉 box-sizing 속성은 CSS의 테두리 영역의 크기를 결정한다.</p>
<blockquote>
<p>box-sixing : 속성값</p>
</blockquote>
<h2 id="content-box">content-box</h2>
<p>지정한 CSS width와 height를 컨텐츠 영역에만 적용한다. padding, border, margin은 
너비와 높이에 포함되지 않고, 따로 계산 되어 전체 영역이 설정값에 더해지기 때문에 커질 수 있다. </p>
<p>css의 기본 설정값은 <strong>content-box</strong>로 초기 설정에서 width와 height를 설정하면 레이아웃이 원하는 결과대로 나오지 않을 수 있다. 따라서 원하는 widht와 height로 지정해주길 원한다면
border-box로 지정해 주어야한다.</p>
<blockquote>
<p>전체크기 : content-box + border + padding + margin
컨텐츠크기 : content-box</p>
</blockquote>
<pre><code>&lt;html&gt;
  &lt;head&gt;
    &lt;style&gt;
      div {
        border : 5px black solid;
        width : 100px;
        height : 100px;        
        box-sizing:content-box;
      }
    &lt;/style&gt;
  &lt;body&gt;
    &lt;div&gt;content-box&lt;/div&gt;
  &lt;/body&gt;
  &lt;/head&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/b5ed9f4e-e616-493a-aa3f-a886f4b09941/image.png" alt=""></p>
<p>스타일시트에선 width와 height의 값을 100px로 지정해주었지만
border때문에 110px씩 잡힌것을 볼 수 있다.</p>
<h2 id="border-box">border-box</h2>
<p>border-box 의 경우에는 전체 요소의 크기가 width값으로 적용된다.
따라서 요소의 padding, margin, border가 width를 늘릴 수는 없다.</p>
<blockquote>
<p>전체 크기 = border-box = content + border + padding + margin
컨텐츠 크기 = border-box – border – padding – margin</p>
</blockquote>
<pre><code>&lt;html&gt;
  &lt;head&gt;
    &lt;style&gt;
      div {
        border : 5px black solid;
        width : 100px;
        height : 100px;        
        box-sizing:border-box;
      }
    &lt;/style&gt;
  &lt;body&gt;
    &lt;div&gt;content-box&lt;/div&gt;
  &lt;/body&gt;
  &lt;/head&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/ad113007-1a64-46fd-98dc-51089da2f408/image.png" alt=""></p>
<p>border-box 속성값은 지정한 width와 height의 크기가 모든 box-model의 합계로 지정되기 때문에, border-box를 설정하였을 경우 css 에서 지정한 width와 height의 값인 100px씩 적용된것을 알 수 있다. 대신 컨텐츠 영역이 자동으로 padding, margin, border의 크기만큼 줄어들기 때문에 지정할때 유념하여야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTML] title과 alt 속성]]></title>
            <link>https://velog.io/@munju_dev/HTML-title%EA%B3%BC-alt-%EC%86%8D%EC%84%B1</link>
            <guid>https://velog.io/@munju_dev/HTML-title%EA%B3%BC-alt-%EC%86%8D%EC%84%B1</guid>
            <pubDate>Wed, 12 Apr 2023 08:32:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참조 문서
<a href="https://developer.mozilla.org/ko/docs/Web/HTML/Global_attributes/title">https://developer.mozilla.org/ko/docs/Web/HTML/Global_attributes/title</a>
<a href="https://bbaksae.tistory.com/25">https://bbaksae.tistory.com/25</a>
<a href="https://nuli.navercorp.com/community/article/1132934">https://nuli.navercorp.com/community/article/1132934</a>
<a href="https://blog.hivelab.co.kr/%EA%B3%B5%EC%9C%A0-title-%EC%86%8D%EC%84%B1%EC%9D%98-%EB%B0%94%EB%9E%8C%EC%A7%81%ED%95%9C-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95/">https://blog.hivelab.co.kr/%EA%B3%B5%EC%9C%A0-title-%EC%86%8D%EC%84%B1%EC%9D%98-%EB%B0%94%EB%9E%8C%EC%A7%81%ED%95%9C-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95/</a></p>
</blockquote>
<p>오늘은 title 속성은 어느 때에 사용하고, 어떤 식으로 사용하는 것이 바람직한지
알아보도록 하겠다.</p>
<h2 id="title-속성">title 속성</h2>
<p>title 속성은 엘리먼트에 대한 정보를 나타내주는 툴팁(tooltip) 기능을 가지고 있다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;title 속성&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;a href=&quot;#&quot; title=&quot;link text&quot;&gt;Deep link with title&lt;/a&gt;        

    &lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/c17e1d20-322d-4249-be79-8463226de89a/image.png" alt=""></p>
<blockquote>
<ul>
<li>title 속성값은 위의 예시처럼 마우스를 올리면 툴팁으로 
title 속성에 적힌 문자 정보가 태그 위에 표시된다.</li>
</ul>
</blockquote>
<ul>
<li>요소에서 title 속성이 생략된다면, 가장 가까운 부모 요소의 title 속성이 암시적으로
적용될 수 있다. 따라서 부모요소와 무관한 것임을 알려주기 위해서는 명시적으로 
title 속성을 제공해야한다.</li>
<li>빈 문자열을 설정한다면 title 이 보조 정보를 갖고 있지 않음을 의미한다.</li>
<li>title 속성은 개행문자를 처리하기 때문에 줄바꿈에 유의하여야한다.</li>
</ul>
<h3 id="title에-빈문자열을-지정할-경우">title에 빈문자열을 지정할 경우</h3>
<pre><code>&lt;div title=&quot;CoolTip&quot;&gt;
  &lt;p&gt;여기 어디에 마우스를 올리면 “CoolTip”이 나타납니다.&lt;/p&gt;
  &lt;p title=&quot;&quot;&gt;하지만 여기에서는 나타나지 않습니다.&lt;/p&gt;
&lt;/div&gt;</code></pre><p>-&gt; title에 빈 문자열을 지정한 경우 title이 더이상 관련되지 않으며, 해당 요소에는 툴팁을 표시하지 않는다.</p>
<h3 id="title은-여러줄을-가질-수-있다">title은 여러줄을 가질 수 있다.</h3>
<p>툴팁이 두 줄로 나타날 수 있으므로 주의를 요한다.</p>
<pre><code>&lt;p&gt;&lt;code&gt;title&lt;/code&gt; 안에서 줄을 바꿀 땐 조심해야 합니다.
이 &lt;abbr title=&quot;This is a
multiline title&quot;&gt;예제&lt;/abbr&gt;처럼요.&lt;/p&gt;</code></pre><p>abbr 요소는 준말 또는 머리글자를 나타내는데, 이때 선택 속성인 title을 사용하면
준말의 전체 뜻이나 설명을 제공할 수 있다. title 속성은 전체 설명만 가져야하며
다른건 포함시킬 수 없다.</p>
<h2 id="title-속성의-사용방법">title 속성의 사용방법</h2>
<ol>
<li>a 요소 : 대상의 제목이나 설명을 나타낼때 사용한다.</li>
</ol>
<pre><code>&lt;a href=&quot;https://www.naver.com/&quot; title=&quot;네이버 홈페이지&quot;&gt;https://www.naver.com/&lt;/a&gt;</code></pre><ol start="2">
<li>img 요소 : 이미지의 설명이나 크레딧을 나타낸다.</li>
</ol>
<pre><code>&lt;img src=&quot;img/lawyer.png&quot; alt=&quot;대표 변호사&quot; title=&quot;변호사&quot;&gt;</code></pre><ol start="3">
<li>input 요소 : input 요소에 label을 제공하지 못하였을때 대신 사용한다.
(단, label 태그는 ui 항목에 대한 설명을 나타내기 때문에, 태그 특성상 텍스트로
설명이 가능하기 때문에 title 속성을 써줄 필요가 없다.)</li>
</ol>
<pre><code>&lt;input type=&quot;text&quot; title=&quot;전화번호&quot;&gt;</code></pre><ol start="4">
<li>iframe : 프레임이 지원되지 않는 경우에는 iframe 요소의 내용이 그대로 표시될 수 있으므로 지원되지 않는 환경까지 고려하여 대체 텍스트를 넣어주어야한다. 요소에 담긴 콘텐츠를 잘 나타낼 수 있는 내용으로 지정한다.</li>
</ol>
<pre><code>&lt;iframe src=&quot;ad_banner.html&quot; name=&quot;ad&quot; frameborder=&quot;0&quot; 
width=&quot;350&quot; height=&quot;50&quot; scrolling=&quot;no&quot; title=&quot;배너 광고&quot;&gt;
 &lt;p&gt;프레임이 표시되지 않는 분은 
  &lt;a href=&quot; ad_banner.html&quot;&gt;배너 광고 바로가기&lt;/a&gt;를 클릭해 주세요.&lt;/p&gt;
&lt;/iframe&gt; </code></pre><p>이외 <code>&lt;span&gt;</code>, <code>&lt;td&gt;</code>, <code>&lt;input&gt;</code> 등에도 쓰인다.</p>
<h2 id="alt-속성">alt 속성</h2>
<h3 id="altalternative--이미지의-대안이나-이미지에-대한-설명">alt(alternative) : 이미지의 대안이나 이미지에 대한 설명</h3>
<pre><code>&lt;img src=&quot;img/apple.png&quot; alt=&quot;사과&quot;&gt;</code></pre><p>인터넷 속도, 또는 컴퓨터 사양 문제로 웹브라우저 설정을 &#39;이미지 출력 안 함&#39;으로 한 사용자에게 이미지에 대한 간략한 설명을 볼 수 있다. (데스크탑이 아닌 모바일기기로 접속시에도 유용함.)</p>
<p>시각장애인의 웹서핑시 사용하는 리더(reader) 프로그램이 텍스트는 읽어주지만, 이미지는 읽을 수 없기때문에, alt 의 설명을 읽어준다.</p>
<p>웹서핑시 인터넷 접속 등의 문제로 해당 이미지를 불러오지 못했을 때, 해당 이미지 설명을 보여주기때문에 대략적으로 이미지에 대한 정보를 알 수 있다.</p>
<h2 id="접근성과-사용성-측면">접근성과 사용성 측면</h2>
<p>타이틀 텍스트는 마우스를 오버했을 때 나타난다고 하였다. 그렇다면, 
각 요소마다 사용자가 마우스 오버를 하지 않는 이상 
타이틀 텍스트가 있는지 알수 없다. 또한 1초 이상 마우스 오버 후 기다려야 
표시 되기 때문에 빠르기 웹페이지를 탐색하는 부분에서는 그리 효과적이지 않다.</p>
<p>title 속성은 요소에 대한 부가적인 정보를 나타내며, 툴팁으로 사용되기에 적절하다.
하지만 title 속성은 스크린리더기에서 읽히지 않은 경우도 고려했을 때,
모든 사용자를 고려하는 마크업을 하기 위해선 <strong>대체 텍스트나 숨김 텍스트</strong>를 우선으로
사용하는 것이 적절하겠다.</p>
<blockquote>
<p>터치스크린 디바이스의 경우
: 특정요소를 탭하는 동작을 취했을때 요소가 바로 실행되기 때문에
마우스 오버 기능을 사용할 수 없다. 모바일 웹이 아닌 PC 웹을 많이 사용하므로, 
문제가 생길 수 있다.</p>
</blockquote>
<blockquote>
<p>저시력 사용자의 경우 화면을 크게 확대할 수 있다. 
: 마우스 오버를 할때 표시되는 타이틀 텍스트 또한 확대할 경우 일부만 표시 될 수 있는데,
다른 영역을 보기 위해 마우스를 옮기면 타이틀이 사라진다.
즉 확대 프로그램 사용자는 타이틀 텍스트 전체를 보기에는 부적합하다.
이미지에 대한 필수 정보를 타이틀 텍스트로 제공한 경우에는 더더욱 그렇다.</p>
</blockquote>
<blockquote>
<p>스크린리더 사용자 외에도 마우스를 사용하기 어려운 사용자일 경우에는
키보드 탭 키 등을 통해 웹페이지를 탐색하는데, 
이때 타이틀 텍스트를 키보드 탐색 시에도 표시하게 하려면 JS 또는 CSS를 사용하여
브라우저에서 지원할 수 있도록 해야한다.</p>
</blockquote>
<h3 id="결론">결론</h3>
<p>W3C 스펙에 정의된 내용과 각 웹 콘텐츠 접근성 지침들의 내용들을 종합한 결론으로 보자면,</p>
<ol>
<li><p>title 요소가 있는 부분을 선택자로 지정한 후 해당 요소에 포커스 하였을 때
타이틀 텍스트를 표시하는것이 적절하겠다. (브라우저에서 키보드 탐색 시 타이틀 텍스트 지원X)</p>
</li>
<li><p>title 속성과 alt 속성의 값이 동일하게 제공될 경우에는 과도한 정보제공이 
될 수 있기 때문에 주의 하여야한다.</p>
</li>
<li><p>필요한 경우에 사용
<code>&lt;iframe&gt;</code> 요소에 제목을 제공해야할 때에는 title 속성을 사용하여 정보를 제공하고, 
<code>&lt;label&gt;</code> 요소를 ui상 추가하기 어려운 상황에는 title 속성을 사용하는 것이
웹 접근성 측면에서 바람직하다고 볼 수 있겠다.</p>
</li>
</ol>
<p>*2023.04.13 추가내용
-링크에 적용된 title 속성값은 센스리더를 제외한 다른 스크린리더들은 읽지 못하기 때문에 스크린리더 사용자에게 별도의 추가 설명이 제공되는 컨트롤을 사용할 때는 ARIA-label을 사용해야만 모든 스크린리더에서 컨트롤명과 추가 정보를 읽을 수 있다.</p>
<pre><code> &lt;a href=&quot;https://www.naver.com/&quot; ARIA-label=&quot;네이버 - 새 창이 열립니다&quot;&gt;네이버&lt;/a&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] 이미지 스프라이트 기법]]></title>
            <link>https://velog.io/@munju_dev/CSS-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%8A%A4%ED%94%84%EB%9D%BC%EC%9D%B4%ED%8A%B8-%EA%B8%B0%EB%B2%95</link>
            <guid>https://velog.io/@munju_dev/CSS-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%8A%A4%ED%94%84%EB%9D%BC%EC%9D%B4%ED%8A%B8-%EA%B8%B0%EB%B2%95</guid>
            <pubDate>Tue, 11 Apr 2023 08:16:20 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 포스팅은 <a href="https://velog.io/@untiring_dev/HTMLCSS-Day31.-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%8A%A4%ED%94%84%EB%9D%BC%EC%9D%B4%ED%8A%B8-%EA%B8%B0%EB%B2%95">[HTML/CSS] 이미지 스프라이트 기법 ✂️</a>, <a href="https://velog.io/@mooongs/CSS-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%8A%A4%ED%94%84%EB%9D%BC%EC%9D%B4%ED%8A%B8-%EA%B8%B0%EB%B2%95">[CSS] 이미지 스프라이트 기법</a> 을 참고하여 게시하였습니다. 도움이 되어 감사합니다.</p>
</blockquote>
<h2 id="이미지-스프라이트image-sprite란-🔎">이미지 스프라이트(Image Sprite)란 🔎?</h2>
<p>스프라이트(Sprite)란 컴퓨터 그래픽스에서 작은 2차원 비트맵이나 애니메이션을 합성하는
기술을 의미하는데, 웹의 경우에는 여러개의 이미지를 하나의 이미지로 만들어 놓는것을 의미한다고 한다.
즉 여러 개의 배경 이미지를 하나의 파일로 제작한 후 background-position 속성을 이용하여 이미지를 배치하는 방법이다.</p>
<p>쉽게 말하면 각각의 이미지를 개별적으로 다운받는 것이 아닌, 하나의 파일만 업로드하여 필요 부분만 개별적으로 사용하는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/5c318425-db12-4572-b506-01438735be40/image.png" alt=""></p>
<p>👆 네이버에 메인페이지에서는 스프라이트 기법을 이용해서 아이콘이나 이미지들을 활용하는데에 쓰이고 있는 것을 알 수 있다.</p>
<h2 id="이미지-스프라이트-사용법-🤔">이미지 스프라이트 사용법? 🤔</h2>
<p>이미지 스프라이트는 img 태그를 사용해서 이미지를 삽입하는 것이 아닌 CSS의 background 속성을 이용하여 삽입한다. 그런데, 스프라이트 기법이 적용된 이미지를 일일이 붙여서 만들면
시간 소요가 생각보다 될 것이다. 오차가 발생할 수도 있고 이미지 적용이 생각보다 위치 잡는 데에 번거로울 수 있기 때문에 만들어주는 사이트를 사용하는것이 유용하다.</p>
<p>아래 링크는 CSS Sprites Generator라는 프로그램이다. 
사용할 이미지들을 넣어주면 자동으로 스프라이트 이미지를 생성해준다.</p>
<p><a href="https://www.toptal.com/developers/css/sprite-generator/">https://www.toptal.com/developers/css/sprite-generator/</a></p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/57147cd1-7f6c-4f69-945f-c50cf10244b3/image.png" alt=""></p>
<p>원하는 아이콘, 이미지의 위치값까지 (background-position) 복붙해서 사용하니 편리하다.
<img src="https://velog.velcdn.com/images/munju_dev/post/4e0970ff-8ef0-4d43-99ac-0b2bd254af9a/image.png" alt=""></p>
<p><strong>스프라이트 기법을 사용하기 위해서는 필수적으로 작성해줘야할것들</strong></p>
<p>width, height : 삽입할 이미지의 크기를 결정한다.
background-image : 삽입할 이미지의 경로를 설정한다.
background-position : 이미지에서 사용할 이미지의 위치를 설정한다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;Document&lt;/title&gt;
    &lt;/head&gt;
    &lt;style&gt;
        a::after {
            content: &quot;&quot;;
            display: block;
            width: 28px;
            height: 28px;
            background-image: url(./css_sprites.png);
        }

        .css::after {
            width: 120px; height: 170px;
            background: url(&#39;css_sprites.png&#39;) -10px -10px;
        }

        .js::after {
            width: 120px; height: 170px;
            background: url(&#39;css_sprites.png&#39;) -290px -10px;
        }

        .html::after {
            width: 120px; height: 170px;
            background: url(&#39;css_sprites.png&#39;) -150px -10px;
        }
    &lt;/style&gt;


    &lt;body&gt;
        &lt;a href=&quot;#&quot; class=&quot;css&quot;&gt;CSS&lt;/a&gt;
        &lt;a href=&quot;#&quot; class=&quot;js&quot;&gt;JS&lt;/a&gt;
        &lt;a href=&quot;#&quot; class=&quot;html&quot;&gt;HTML&lt;/a&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><p>스프라이트된 이미지를 background-image를 통해 ::after에 적용하고,
background-position을 통해 위치를 잡아주었다.</p>
<p>브라우저에는 아래와 같이 적용된 모습을 볼 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/c266fe55-dba6-4949-9742-e00430d49e87/image.png" alt=""></p>
<h2 id="이미지-스프라이트-기법의-장점">이미지 스프라이트 기법의 장점</h2>
<h3 id="1-이미지-로딩-속도-향상최적화된다">1. 이미지 로딩 속도 향상(최적화)된다.</h3>
<p>일반적으로 이미지태그를 이용해 하나씩 삽입할때보다
브라우저의 로딩 속도가 향상된다.
각각의 이미지를 가져오는것에 비해 스프라이트 이미지를 하나만 받아야하는
브라우저의 입장에서는 스프라이트 이미지 한장을 불러오는것이 더 빠를 수 밖에 없다.</p>
<h3 id="2-html-마크업이-간결해지고-스크린-리더의-탐색-속도가-향상된다">2. html 마크업이 간결해지고 스크린 리더의 탐색 속도가 향상된다.</h3>
<p>css로 작업하지 않고 일일이 html img 태그에 적용을 시킨다면, 텍스트 양도 늘어나고, 
img 태그로 인해 스크린 리더가 하나씩 읽게 될 것이다.
이미지 스프라이트 기법을 통해 이미지를 background 속성으로 적용하게 된다면
스크린리더가 읽을 필요가 없는 &#39;배경이미지&#39;로 인식하게 되어 탐색 속도가 빨라지게 될 수 있다.
(css 로 조절되기 때문에 alt 속성을 지정해 줄 수 없다.)
따라서 이미지 스프라이트 기법은 되도록 의미가 없고 디자인을 목적으로 하는 이미지를 위해 사용하는것이 적합하다.</p>
<h3 id="3-하나의-파일만-관리하면-된다">3. 하나의 파일만 관리하면 된다.</h3>
<p>이미지 스프라이트 기법은 여러 이미지를 관리하는 것보다 하나의 이미지를 관리하기 때문에 간편하다. 하지만 관련된 이미지들로만 묶어 합쳐 놓는 것이 좋다. 
여러 이미지로 혼합하여 묶을 시에는 
여러개의 이미지를 하나의 이미지 파일에 관리하는 것이기 때문에 
번거로움이 그대로 유지 될수 있기 때문이다.</p>
<h2 id="이미지-스프라이트-기법의-단점">이미지 스프라이트 기법의 단점</h2>
<h3 id="1-유지-보수-어려움">1. 유지 보수 어려움</h3>
<p>장점에서는 파일관리가 쉽기 때문에 유지보수가 잘될 수 있다고 하였지만, 
만약 웹페이지가 업데이트, 리뉴얼 됨에 따라 이미지가 추가 된다고 하면, 
스프라이트 이미지를 다시 제작 해야한다.</p>
<p>이미 만들어진 이미지는 각각의 포지션 값이 정해져있기 때문에, 이미지 파일을 바꾸면
이전에 적용되었던 위치값들이 변경되기 때문에 전부 바꿔줘야하는 어려움이 발생한다.</p>
<p>만약 이미지가 수정이 빈번한 이미지라면 개별적인 이미지 파일로 관리하는것이 적합하겠다.</p>
<h3 id="2-데이터-관리에-문제가-생길경우-이미지-로딩이-불가능">2. 데이터 관리에 문제가 생길경우 이미지 로딩이 불가능</h3>
<p>여러 개의 이미지 파일을 이용하여 각각의 이미지를 삽입했을 때에는
하나의 이미지가 문제가 발생한다면 문제가 생긴 하나의 이미지 파일만 수정을 하면 된다.</p>
<p>하지만 스프라이트 이미지는 여러개의 이미지가 합쳐져 있기 때문에 스프라이트기법을 적용한 이미지 파일에 문제가 생긴다면 이미지를 볼 수 없는 상황이 발생한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] Display:none / Overflow:hidden]]></title>
            <link>https://velog.io/@munju_dev/CSS-displaynone-Overflowhidden</link>
            <guid>https://velog.io/@munju_dev/CSS-displaynone-Overflowhidden</guid>
            <pubDate>Tue, 11 Apr 2023 07:20:53 GMT</pubDate>
            <description><![CDATA[<p>display: none 과 overflow: hidden 의 차이점에 대해 알아보겠다.
사실 깊이 생각한 적이 없었는데, 이번 기회를 통해 알아보면서 웹접근성에 대해서도
한번 더 숙지 하게 되었다.</p>
<blockquote>
<p>이 포스팅은 <a href="https://velog.io/@fenjo/CSS-overflowhidden%EA%B3%BC-displaynone">fenjo.log</a>, <a href="https://velog.io/@untiring_dev/HTMLCSS-Day11.-Displaynone-VS-Overflowhidden">untiring_dev.log</a> 게시물을 참고 하여 작성하였습니다. 도움이 되어 감사합니다.</p>
</blockquote>
<h2 id="display-none">Display: none</h2>
<p><strong>태그가 화면에 보이는 방식을 지정하는 속성이다.</strong></p>
<p>display 는 주로 요소의 성격을 바꿀 때 많이 사용한다. 
display: block; , inline, inline-block, grid, flex 이런식으로 css 작성시 사용해왔었다.</p>
<blockquote>
<p>none    태그를 화면에서 보이지 않게 만든다.
block    태크를 bolck 형식으로 지정한다.
inline    태그를 inline 형식으로 지정한다.
inline-block 태그를 inline-block으로 지정한다.</p>
</blockquote>
<p>예를 들어</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;display: none VS overflow: hidden&lt;/title&gt;
    &lt;/head&gt;
    &lt;style&gt;
        .box1 { width: 50px; height: 50px; background-color: red; }
        .box2 { width: 50px; height: 50px; background-color: blueviolet; }

    &lt;/style&gt;
    &lt;body&gt;
        &lt;div class=&quot;box1&quot;&gt;box1&lt;/div&gt;
        &lt;div class=&quot;box2&quot;&gt;box2&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/c5e1e748-05ff-4a84-88cd-430f85e0ea52/image.png" alt=""></p>
<p>브라우저에는 위와 같이 div로 구성된 영역이 생성된다.
이때, box1에 display:none을 적용시켜보면, </p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/a5f36754-0745-46a4-96cf-d5bcf9dd64e3/image.png" alt=""></p>
<p>화면에서는 box1이 사라진것을 확인할 수 있다. 하지만 개발자도구에서 확인하면
box1에 해당하는 태그는 아직 남아 있는것을 확인할 수 있다.</p>
<h2 id="overflowhidden">overflow:hidden;</h2>
<p>overflow 속성은 내부의 요소가 부모의 범위를 벗어날 때 어떻게 처리할 건지 지정하는 속성인데, 
overflow란 &#39;넘쳐흐르다&#39; 라는 말 그대로 사전적의미가 포함되어 있다. 
주로 사용되는 속성값은 hidden 이다. 보통 부모 영역보다 자식의 요소가 크면
부모영역의 크기로 맞추고 넘치는 부분을 안보이게끔 한다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;display: none VS overflow: hidden&lt;/title&gt;
    &lt;/head&gt;
    &lt;style&gt;

        .parents {width:400px; height: 300px; background-color: aqua;  }
        .child { width: 600px; height: 200px; background-color: yellow; }
        .last { width: 400px; height: 200px; background-color: brown; }

    &lt;/style&gt;
    &lt;body&gt;
        &lt;div class=&quot;parents&quot;&gt;
            &lt;div class=&quot;child&quot;&gt;child&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;last&quot;&gt;last&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/c011843c-73a1-4c92-9d55-7bcb67269a49/image.png" alt=""></p>
<p>부모 요소에 overflow:hidden 을 넣어줄경우</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/b4364c00-a86c-480b-aba3-c46fc13cbac1/image.png" alt=""></p>
<p>hidden    영역을 벗어나는부분을 보이지 않게 만든다.
위와 같이 child 영역이 가려진 것을 확인할 수 있다.</p>
<p>scroll    영역을 벗어나는 부분을 스크롤을 생성하게 한다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
&lt;head&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;style&gt;
        body &gt; div{
            width: 400px;
            height: 100px;
            border: 3px solid black;
            position: relative;
            overflow: scroll;
        }
        .box{
            width: 100px; 
            height: 100px;
            position: absolute;
        }
        .box1{
            background-color: red;
            left: 10px;
            top: 10px;
        }
        .box2{
            background-color: green;
            left: 50px;
            top: 50px;
        }
        .box3{
            background-color: blue;
            left: 90px;
            top: 90px;
        }
    &lt;/style&gt;

&lt;/head&gt;
&lt;body&gt;
    &lt;div&gt;
        &lt;div class=&quot;box box1&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;box box2&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;box box3&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/2fcdb4ba-c130-4a69-abf4-1d4798dfcea7/image.png" alt=""></p>
<p>display:none의 경우 적용된 요소의 하위 요소를 포함해서 존재하지 않는것처럼
렌더링 된다. 이것이 의미하는 것은 적용된 요소 내의 콘텐츠 또한 사라진다는것이다.
그렇기 때문에 display:none 이 적용된 요소는 하위의 콘텐츠까지 스크린리더기가 읽을 수 없다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/627464d7-0fb5-4f83-88d5-474b6d21dc19/image.png" alt=""></p>
<p>display:none 이 적용된 요소는 접근성 트리에서 제거가 되며 해당 요소와 하위 요소-콘텐츠 등이 화면 판독 기술(스크린리더기)에 의해 인식되지 않는다.</p>
<p>그렇게 될 경우 스크린 리더기에 의존해야하는 사람들은 웹사이트를 이용하는데 어려움을 겪게 될 것이다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/2bb9b6c0-9310-4387-a9ca-5ce8ca4e3d85/image.png" alt=""></p>
<p>overflow:hidden은 숨겨져있지만 숨겨진 요소가 포커스가 된다.
순서가 없이 읽으면 복잡한 데이터를 가지고 있는 것을 필요할 때 읽어주기 위함이다.
위 사진은 네이버 검색창에 있는 가상 키보드 영역이다.
키보드 아이콘을 클릭하면 텍스트 입력이 가능한 가상 키보드가 나온다.
이 가상 키보드는 #_nx_kbd 이며, display:none으로 숨겨져있다.
<img src="https://velog.velcdn.com/images/munju_dev/post/f17d1bea-2f04-4d04-8248-0572a14ffa6d/image.png" alt=""></p>
<p>overflow:hidden은 숨겨져있지만 숨겨진 요소가 포커스 된다고 했다.
만약 가상키보드가 필요 없는 상황이라면 시각장애인들은 원하는 정보에 도달하기 위해
많은 포커스를 걸쳐 검색 버튼을 눌러야할것이다.</p>
<p>이를 방지하기 위해 가상키보드 버튼 포커스에 도달하기 위해 원하는 기능을 
선택하게 하고, 기능창을 나타내어 사용하게 할 수 있도록 하며, 
필요없는 상황에서는 포커스가 가지 않도록 하기위해 display:none을 사용하는 것이 
적절하다.</p>
<ul>
<li>display:none은 보이는 것, 들리는것 둘다 없앤다.</li>
</ul>
<ul>
<li>overflow:hidden은 보이는것은 숨기지만 들리거나 읽힐 수는 있다.</li>
</ul>
<p>마지막으로 display:none, visibility:hidden;의 차이점에 대해 알아보겠다.
예시를 보면 명확하게 이해 할 수 있다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;Document&lt;/title&gt;
    &lt;/head&gt;
    &lt;style&gt;
        div { display: inline-block; border: 1px solid #ddd; margin: 10px; padding: 10px; }
        .dis div { width: 50px; background-color: aqua; }
        .vis div { width: 50px; background-color: red; }
    &lt;/style&gt;
    &lt;body&gt;

        &lt;h2&gt;display&lt;/h2&gt;
        &lt;div class=&quot;dis&quot;&gt;
            &lt;div class=&quot;box1&quot;&gt;box1&lt;/div&gt;
            &lt;div class=&quot;box2&quot;&gt;box2&lt;/div&gt;
            &lt;div class=&quot;box3&quot;&gt;box3&lt;/div&gt;
        &lt;/div&gt;

        &lt;h2&gt;visibility&lt;/h2&gt;
        &lt;div class=&quot;vis&quot;&gt;
            &lt;div class=&quot;box4&quot;&gt;box4&lt;/div&gt;
            &lt;div class=&quot;box5&quot;&gt;box5&lt;/div&gt;
            &lt;div class=&quot;box6&quot;&gt;box6&lt;/div&gt;
        &lt;/div&gt;

    &lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/416fc5e1-ab40-41f6-bb2b-d4ed179b5332/image.png" alt=""></p>
<p>여기서 .box2에는 display:none을, .box5에는 visibility: hidden; 을 줘보겠다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/0a020c7e-8b61-42be-b31d-978b740d81f5/image.png" alt=""></p>
<p>display: none; 은 앞서 말했듯이 화면에 보이지 않게 처리하고 차지하고 있는 공간도 없앤다.
visibility: hidden; 은 화면에서는 보이지 않게 처리하지만 차지하고 있는 공간은 그대로 남는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Jquery] effect 효과제어하기]]></title>
            <link>https://velog.io/@munju_dev/Jquery-effect-%ED%9A%A8%EA%B3%BC%EC%A0%9C%EC%96%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@munju_dev/Jquery-effect-%ED%9A%A8%EA%B3%BC%EC%A0%9C%EC%96%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 07 Apr 2023 04:18:17 GMT</pubDate>
            <description><![CDATA[<p>jquery effect 효과에 대해 알아보겠다.</p>
<ul>
<li>delay()</li>
<li>stop()</li>
<li>finish()</li>
</ul>
<p>예제 )</p>
<pre><code>&lt;body&gt;
    &lt;h1&gt;이펙트 효과의 지연 설정&lt;/h1&gt;
    &lt;button id=&quot;startBtn&quot;&gt;이펙트효과시작&lt;/button&gt;
    &lt;div id=&quot;divBox&quot;&gt;&lt;/div&gt;

    &lt;h1&gt;이펙트 효과의 정지와 중지&lt;/h1&gt;
    &lt;p&gt;&lt;/p&gt;
    &lt;button id=&quot;toggle_btn&quot;&gt;slideToggle&lt;/button&gt;
    &lt;button id=&quot;stop_btn&quot;&gt;stop()&lt;/button&gt;
    &lt;button id=&quot;finish_btn&quot;&gt;finish()&lt;/button&gt;
    &lt;div id=&quot;divBox2&quot;&gt;&lt;/div&gt;
&lt;/body&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/626e05c2-d725-4d9f-807e-161942dc2a3f/image.png" alt=""></p>
<pre><code>&lt;script&gt;
    $(document).ready( function(){
        $(&#39;#startBtn&#39;).click( function(){
            //divBox를 0.5초에 걸쳐 사라지게 하고
            //1초 딜레이 후에 다시 2초동안 나타남
            $(&#39;#divBox&#39;).fadeOut(500).delay(1000).fadeIn(2000);
        });
        $(&quot;#toggle_btn&quot;).click( function(){
            $(&#39;#divBox2&#39;).slideToggle(2000);
        });
        $(&quot;#stop_btn&quot;).click( function(){
            $(&#39;#divBox2&#39;).stop();
        });
        $(&#39;#finish_btn&#39;).click( function(){
            $(&#39;#divBox2&#39;).finish();
        });
    });

&lt;/script&gt;</code></pre><h2 id="delay">delay()</h2>
<p>effect 효과의 지연설정
delay() 메소드는 실행 중인 큐 안에서 연속적으로 실행되는 이벤트 효과 사이의
시간을 설정한다.</p>
<p>일정시간이 경과한 후에 함수 뒤의 코드를 실행하도록 강제적인 지연시간을 생성하는ㄴ데, 
큐를 가진 애니메이션에만 적용된다.</p>
<h2 id="stop">stop()</h2>
<p>effect 효과의 중지
.stop() 메소드는 선택한 요소에서 실행 중인 모든 이펙트 효과를 중지시킨다.</p>
<h2 id="finish">finish()</h2>
<p>.finish() 메소드는 선택한 요소가 포함된 큐까지 제거하여 모든 이펙트 효과를 전부 종료시킨다.</p>
<p>.stop()메소드와 .finish() 메소드는 실행 중인 이펙트 효과를 멈춘다는 점이 동일하지만,
.stop()메소드는 일시적으로 중지시키고 다시 재개도 가능하지만, .finish() 메소드는 중지가 아닌 아예 종료시키며 다시 재개할 수 없고 처음부터 실행을 해야한다는 점이 차이점이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[es6] javascript 문법 (2) 화살표함수]]></title>
            <link>https://velog.io/@munju_dev/es6-javascript-%EB%AC%B8%EB%B2%95-2-%ED%99%94%EC%82%B4%ED%91%9C%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@munju_dev/es6-javascript-%EB%AC%B8%EB%B2%95-2-%ED%99%94%EC%82%B4%ED%91%9C%ED%95%A8%EC%88%98</guid>
            <pubDate>Thu, 06 Apr 2023 09:04:56 GMT</pubDate>
            <description><![CDATA[<p>ES6는 템플릿 리터럴 이라고 불리는 새로운 문자열 표기법을 도입하였는데,
템플릿 리터럴은 일반 문자열과 비슷해 보이지만 &#39;또는 &quot;같은 통상적인 따옴표 문자 대신 백틱 문자 &#39;를 사용한다. </p>
<p>const template = <code>템플릿 리터럴은 &#39;작은따옴표(single quotes)&#39;와 &quot;큰따옴표(double quotes)&quot;를 혼용할 수 있다.</code>;</p>
<pre><code>&lt;script&gt;
       const template = 
       `&lt;ul class=&quot;nav-items&quot;&gt;
            &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;News&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Contact&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;About&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;`;
        console.log(template);
&lt;/script&gt;</code></pre><ol>
<li>일반적인 문자열에서 줄바꿈은 허용되지 않으며 공백을 표현하기 위해서는 백슬래시로 시작하는 이스케이프 시퀀스를 사용해야한다. ES6템플릿 리터럴은 일반적인 문자열과 달리 여러줄에 걸쳐 문자열을 작성할 수 있으며, 템플릿 리터럴 내의 모든 공백은 있는 그대로 적용한다. </li>
</ol>
<pre><code>&lt;script&gt;
    const first = &quot;Lee&quot;;
    const last = &quot;Jo&quot;;
    //ES5: 문자열연결
    console.log(&#39;My name is &#39; + first + &#39; &#39; + last + &#39;.&#39;);
&lt;/script&gt;</code></pre><ol start="2">
<li>ES6 : String Interpolaton
템플릿 리터럴은 +연산자를 사용하지 않아도 간단한 방법으로 새로운 문자열을 
삽입할 수 있는 기능을 제공한다.</li>
</ol>
<pre><code>&lt;script&gt;
    console.log(`1+1 = ${1+1}`);  // 1+1 = 2
    const name = &#39;Leee&#39;;
    console.log(`Hello ${name.toUpperCase()}`); //Hello Leee;
&lt;/script&gt;</code></pre><ol start="3">
<li>${expression}을 템플릿 대입문이라고 하는데,
템플릿 대입문에서는 문자열 뿐만아니라 표현식도 할 수 있다.</li>
</ol>
<h2 id="arrow-function화살표함수">Arrow Function(화살표함수)</h2>
<p>키워드 대신 화살표 =&gt; 를 사용하여 
간략한 방법으로 함수를 선언할 수 있다. (모든 경우에 사용할수 X)</p>
<h3 id="화살표-함수의호출">화살표 함수의호출</h3>
<p>화살표함수는 익명함수로만 사용할수 있어서 호출하기 위해서는 함수표현식을 사용한다.</p>
<p>매개변수 지정 방법</p>
<p>() =&gt; {...} 매개변수가 없을 경우
x =&gt; {...}  매개변수가 한개인경우, 소괄호 생략 가능
(x,y) =&gt; {...}  매개변수가 여러개인 경우, 소괄호 생략할수 없음</p>
<p>함수몸체 지정 방법
x =&gt; { return x<em>x }  single line block
x =&gt; x</em>x
함수 몸체가 한줄의 구문이라면, 중괄호를 생략할 수 없으며, 암묵적으로 return된다.  </p>
<pre><code>    () =&gt; { return { a: 1 }; }
    () =&gt; ({ a: 1 })

    () =&gt; {  //multi line block
        const x = 10;
        return x*x;
    };</code></pre><pre><code>&lt;script&gt;
    //ES5
    var pow1 = function(x) { return x*x; };
    console.log(pow1(10)); //100

    //ES6
    const pow = x =&gt; x*x;
    console.log(pow(10)); //100

    //ES5
    var arr = [1,2,3];
    var poww = arr.map( function(x){
        return x*x;
    });
    console.log(poww); // [1,4,9]

    //ES6
    const poo = x =&gt; x*x;
    console.log(poo(10)); //100

    //ES5
    var ree = [1,2,3];
    var pee = ree.map( function(x){
        return x*x;
    });
    console.log(pee); // [1,4,9]

    //ES6
    const reee = [1,2,3];
    const peee = reee.map(x=&gt;x*x);
    console.log(peee);  // [1,4,9]
&lt;/script&gt;</code></pre><h2 id="일반함수의-this">일반함수의 this</h2>
<p>-일반 함수의 경우, 해당 함수를 호출하는 패턴에 따라
this에 바인딩되는 객체가 달라지고, 콜백함수 내부의 ,this는 전역객체 window를 가르킨다.</p>
<pre><code>&lt;script&gt;
    function Prefixer(prefix){
        this.prefix = prefix;
    }
    Prefixer.prototype.prefixArray = function(arr){
        //(A)
        return arr.map( function(x){
            return this.prefix + &#39; &#39; + x; //(B)
        });
    };

    var pre = new Prefixer(&#39;Hi&#39;);
    console.log(pre.prefixArray([&#39;Lee&#39;,&#39;kim&#39;])); 
&lt;/script&gt;</code></pre><p>(A)지점에서의 this는 생성자함수 Prefixer가 생성한 객체, 
생성자 함수의인스턴스 (위예제의 경우 pre).</p>
<p>(B)지점에서 사용한 this는 전역객체 window를 가르킨다.
생성자함수와 객체의 메소드를 제외한 모든 함수 내부의 this는 전역객체를 가르키기 때문</p>
<p>((A)처럼 pre라고 생각하겠지만)..</p>
<p>.
.
.</p>
<p>넘 어렵다..😢 다시 소화시키고 수정하겠다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[간단한 모달창 구현 modal example]]></title>
            <link>https://velog.io/@munju_dev/%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%AA%A8%EB%8B%AC%EC%B0%BD-%EA%B5%AC%ED%98%84-modal-example</link>
            <guid>https://velog.io/@munju_dev/%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%AA%A8%EB%8B%AC%EC%B0%BD-%EA%B5%AC%ED%98%84-modal-example</guid>
            <pubDate>Thu, 06 Apr 2023 08:35:35 GMT</pubDate>
            <description><![CDATA[<p>이번 예제는 폼안에 있는 자세히보기를 클릭하였을 때 상세보기를 할 수 있도록 
간단한 스크립트로 예제를 만들어보았다.!</p>
<h3 id="html">html</h3>
<pre><code>&lt;body&gt;
    &lt;section class=&quot;main-g&quot;&gt;
      &lt;div class=&quot;content-container&quot;&gt;
        &lt;div class=&quot;main-form-wrap&quot;&gt;
          &lt;div class=&quot;form-box&quot;&gt;
            &lt;form action=&quot;/form_save.php&quot; method=&quot;post&quot;&gt;
              &lt;h3&gt;SMS 빠른상담신청&lt;/h3&gt;
              &lt;p&gt;SMS상담 신청으로 간편하고 빠르게 상담 받아보세요.&lt;/p&gt;
              &lt;div class=&quot;form-wrap&quot;&gt;
                 &lt;div class=&quot;name-phone&quot;&gt;
                   &lt;input type=&quot;text&quot; name=&quot;user_name&quot;  placeholder=&quot;이름&quot; required&gt;
                   &lt;input type=&quot;text&quot; name=&quot;user_phone&quot; placeholder=&quot;연락처&quot; required maxlength=&quot;13&quot; onkeyup=&quot;this.value=this.value.replace(/[^0-9]/g,&#39;&#39;);&quot;&gt;
                 &lt;/div&gt;

                &lt;div class=&quot;contents&quot;&gt;
                  &lt;input type=&quot;text&quot; name=&quot;contents&quot; placeholder=&quot;내용을 입력하세요.&quot; required&gt;
                &lt;/div&gt;

                &lt;div class=&quot;chk-box&quot;&gt;
                    &lt;input id=&quot;chk-top&quot; type=&quot;checkbox&quot; name=&quot;agree_terms&quot; value=&quot;동의&quot; checked=&quot;checked&quot; required&gt;
                    &lt;label for=&quot;chk-top&quot;&gt;개인정보처리방침동의&lt;/label&gt;
                    &lt;a href=&quot;javascript:;&quot; class=&quot;modal-link&quot;&gt;내용보기&lt;/a&gt;
                &lt;/div&gt;

                &lt;div id=&quot;modal&quot;&gt;
                    &lt;div class=&quot;modal-close&quot;&gt;x&lt;/div&gt;
                    &lt;p&gt;
                        &lt;strong&gt;개인정보 수집·이용 동의&lt;/strong&gt;&lt;br/&gt;

                         아무개의 개인정보 수집 이용 목적은 다음과 같습니다. 
                         내용을 읽어보신 후 동의 여부를 결정하여 주시기 바랍니다.&lt;br/&gt;&lt;br/&gt;

                        1. 수집·이용 목적&lt;br/&gt;

                        ▪ 전화 법률상담&lt;br/&gt;
                        ▪ 방문예약 상담 및 관리&lt;br/&gt;&lt;br/&gt;

                        2. 수집·이용 항목&lt;br/&gt;
                        ▪ 필수항목_이름, 연락처&lt;br/&gt;
                        ▪ 선택항목_이메일, 상담내용&lt;br/&gt;&lt;br/&gt;

                        3. 보유·이용 기간&lt;br/&gt;
                        ▪ 수집일로부터 6개월까지&lt;br/&gt;&lt;br/&gt;

                        동의서의 내용을 이해하였으며, 
                        개인정보 수집·이용·제공에 관하여 
                        자세한 설명을 듣고, ‘개인정보 보호법’ 
                        제15조(개인정보의 수집, 이용) 등 관련 법규에 
                        의거하여 아무개에 위와 같이 개인정보를 
                        수집·이용·제공하는 것에 동의 또는 부동의 합니다.

                    &lt;/p&gt;
                &lt;/div&gt;
              &lt;/div&gt;
              &lt;button type=&quot;submit&quot;&gt;SMS빠른상담신청 하기 →&lt;/button&gt;
            &lt;/form&gt;            
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/section&gt;
&lt;/body&gt;</code></pre><h3 id="css">css</h3>
<pre><code>&lt;style&gt;
/* 초기화 */
* { box-sizing: border-box; }
html {font-size: 16px;}
body {font-size: 0.75em; line-height: 1.2; font-family: &#39;Noto Sans KR&#39;,&quot;맑은 고딕&quot;, &quot;Malgun Gothic&quot;, Arial, sans-serif; color: #000; }
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, strong, sub, sup, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, embed, input, select, textarea, button { margin: 0; padding: 0; }
h1, h2, h3, h4, h5, h6 {font-size: 1em; font-family: &#39;Noto Sans KR&#39;,&quot;맑은 고딕&quot;, &quot;Malgun Gothic&quot;, Arial, sans-serif; }
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block}
input, button, textarea, select { font-size: 1em; font-family: &#39;Noto Sans KR&#39;,&quot;맑은 고딕&quot;, &quot;Malgun Gothic&quot;, Arial, sans-serif; }
ul, dl,dt,dd {margin:0;padding:0;list-style:none}
legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden}
label, input, button, select, img {vertical-align:middle;font-size:1em}
input, button {margin:0;padding:0;font-family:&#39;Noto Sans KR&#39;, dotum, sans-serif;font-size:1em}
input[type=&quot;submit&quot;] {cursor:pointer}
button {cursor:pointer}

textarea, select {font-family:&#39;Noto Sans KR&#39;, dotum, sans-serif;font-size:1em}
select {margin:0}
p {margin:0;padding:0;word-break:break-all}
hr {display:none}
pre {overflow-x:scroll;font-size:1.1em}
a {color:#000;text-decoration:none}

*, :after, :before {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}

input[type=text],input[type=password], textarea {
-webkit-transition:all 0.30s ease-in-out;
-moz-transition:all 0.30s ease-in-out;
-ms-transition:all 0.30s ease-in-out;
-o-transition:all 0.30s ease-in-out;
outline:none;
}

input[type=text]:focus,input[type=password]:focus, textarea:focus,select:focus {
-webkit-box-shadow:0 0 5px #9ed4ff;
-moz-box-shadow:0 0 5px #9ed4ff;
box-shadow:0 0 5px #9ed4ff;
border:1px solid #558ab7 !important;
}
/* 오시는 길 */
.main-g { background: #fff; }
.main-g .main-form-wrap { padding: 60px; display: flex; align-items: center; letter-spacing: -1px; }
.main-g .form-box { width: 490px; }
.main-g .talk-box { flex: 1; }
.main-g .talk-box img { width: 100%; }
.main-g h3 { font-size: 2.3rem; color: #000; }
.main-g p { font-size: 1.1rem; color: rgba(0, 0, 0, 0.7); line-height: 1.55; margin: 12px 0 20px; }
.main-g .name-phone input[type=text] { font-size: .9rem; width: 237px; margin-right: 10px; height: 50px; display: inline-block; border-radius: 5px; border: 1px solid #d3d3d3; padding-left: 10px; }
.main-g .name-phone input:last-child { margin-right: 0; }
.main-g .name-phone input::placeholder { font-size: 1rem; }
.main-g .contents { margin-top: 15px; }
.main-g .contents input { font-size: .9rem; width: 485px; height: 150px; border-radius: 5px; border: 1px solid #d3d3d3; padding-left: 10px; }
.main-g .contents input::placeholder { font-size: 1rem; }
.main-g .main-form-wrap button { background: #0361ca; color: #fff; border: 1px solid #0361ca; padding: 12px 30px; font-size: 1.1rem; border-radius: 25px; letter-spacing: 1px; display: inline-block; transition: .3s; margin-top: 30px; letter-spacing: -1px; }

.main-g .main-form-wrap .form-box .chk-box { position: relative; margin-top: 20px; }
.main-g .main-form-wrap .form-box #modal { position: relative; display: none; background-color: #ededed; color: #474c4a; padding: 30px; border-radius: 4px;  width: 23%; position: absolute; top: 15%; left: 30%; display: none; box-sizing: border-box; z-index: 10; }
.main-g .main-form-wrap .form-box #modal p { word-break: keep-all; } 
.main-g .main-form-wrap .form-box .modal-link { display: inline-block; position:absolute; right: 20px; margin-left: 10px; text-decoration: underline!important;}
.main-g .main-form-wrap .form-box .modal-close {  background-color: #000; color: #fff; width: 30px; height: 30px; position: absolute; top: 5px; right: 5px; cursor: pointer; padding: 4px; text-align: center;font-size: 22px; line-height: 14px; border-radius: 50%; }
&lt;/style&gt;</code></pre><h3 id="script">script</h3>
<pre><code>&lt;script&gt;

  const btn = $(&#39;.modal-link&#39;);
  const modal = $(&#39;#modal&#39;);
  const close = $(&#39;.modal-close&#39;);

  btn.click(function(){
        modal.fadeIn(&#39;slow&#39;);
    close.click(function(){
        modal.fadeOut(&#39;slow&#39;);
    });
  });
&lt;/script&gt;</code></pre><p>or</p>
<pre><code>&lt;script&gt;
  $(&#39;.modal-link&#39;).click(function(){
      $(&#39;#modal&#39;).show();
  });
&lt;/script&gt;</code></pre><p>내용보기 를 클릭하면 #modal 창이 천천히 나왔다가 modal-close를 클릭하면
천천히 사라진다.</p>
<p>정말 간단한 모달 창을 만들어봤다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/2116f62f-8685-4f7b-9e72-1dd1f5ccd86a/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 콜백함수]]></title>
            <link>https://velog.io/@munju_dev/JS-%EC%BD%9C%EB%B0%B1%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@munju_dev/JS-%EC%BD%9C%EB%B0%B1%ED%95%A8%EC%88%98</guid>
            <pubDate>Thu, 06 Apr 2023 08:20:34 GMT</pubDate>
            <description><![CDATA[<h2 id="콜백함수-callback-function">콜백함수 (callback function)</h2>
<p>콜백함수란 나중에 호출되는 함수로
다른 함수의 매개변수로 함수를 전달하고, 어떠한 이벤트가 발생한 후 매개변수로 전달한 함수가 다시 호출되는 것을 의미한다.</p>
<p>콜백함수는 코드를 통해 명시적으로 호출하는 함수가 아니라, 단지 함수를 등록하기만 하고, 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수를 말한다. (호출방식에 의한 구분이다) 특정 함수에 전달되어 특정함수가 어떤 조건에 의해 호출하는 함수라고 설명하면 쉽겠다.</p>
<pre><code>&lt;script&gt;
    function first(a,b,callback) {
        let v = a + b;
        callback(v);
    }

    first(1,2,function(v) {
        console.log(v); //3
    });

    function button1_click(){
        alert(&#39;버튼1을 눌렀습니다.&#39;);
    }
&lt;/script&gt;

&lt;body&gt;
    &lt;button id=&quot;button1&quot; onclick=&quot;button1_click()&quot;&gt;버튼1&lt;/button&gt;
&lt;/body&gt;</code></pre><p>first 함수를 호출하는데, 호출할 때 익명함수를 parameter로 넘겨주고
first 함수에서는 파라미터를 callback이라는 이름으로 받는다.</p>
<p>first가 실행되면 a,b를 곱한 결과값을 callback함수의 파라미터로 넣어주게 되며,
callback함수는 익명함수이므로 익명함수가 실행되어 3(1+2)가 된다.</p>
<blockquote>
<p><strong>콜백함수를 사용하는 이유</strong>는 🤔 ?
자바스크립트에서 비동기적 프로그래밍을 할 수 있기 때문! </p>
</blockquote>
<ol>
<li><p>사용자 이벤트 처리
-브라우저 화면에서 발생하는 사용자의 이벤트는 예측이 불가능하므로 특정이벤트가 
발생할 때 호출을 원하는 내용을 콜백함수에 전달하게된다.</p>
</li>
<li><p>네트워크 응답 처리 
-화면단에서 서버에게 요청을 보냈을 때, 응답이 언제오는 지 알 수 없기 때문에, 
서버에 대한 응답처리도 비동기적으로 처리한다.</p>
</li>
</ol>
<ol start="3">
<li>파일을 읽고 쓰는 등의 파일 시스템작업, 의도적으로 지연을 사용하는 기능에 사용된다. (알람 등)</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[비동기 처리]]></title>
            <link>https://velog.io/@munju_dev/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC%EC%99%80-%EC%BD%9C%EB%B0%B1%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@munju_dev/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC%EC%99%80-%EC%BD%9C%EB%B0%B1%ED%95%A8%EC%88%98</guid>
            <pubDate>Thu, 06 Apr 2023 08:04:46 GMT</pubDate>
            <description><![CDATA[<h2 id="1-비동기-처리의-가장-흔한-사례-jquery-ajax">1. 비동기 처리의 가장 흔한 사례 jquery ajax</h2>
<ul>
<li>화면에 표시할 이미지나 데이터를 서버에서 불러와 표시해야하는데,
이때 ajax 통신으로 해당 데이터를 서버로부터 가져올 수 있다.</li>
</ul>
<pre><code>&lt;script&gt;
 function getData(){
        var tableData;
        $.get(&#39;https://domain.com/products/1&#39;, function(response){
                tableData = response;
        });
        return tableData;
    }
    console.log(getData()); 
    //undefined

 &lt;/script&gt;</code></pre><p>$.get()이 ajax통신을 하는 부분으로,
<a href="https://domain.com">https://domain.com</a> 에다가 HTTP GET요청을 날려 1번 상품 (product)정보를 요청하는 코드이다. = 지정된 url에 데이터를 하나 보내주세요. 라는 요청과 같다.</p>
<p>그렇게 서버에서 받아온 데이터는 response 인자에 담기고, tableData = response; 코드로 받아온 데이터를 tableData라는 변수에 저장함. 
이때 getData()를 호출하면 받아온 데이터가 찍히나, undefined로 나온다.</p>
<p>$.get()로 데이터를 요청하고 받아올 때까지 기다려주지 않고 다음 코드인 return tableData;를 실행했기 때문. 따라서 getData()의 결과 값은 초기 값을 설정하지 않은 tableData의 값인 undefined를 출력하게 된다.</p>
<p>이렇게 특정 로직의 실행이 끝날 때까지 기다려주지 않고 나머지 코드를 먼저 실행하는 것이 <strong>비동기처리이다.</strong> 자바스크립트에서 비동기처리가 필요한 이유는 화면에서 서버로 데이터를 요청했을 때 서버가 언제 그 요청에 대한 응답을 줄지 모르기때문에 마냥 다른 코드를 실행하지 않고 기다릴 순 없기때문이다.</p>
<p>-만약 저런 코드 1개가 아니라 100개를 보낸다고 생각하면 ?
-비동기처리가 아니고 동기처리라면 코드를 실행하고 기다리고 -하나 실행하는데 수십분은 걸릴것.</p>
<h3 id="비동기처리의-settimeout">비동기처리의 setTimeout()</h3>
<p>setTimeout()은 web API의 종류로 코드를 실행하지 않고 지정한 시간만큼 기다렸다가 로직을 실행한다.</p>
<pre><code>&lt;script&gt;
    console.log(&#39;hello&#39;);
    setTimeout( function(){
        console.log(&#39;bye&#39;);
    },3000);
    console.log(&#39;hello Again&#39;);
&lt;/script&gt;</code></pre><blockquote>
<p>예상 : hello 출력-&gt; 3초있다가 bye출력-&gt; hello Again 출력
실제 : hello 출력 -&gt; hello again출력 -&gt; 3초있다가 bye출력</p>
</blockquote>
<p> setTimeout() 역시 비동기 방식으로 실행되기 때문에 3초를 기다렸다가 다음코드를 수행하는 것이아니라 일단 setTimeout()을 실행하고 나서 바로 다음코드인 console.log(&#39;hello Again&#39;);으로 넘어간다. 
따라서 hello -&gt; hello Again -&gt; bye 출력 </p>
<h3 id="비동기-실행-방식인-settimeout을-이용한-예제">비동기 실행 방식인 setTimeout을 이용한 예제</h3>
<pre><code>&lt;script&gt;
  console.log(&#39;1&#39;);
  function exec() {
      setTimeout( function(){
          console.log(&#39;2&#39;);
      },3000);
      setTimeout( function(){
          console.log(&#39;3&#39;);
      },0);

      console.log(&#39;4&#39;);
      setTimeout( function(){
          console.log(&#39;5&#39;);
          },1000);
      }
      console.log(exec());

&lt;/script&gt;</code></pre><p>실행결과 1 -&gt; 4 -&gt; 3 -&gt; 5 -&gt; 2 
setTimeout이 지연시간이 0이라고 해도 실행컨텍스트가 다르기 때문에 1,4가 먼저 출력됨</p>
<pre><code>&lt;script&gt;
    var i;
    for ( i = 0; i &lt; 5; i++ ){
        setTimeout( function(){
            console.log(i);
        },1000);
    }
&lt;/script&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Jquery] jquery fx 객체 ]]></title>
            <link>https://velog.io/@munju_dev/Jquery-jquery-fx-%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@munju_dev/Jquery-jquery-fx-%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Fri, 31 Mar 2023 09:21:59 GMT</pubDate>
            <description><![CDATA[<h2 id="jquery-fx-객체">jquery fx 객체</h2>
<p>effect 효과가 구현되는 방법을 제어하는 프로퍼티이다.</p>
<blockquote>
<p><strong>jQuery.fx.speeds</strong></p>
</blockquote>
<p>-밀리초에 해당하는 slow(200),normal(400),fast(600)등의 값을 가지고 이펙트 효과의 속도를 나타낸다.</p>
<blockquote>
<p><strong>jQuery.fx.interval</strong></p>
</blockquote>
<p>-jQuery.fx 객체의 interval 프로퍼티는 이펙트 효과가 보여지는 동안의 초당 프레임수를 나타내는데, 연속적인 프레임에서의 초당 프레임수는 13으로 기본설정으로 되어있다.
초당프레임수를 interval 프로퍼티를 이용하여 사용 목적에 맞게 변경할 수 있음!</p>
<blockquote>
<p>*<em>jQuery.fx.off *</em></p>
</blockquote>
<p>jQuery.fx 객체의 off 프로퍼티를 true로 설정하면, 모든 이펙트 효과를 사용할 수 없도록 비활성화시킨다. 
이펙트 효과가 비활성화되면, 이펙트 효과는 실행되지 않으며 이펙트 효과의 마지막 상태로 즉시 변경되며, off 프로퍼티는 특히 구형 버전의 브라우저를 다룰 때 유용하게 사용될 수 있다.</p>
<p>예제를 보면 좀 더 수월하게 이해할수 있겠다.</p>
<h3 id="html">html</h3>
<pre><code>&lt;body&gt;
    &lt;h1&gt;jQuery.fx.speeds 프로퍼티&lt;/h1&gt;
    &lt;button id=&quot;toggleBtn&quot;&gt;이펙트효과 토글&lt;/button&gt;
    &lt;button id=&quot;setBtn&quot;&gt;이펙트 효과 속도 변경&lt;/button&gt;
    &lt;div id=&quot;divBox&quot;&gt;&lt;/div&gt;

    &lt;h1&gt;jQuery.fx.off 프로퍼티&lt;/h1&gt;
    &lt;button id=&quot;toggleBtn2&quot;&gt;이펙트 효과 토글&lt;/button&gt;
    &lt;button id=&quot;forbidBtn2&quot;&gt;이펙트 효과 금지&lt;/button&gt;
    &lt;div id=&quot;divBox2&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;style&gt;
    #divBox,#divBox2 { width: 100px; height: 100px; 
    background-color: yellow;  border: 5px solid red; margin-top: 20px; }
&lt;/style&gt;</code></pre><h3 id="script">script</h3>
<pre><code>&lt;script&gt;
    $(document).ready( function(){
      $(&#39;#toggleBtn&#39;).click(function(){
          $(&quot;#divBox&quot;).slideToggle(&quot;fast&quot;);
      });

      $(&#39;#setBtn&#39;).click( function(){
          //jQuery.fx 객체의 speeds 프로퍼티의 fast의 기본값을 1초로 변경함
          jQuery.fx.speeds.fast = 1000;
      });

      $(&#39;#toggleBtn2&#39;).click( function(){
          $(&#39;#divBox2&#39;).slideToggle(1000); 
      });

      $(&#39;#forbidBtn2&#39;).click( function(){
          jQuery.fx.off = true;
      });

    });
&lt;/script&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/11ac75cf-b421-4d32-8bd6-66fb492da552/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 생성자 함수 this 바인딩]]></title>
            <link>https://velog.io/@munju_dev/JS-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98-this-%EB%B0%94%EC%9D%B8%EB%94%A9</link>
            <guid>https://velog.io/@munju_dev/JS-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98-this-%EB%B0%94%EC%9D%B8%EB%94%A9</guid>
            <pubDate>Thu, 30 Mar 2023 02:38:03 GMT</pubDate>
            <description><![CDATA[<h2 id="javascript-객체-생성방법">javascript 객체 생성방법</h2>
<ol>
<li>리터럴 방식</li>
<li>생성자함수 </li>
</ol>
<p>2) 생성자함수는 javascript의 객체를 생성하는 역할을 하는데, 
    2-1) 기존 함수에 new연산자를 붙여서 호출하면 해당함수는 생성자 함수로 동작한다.
    2-2) 함수이름의 첫 문자는 대문자로 쓰는 것을 권하고 있다.</p>
<h3 id="동작방식">동작방식</h3>
<h4 id="1-빈객체-생성-및-this바인딩">1. 빈객체 생성 및 this바인딩</h4>
<p>생성자 함수 코드가 실행되기 전 빈객체가 생성 됨, 생성한 객체는 this로 바인딩 되는데, 
이후 생성자 함수의 코드 내부에서 사용된 this는 빈 객체를 가리킨다. </p>
<pre><code>&lt;script&gt;
  //Person() 생성자 함수
  var Person = function() {
    //함수 코드 실행 전
    this.name = name;
    //함수리턴
    //this가 가리키는 빈객체에 name이라는 동적 프로퍼티를 생성
  }
&lt;/script&gt;</code></pre><blockquote>
<p>Person() 함수를 생성자로 호출되면, 함수코드가 실행되기 전에 빈객체가 생성된다. 
빈 객체는 Person() 생성자함수의 prototype 프로퍼티가 가리키는 객체를 링크로 연결해서 자신의 프로토타입으로 설정한다. -&gt; this로 바인딩 됨 </p>
</blockquote>
<pre><code>&lt;script&gt;
  var foo = new Person(&#39;foo&#39;);
  //리턴값이 없으므로, this로 바인딩한 객체가 생성자 함수의 리턴값으로 반환돼서 foo변수에 저장된다
  //foo객체-&gt;객체 리터럴 방식
  console.log(foo.name); //foo출력

  var lee = {
    name: &#39;lee nu&#39;,
    age: 35,
    gender: &#39;man&#39;
  };
  console.dir(lee);
&lt;/script&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] 메뉴 구현]]></title>
            <link>https://velog.io/@munju_dev/CSS-%EB%A9%94%EB%89%B4-%EA%B5%AC%ED%98%84</link>
            <guid>https://velog.io/@munju_dev/CSS-%EB%A9%94%EB%89%B4-%EA%B5%AC%ED%98%84</guid>
            <pubDate>Thu, 30 Mar 2023 02:18:59 GMT</pubDate>
            <description><![CDATA[<p> 간단한 메뉴 구현</p>
<p> 이미지를 이용해서 햄버거 버튼 클릭 시 사이드에 메뉴바가 나오는 것을 구현해보았다.</p>
<p>** HTML**</p>
<pre><code>&lt;body&gt;
  &lt;div class=&quot;box&quot;&gt;
    &lt;div class=&quot;container&quot;&gt;
        &lt;div class=&quot;header-menu&quot;&gt;
          &lt;button&gt;&lt;img src=&quot;../javascript/img/close_btn.png&quot; alt=&quot;close_btn&quot;&gt;&lt;/button&gt;
        &lt;/div&gt;

      &lt;ul class=&quot;top-menu&quot;&gt;
        &lt;li class=&quot;menu-items&quot;&gt;&lt;a href=&quot;#&quot;&gt;menu1&lt;/a&gt;&lt;/li&gt;
        &lt;li class=&quot;menu-items&quot;&gt;&lt;a href=&quot;#&quot;&gt;menu2&lt;/a&gt;&lt;/li&gt;
        &lt;li class=&quot;menu-items&quot;&gt;&lt;a href=&quot;#&quot;&gt;menu3&lt;/a&gt;&lt;/li&gt;
        &lt;li class=&quot;menu-items&quot;&gt;&lt;a href=&quot;#&quot;&gt;menu4&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;

        &lt;ul class=&quot;bottom-menu&quot;&gt;
          &lt;li class=&quot;bottom-menu-item&quot;&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
    &lt;/div&gt;

  &lt;div class=&quot;open-menu&quot;&gt;
      &lt;button&gt;&lt;img src=&quot;../javascript/img/menu_btn.webp&quot;&gt;&lt;/button&gt;
  &lt;/div&gt;

&lt;/body&gt;</code></pre><p><strong>CSS</strong></p>
<pre><code>&lt;style&gt;
  body { height: 100%; margin: 0; background: #fffbf6; color: black; font-family: &#39;Roboto&#39;, sans-serif; }
  .box { height: 100vh; width: 300px; position: absolute; left: -350px; z-index: 1001; background: white; overflow: hidden; text-align: left;
  -webkit-transition: -webkit-transform 250ms ease-in-out;
  transition: transform 250ms ease-in-out;
  }
  li { list-style-type: none; padding: 0px 0px 0px 0px; }
  ul { padding: 0px; margin: 0px; }
  button:focus { outline: none; }
  .active {
  -webkit-transform: translateX(350px);
  -moz-transform: translateX(350px);
  -o-transform: translateX(350px);
  -ms-transform: translateX(350px);
  transform: translateX(350px);
  box-shadow: 0 19px 38px rgba(78, 78, 78, 0.3), 0 15px 12px rgba(78, 78, 78, 0.3);
  -moz-box-shadow: 0 19px 38px rgba(78, 78, 78, 0.3), 0 15px 12px rgba(78, 78, 78, 0.3);
  -webkit-box-shadow: 0 19px 38px rgba(78, 78, 78, 0.3), 0 15px 12px rgba(78, 78, 78, 0.3);
  }
  .open-menu {display: inline-block;}
  .open-menu button { display: inline; z-index: 0; background: transparent; border: none; margin-top: 10px; margin-left: 25px; padding: 0px; cursor: pointer; }
  .open-menu img { width: 30px; height: 30px; }
  .header-menu { height: 50px; background-color: white; margin-bottom: 200px }
  .header-menu button { position: relative; left: 260px; background: transparent; border: none; margin-top: 10px; padding: 0px; cursor: pointer; }
  .header-menu img { width: 40px; height: 40px; }
  .top-menu { margin-top: 35px; }
  .top-menu a { text-decoration: none; color: black; font-weight: 500; font-size: 16rem; display: block; line-height: 40px; padding-left: 35px;  transition: .8s; }
  .top-menu a:hover { color: #74b5ff; transition: .5s; }
  .bottom-menu { position: absolute; bottom: 0px; width: 300px; background-color: white; text-align: center; }
  .bottom-menu li { padding-top: 20px; padding-bottom: 20px; padding-left: 0px; color: black; font-weight: 700; font-size: 13px; }

&lt;/style&gt;</code></pre><p><strong>script</strong></p>
<pre><code>&lt;script&gt;
  $(function() {
    const box = $(&#39;.box&#39;);
    const button = $(&#39;.open-menu, .header-menu&#39;);
    button.on(&#39;click&#39;, function(){
        box.toggleClass(&#39;active&#39;);
    });
  });
&lt;/script&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/f9462713-b78d-4296-a896-3891664626ac/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/1a559257-f879-4463-9999-c62afd633ba9/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[카페24] 게시판 커스텀 01]]></title>
            <link>https://velog.io/@munju_dev/%EC%B9%B4%ED%8E%9824-%EA%B2%8C%EC%8B%9C%ED%8C%90-%EC%BB%A4%EC%8A%A4%ED%85%80-01</link>
            <guid>https://velog.io/@munju_dev/%EC%B9%B4%ED%8E%9824-%EA%B2%8C%EC%8B%9C%ED%8C%90-%EC%BB%A4%EC%8A%A4%ED%85%80-01</guid>
            <pubDate>Tue, 28 Mar 2023 05:56:28 GMT</pubDate>
            <description><![CDATA[<p>카페24는 제일 대중적인 cms이다.
우리 회사에서는 카페24를 이용해 홈페이지 구축을 하는데,
오늘은 그동안 미뤘던 게시판 커스텀 하는 법을 기록해보려한다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/a7993e37-2730-4d5e-8b80-20d554c40efc/image.png" alt=""></p>
<p>-예시로 현재 적용된 고객사의 게시판 모습이다.
그 전 작업자가 메인페이지에 게시판을 슬라이드 형태로 노출을 해두었는데, 
카페24 작업 경험이 많지 않았기 때문에 게시판을 커스텀 하는것이란 너무 어렵게만 느껴졌다.
더구나 성공사례 게시판의 경우에는 더더욱 생소했다.</p>
<h2 id="게시판">게시판</h2>
<h3 id="메인페이지-노출-ui--슬라이드-구현--클릭시-해당-게시판-게시물로-이동">메인페이지 노출 UI / 슬라이드 구현 / 클릭시 해당 게시판 게시물로 이동</h3>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/71d14a65-7301-48d5-bd05-e57c95b11d56/image.png" alt=""></p>
<p>위에 이미지는 현재 개인 계정에 있는 내 포트폴리오 사이트에 작업한 결과물이다.
이미지까지 업로드 되도록 커스텀 해봤다. 만든지는 조금 됐지만 나중을 대비해 기록을 해두려한다.</p>
<h3 id="html">html</h3>
<pre><code>&lt;div class=&quot;section section05&quot; id=&quot;section05&quot;&gt;
    &lt;div class=&quot;reward-wrap&quot;&gt;
        &lt;?php echo latest(&#39;theme/swiper&#39;, &#39;work&#39;, 8, 23); ?&gt;
        &lt;div class=&quot;txt-box&quot;&gt;
            &lt;p class=&quot;stit&quot;&gt;Memo board&lt;/p&gt;
            &lt;p class=&quot;tit&quot;&gt;dailymunju &lt;br&gt;&lt;strong&gt;메모보드&lt;/strong&gt;&lt;/p&gt;

            &lt;p class=&quot;txt&quot;&gt;부족한 부분을 게시하여 &lt;br/&gt;공부하는 메모보드입니다&lt;/p&gt;
            &lt;div class=&quot;slide-arrow-box&quot;&gt;
                &lt;div class=&quot;prev&quot;&gt;←&lt;/div&gt;
                &lt;div class=&quot;next&quot;&gt;→&lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;</code></pre><pre><code>&lt;?php echo latest(&#39;theme/swiper&#39;, &#39;work&#39;, 8, 23); ?&gt;</code></pre><p><em>위의 php 코드를 reward-wrap코드 안에 삽입한다.</em></p>
<h3 id="css">CSS</h3>
<p>메인페이지에 구현할 스타일 시트를 추가한다.</p>
<pre><code>
&lt;style&gt;
        .section05{background-color: #aeb3b7;/* background:url(/img/section_05bg.jpg) no-repeat center; background-size: cover; */ letter-spacing: -1px;}
        .section05 .reward-wrap{display:flex; align-items: center;}
        .section05 .reward-box{width:1230px; margin-left:0; margin-right:0;}
        .section05 .txt-box{padding-left:75px;}
        .section05 .txt-box .stit{color: #767676; margin-bottom:30px; font-size:17px; letter-spacing: 2px; font-weight: bold;}
        .section05 .txt-box .tit{font-size:28px; color:#fff; font-weight: 500; margin-bottom: 50px; line-height: 1.34;}
        .section05 .txt-box .tit strong{font-size:37px;}
        .section05 .txt-box .txt{font-size:18px; line-height: 1.65; color:rgba(255,255,255,.6);}
        .section05 .txt-box .slide-arrow-box {margin-top:30px; display:flex;}
        .section05 .txt-box .slide-arrow-box &gt; div {background:#7a7a7a; color:#fff; cursor:pointer; padding:10px 20px 12px; font-size:28px; font-weight:bold;}
        .section05 .txt-box .slide-arrow-box &gt; div.prev{position:relative;}
        .section05 .txt-box .slide-arrow-box &gt; div.prev::after{content:&quot;&quot;; display:block; position:absolute; right:0;  top: 22px;  width:1px;height:20px; background:rgba(255,255,255,.5);}
        .section05  .swiper-wrapper {padding-bottom:20px; padding-top:20px;}
        .section05 .swiper-wrapper .swiper-slide{box-shadow: 2px 4px 10px rgb(0 0 0 / 20%);}
        .section05 .reward-box .img-box img {width:100%;}
        .section05 .reward-box .pan-info{padding:50px; background:#fff; position:relative;}
        .section05 .reward-box .pan-info .btn-go{display:block; width:45px; height:45px; position:absolute; right:40px; top:30px; border-radius:50%; color:#fff; font-size:35px; background:#536878; text-align:center; line-height:42px;}
        .section05 .reward-box .pan-info .tit{font-size:28px; font-weight:bold; margin-bottom:12px; text-decoration: underline;}
        .section05 .reward-box .pan-info .subject{font-size:20px; font-weight:bold; margin-bottom:12px; }
        .section05 .reward-box .pan-info .txt{font-size:15px; color:#333; display: -webkit-box;overflow: hidden;text-overflow: ellipsis;-webkit-line-clamp: 4;-webkit-box-orient: vertical;}
&lt;/style&gt;</code></pre><h3 id="script">script</h3>
<p>슬라이드 구현 스크립트를 추가한다.</p>
<pre><code>    &lt;script&gt;
        var swiper_slide = new Swiper(&#39;.section05 .swiper-container&#39;, {
            slidesPerView: 3,
            spaceBetween: 50,
            speed: 1500,
            autoplay: true,
            loop: true,
            navigation: {
            nextEl: &#39;.slide-arrow-box .next&#39;,
            prevEl: &#39;.slide-arrow-box .prev&#39;,
            },
        });
    &lt;/script&gt;</code></pre><p>카페24 서버에 접속하면, theme/basic에 있는 상위 폴더에서
header / index / tail 등의 php 파일에서 작업을 하는데, 
경로는 대략 아래와 같다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/a12cc95b-81e9-48d3-8825-cb18a1f9280f/image.png" alt=""></p>
<pre><code>&lt;?php echo latest(&#39;theme/swiper&#39;, &#39;work&#39;, 8, 23); ?&gt;</code></pre><p>이코드는 php언어로 작성되었는데, 전임자가 작업한 소스를 보고 응용하였다.
먼저 latest폴더를 생성하기 전에 해당 게시판을 관리자페이지에서 개설한다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/b076da16-a5a0-4cd6-8ecc-2d8057ab7922/image.png" alt=""></p>
<p>위 이미지 처럼 나는 스킨에 su라는 폴더를 생성해주었다.
서버에 있는 소스를 보면
<img src="https://velog.velcdn.com/images/munju_dev/post/bf8812b1-c6ca-44a3-bbaa-9a786460046e/image.png" alt="">
이렇게 theme &gt; basic &gt; skin &gt; board &gt; su
라는 경로로 파일을 만들어서 넣어주었다. (관리자에서 생성하기 전에 서버에 생성해 주어야한다.)</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/87882323-a33c-4138-ab10-9f5a42f7d353/image.png" alt="">
분류란에 게시판에 들어갈 분류를 기입해준다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/f9c359c0-98d7-42e9-816a-34fbe2869fbd/image.png" alt=""></p>
<p>위 이미지 처럼 게시판에 들어갔을때 카테고리별로 게시를 하도록 전체, html , css, javascript ,jquery,vue.js, react.js 의 카테고리를 생성해주었다.</p>
<p>su라는 폴더에는 이제 list.skin.php / style.css / view_comment.skin.php /
view.skin.php / write_update.skin.php / write.skin.php 의 파일을 생성해준다.</p>
<p>기존에 게시판을 생성하면 리스트,뷰,라이트 페이지가 있는것처럼 디폴트로 있는 파일들을 
복사해 커스텀을 하는 방식대로 진행하였다.</p>
<p>이제 앞서 작성한 </p>
<pre><code>&lt;?php echo latest(&#39;theme/swiper&#39;, &#39;work&#39;, 8, 23); ?&gt;</code></pre><p>코드를 살펴보겠다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/a2dd401f-5f76-4e02-82cc-5c822a15d75e/image.png" alt=""></p>
<p>경로대로 보면, latest 폴더안에 있는 swiper폴더를 생성한것을 불러오는것인데, 
여기서부터 조금 어렵게 느껴졌다.</p>
<p>su 폴더와 동등한 경로인 latest 폴더를 생성한 후 안에 latest.skin.php와
해당하는 style.css를 만들어주었다.</p>
<h3 id="latestskinphp">latest.skin.php</h3>
<pre><code>&lt;?php
if (!defined(&#39;_GNUBOARD_&#39;)) exit; // 개별 페이지 접근 불가
include_once(G5_LIB_PATH.&#39;/thumbnail.lib.php&#39;);

// add_stylesheet(&#39;css 구문&#39;, 출력순서); 숫자가 작을 수록 먼저 출력됨
add_stylesheet(&#39;&lt;link rel=&quot;stylesheet&quot; href=&quot;&#39;.$latest_skin_url.&#39;/style.css&quot;&gt;&#39;, 0);
$thumb_width = 460;
$thumb_height = 386;
$list_count = (is_array($list) &amp;&amp; $list) ? count($list) : 0;
?&gt;
&lt;div class=&quot;swiper-container reward-box&quot;&gt;
    &lt;div class=&quot;swiper-wrapper&quot;&gt;
        &lt;?php
            for ($i=0; $i&lt;$list_count; $i++) {
      $thumb = get_list_thumbnail($bo_table, $list[$i][&#39;wr_id&#39;], $thumb_width, $thumb_height, false, true);

            if($thumb[&#39;src&#39;]) {
                $img = $thumb[&#39;src&#39;];
            } else {
                $img = G5_IMG_URL.&#39;/no_img.png&#39;;
                $thumb[&#39;alt&#39;] = &#39;이미지가 없습니다.&#39;;
            }
            $img_content = &#39;&lt;img src=&quot;&#39;.$img.&#39;&quot; alt=&quot;&#39;.$thumb[&#39;alt&#39;].&#39;&quot; &gt;&#39;;
            $wr_href = get_pretty_url($bo_table, $list[$i][&#39;wr_id&#39;]);
        ?&gt;

        &lt;div class=&quot;swiper-slide&quot;&gt;
            &lt;div class=&quot;img-box&quot;&gt;
                &lt;?php echo run_replace(&#39;thumb_image_tag&#39;, $img_content, $thumb); ?&gt;
            &lt;/div&gt;
            &lt;div class=&quot;pan-info&quot;&gt;
                &lt;a href=&quot;&lt;?php echo $wr_href; ?&gt;&quot; class=&quot;btn-go&quot;&gt;+&lt;/a&gt;
                &lt;p class=&quot;tit&quot;&gt;&lt;?php echo $list[$i][&#39;ca_name&#39;]; ?&gt; &lt;/p&gt;
                &lt;div class=&quot;subject&quot;&gt;&lt;?php echo $list[$i][&#39;subject&#39;]; ?&gt;&lt;/div&gt;
                &lt;p class=&quot;txt&quot;&gt;
                    &lt;? echo cut_str(strip_tags($list[$i][&#39;wr_content&#39;]), 130); ?&gt;
                &lt;/p&gt;
            &lt;/div&gt;

        &lt;/div&gt;        
        &lt;?php }  ?&gt;
    &lt;/div&gt;
&lt;/div&gt;
</code></pre><h3 id="stylecss">style.css</h3>
<pre><code>&lt;style&gt;
@charset &quot;utf-8&quot;;

/* 새글 스킨 (latest) */
/*.pic_lt .mySwiper{height:600px}*/
.pic_lt a{border:2px solid #21a7ff;display:block;color:#fff}
.pic_lt a:hover{border-color:#0b101a}
.pic_lt .txt{background-color:#21a7ff;padding:20px}
.pic_lt .txt .category{font-size:16px;border-bottom:2px solid #fff;padding-bottom:3px}
.pic_lt .txt .subject{font-size:20px;margin:20px 0; display: -webkit-box;overflow: hidden;text-overflow: ellipsis;-webkit-line-clamp: 1;-webkit-box-orient: vertical;}
.pic_lt .txt .ico{border-radius:50%;border:1px dashed #fff;text-align:center;width:40px;height:40px;line-height:36px;display:inline-block}
.pic_lt .lt_img img{width:100%}
/*.pic_lt .swiper-slide{height:calc((100% - 20px) / 2)}*/
.pic_lt .swiper-wrapper{padding-bottom:70px}
.pic_lt .swiper-button-next:after,
.pic_lt .swiper-button-prev:after{content:&quot;&quot;}
.pic_lt .swiper-button-next, 
.pic_lt .swiper-button-prev{top:-130px; margin-top:0; border:1px solid #21a7ff;border-radius:50%;text-align:center;width:60px;height:60px}
.pic_lt .swiper-button-next{right:auto;left:500px;margin-left:30px}
.pic_lt .swiper-button-prev{right:auto;left:454px;margin-left:-30px}


.law-img {display:flex; align-items:center; margin: 20px 0 0; background:#fff; color:#000;  font-size:1rem;}
.law-img img{margin-right:10px;}
&lt;/style&gt;</code></pre><p>이제 게시판에 게시물을 작성하였을 때 view 단은 </p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/1cea6a04-8e93-4a7f-9bde-febae21e0646/image.png" alt=""></p>
<p>이런식으로 작성된다.</p>
<p>작성자를 추가하기 위해서는
<img src="https://velog.velcdn.com/images/munju_dev/post/a0a7ab24-f9b5-43c4-b7eb-96e072bdaa46/image.png" alt=""></p>
<p>관리자페이지에서 회원관리-회원추가하고, 나는 lee라는 이름으로 섬네일과 작성자를 추가했다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/f5e008da-6ef2-4b95-a509-38bc5c008f94/image.png" alt=""></p>
<p>예를 들면 변호사 얼굴이나 작성자의 섬네일을 등록하고 싶다면 위와 같이 추가할 수 있도록 게시판을 커스텀 해보았다.</p>
<p>법률홈페이지에서 작업한 게시판을 끌어다가 작업했기때문에, 작성란이라든지, 기입란 등등에
아직 흔적이 남아있다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/15fb7863-b553-47e0-8d43-e079cd930d7b/image.png" alt="">
관리자페이지에서 글을 작성할때에는 위 캡처본처럼 소제목 기입란, 메모, 적용 등으로 분류해놨고, 맨 위쪽 분류를 보면 아까 기입했던 카테고리를 선택할 수 있다.
작성시 기입란이나 텍스트를 수정하려면 이 페이지는 write 페이지 이기때문에
su라는 게시판 폴더로 들어가 write.skin.php를 수정해주면 되겠다.</p>
<p>메모가 아닌 낙서 라고 변경 할경우 또는 기입란 에디터를 삭제하고 싶은경우</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/e38076db-a173-48f3-9afa-e99317008e92/image.png" alt=""></p>
<p>위에 소스에 접속하여 커스텀을 하면 된다.</p>
<p>메인페이지에 노출된 슬라이드는 위의 예시작업에서
이미지도 함께 업로드 될수 있도록 작업하였는데, </p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/240382b7-1b65-4af6-8bdd-958d1039f914/image.png" alt=""></p>
<p>vue.js에 이미지를 넣기 위해서는 관리자 페이지에서 해당 게시물을 작성 할때 마지막 첨부파일에서 첨부할 수 있고, 이때 넣은 이미지가 메인페이지에 노출 된다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/761a36fe-cf52-4d2e-9a1c-3b324d4566a1/image.png" alt=""></p>
<p>파일을 넣었다가 삭제하거나 변경하려면 삭제 후 다시 업로드를 해야하는데, 
체크박스에 체크를 한 후 작성완료를 누르면 업로드 되었던 이미지가 삭제되고, 
다른 이미지를 넣으려면 게시물을 수정해서 다시 재첨부해야 한다.</p>
<p>조금은 멘붕이 왔었지만, 실제로 게시판 커스텀은 꽤나 유용하고 많은 도움이 되었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] arguments / append / apply]]></title>
            <link>https://velog.io/@munju_dev/JS-arguments-%ED%95%A8%EC%88%98%EC%9D%B8%EC%9E%90</link>
            <guid>https://velog.io/@munju_dev/JS-arguments-%ED%95%A8%EC%88%98%EC%9D%B8%EC%9E%90</guid>
            <pubDate>Tue, 28 Mar 2023 03:10:41 GMT</pubDate>
            <description><![CDATA[<h2 id="arguments">arguments</h2>
<p>arguments 객체 : 함수 호출 시, 전달인자들이 배열 형태로 저장된 객체이다.
함수 호출 시 전달인자와 함께 arguments 객체가 함수내부로 전달된다.</p>
<pre><code>&lt;script&gt;

    var self = function(){
        console.log(&#39;a&#39;);
        return function(){
            console.log(&#39;b&#39;);
        }
    }
    self = self();
    self();

    function func(arg1,arg2) {
        console.log(arg1,arg2);
    }
    func();
    func(1);
    //함수의 인자보다 적게 함수를 호출했을 경우, 넘겨지지않은 인자에는 undefined 값이 할당된다
    func(1,2);
    func(1,2,3);
    //반대로 정의된 인자 개수보다 많게 함수를 호출했을 경우에는 에러가 발생되지 않고, 초과된 인자는 무시된다. 

    //add 함수
    function add(a,b){
        //arguments 객체 출력
        console.dir(arguments);
        return a+b;
    }
    //arguments객체는 함수를 호출할때 넘긴 인자들이 배열형태로 지정된 객체들을 의미한다. 
    //실제 배열이 아닌 유사배열이기때문에 배열의 메소드는 쓸 수 없다

&lt;/script&gt;</code></pre><h2 id="arguments-callee-속성">arguments-callee 속성</h2>
<p> -자바스크립트 재귀함수 등에 자주 쓰이는 arguments 객체의 callee속성
  : 자바스크립트의 함수는 arguments 객체를 가지고 있으며,
  현재 실행중인 함수 객체를 반환하는 데 함수 실행 시 넘어온 인자는 물론이고
  callee()를 사용해서 재귀함수로써 반복도 가능하다.</p>
<pre><code>  &lt;script&gt;
    var test = function(a,b,c){
         return arguments[0] + arguments[1] + arguments[2];
    }
    console.log(test(1,2,3)); //6
  &lt;/script&gt;</code></pre><p>-자바스크립트의 함수는 전달받은 매개변수를 특정한 arguments에 담고 있는데, 
만약 코드에서 함수에 전달된 매개변수에 접근할 경우 변수명을 사용해도 되지만
arguments를 사용할 수 있다.</p>
<pre><code>&lt;script&gt;
    //arguments객체를 사용하여 재귀함수를 만드는 예제
    function test(num){
        if( num == 0 ){
            return num;
        }else{
            return num + arguments.callee(num-1);
        }
    }

    console.log(test(2)); //3
    console.log(test(10)); //55
&lt;/script&gt;</code></pre><h2 id="append">append</h2>
<h3 id="append-appendto">append(), appendTo()</h3>
<p>선택한 요소 내의 마지막 위치에 새 요소를 생성하고 추가한다.</p>
<blockquote>
<p>$(요소선택).append(새요소);</p>
</blockquote>
<blockquote>
<p>$(새요소).appendTo(요소선택);    </p>
</blockquote>
<p>html</p>
<pre><code>&lt;body&gt;
    &lt;ul id=&quot;list_ul&quot;&gt;
        &lt;li&gt;html1&lt;/li&gt;
        &lt;li&gt;html2&lt;/li&gt;
    &lt;/ul&gt;
    &lt;button id=&quot;append_btn&quot; onclick=&quot;AppendBtn();&quot;&gt;클릭시li추가&lt;/button&gt;
    &lt;button id=&quot;remove_btn&quot; onclick=&quot;RemoveBtn();&quot;&gt;삭제해&lt;/button&gt;
&lt;/body&gt;</code></pre><pre><code>&lt;script&gt;
        //요소 추가하기 javascript
        function AppendBtn() {
            var target = document.getElementById(&#39;list_ul&#39;);
            var li = document.createElement(&#39;li&#39;);
            var textNode = document.createTextNode(&#39;추가된 li입니다.&#39;);
            li.appendChild(textNode);
            li.style.color = &#39;red&#39;;
            target.appendChild(li);
        }

        function RemoveBtn() {
            var target = document.getElementById(&#39;list_ul&#39;);
            var li = document.querySelector(&#39;li&#39;);
            target.removeChild(li);
        }
&lt;/script&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/1c68c7dc-fe88-4d11-93c0-9b026547afa0/image.png" alt="">
----&gt; 브라우저</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/1ba7c701-f2cc-4ec4-8bed-63dffa828190/image.png" alt="">
----&gt; 클릭시 li 추가 눌렀을 시 추가된 li입니다. 가 추가되는 것을 볼 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/munju_dev/post/437211d9-e03d-40c2-bcf8-b765a9b92b84/image.png" alt=""></p>
<p>----&gt; 삭제해 클릭시 html1 삭제됨</p>
<pre><code>&lt;script&gt;
   //제이쿼리에서 append사용
   $(function(){
          $(&#39;ul&#39;).append(&#39;&lt;li&gt;append&lt;/li&gt;&#39;);
        $(&#39;ul&#39;).prepend(&#39;&lt;li&gt;prepend&lt;/li&gt;&#39;);
   });
&lt;/script&gt;</code></pre><h2 id="apply">apply</h2>
<h3 id="apply메서드를-이용한-명시적인-this바인딩">apply()메서드를 이용한 명시적인 this바인딩</h3>
<h4 id="apply-메소드를-사용해서-person함수를-호출한다">apply() 메소드를 사용해서 Person()함수를 호출한다.</h4>
<p>-첫번째 인자로 넘긴 foo가 Person()함수에서 this로 바인딩 되고, apply()메서드의
두번째 인자로 넘긴 배열 [&#39;foo&#39;,30,&#39;man&#39;]은 호출하려는 Person()함수의 인자 name,age,gender로 각각 전달되고, Person(&#39;foo&#39;,30,&#39;man&#39;)함수를 호출하면서 this를 foo객체에 명시적으로 바인딩 된것이다.</p>
<pre><code>&lt;script&gt;
    function Person(name,age,gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }


    //빈객체 생성,리터럴 방식
    var foo = {};
    //apply 메서드 호출
    Person.apply(foo,[&#39;foo&#39;,30,&#39;man&#39;]);
    console.dir(foo);    

    Person.call(foo,&#39;foo&#39;,30,&#39;man&#39;);

&lt;/script&gt;</code></pre><p><img src="blob:https://velog.io/3af0807a-632d-4894-b26e-25fa38b711e5" alt="업로드중.."></p>
<ul>
<li><p>call()메서드의 경우에는 apply()메서드와 기능은 같지만 apply() 두번째 인자에서 
배열형태로 넘긴것을 각각 하나의 인자로 넘긴다</p>
</li>
<li><p>call(),apply()메서드는 this를 원하는 값으로 명시적으로 매핑해서 특정함수나 매서드를 호출 할 수 있다는 장점이 있다. </p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] 의사 클래스 선택자 
:is()와 :where()]]></title>
            <link>https://velog.io/@munju_dev/CSS-%EC%9D%98%EC%82%AC-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%84%A0%ED%83%9D%EC%9E%90-is%EC%99%80-where</link>
            <guid>https://velog.io/@munju_dev/CSS-%EC%9D%98%EC%82%AC-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%84%A0%ED%83%9D%EC%9E%90-is%EC%99%80-where</guid>
            <pubDate>Mon, 27 Mar 2023 06:33:00 GMT</pubDate>
            <description><![CDATA[<h1 id="css-기능적인-의사-클래스-선택자">css 기능적인 의사 클래스 선택자</h1>
<blockquote>
<p>이 게시물은 Adam Argyle, <a href="https://web.dev/css-is-and-where/">https://web.dev/css-is-and-where/</a>, <a href="https://drafts.csswg.org/selectors-4/#zero-matches">Seletors level4</a>, <a href="https://ui.toast.com/weekly-pick/ko_20210721">새로운 CSS 기능적인 의사 클래스 :is()와 :where()</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:is">:is()</a> 참고하여 작성하였습니다. </p>
</blockquote>
<h2 id="is와-where">:is()와 :where()</h2>
<h2 id="1-is">1. :is()</h2>
<p>기존에 css 를 작성할때 여러 요소에 동일한 스타일을 적용시키려면 긴 선택자 목록들을 나열해야만 했다.</p>
<pre><code>&lt;style&gt;
       h1 &gt; b, h2 &gt; b, h3 &gt; b, h4 &lt; b { color: red; }
   &lt;/style&gt;</code></pre><p>동일한 클래스를 줘서 사용해도 되지만 기본적으로 이런식으로 css 를 작성하게 되면, 가독성이 떨어졌었다. 하지만 :is() 를 이용하면 읽기 쉬울 뿐더러 짧은 선택자 사용으로 인해 가독성이 향상 될 수 있다. 일반적으로 ,를 사용하여 선택자 목록을 만들때, 선택자 중 하나라도 유효하지 않다면 모든 선택자가 무효화 되며 요소를 찾는데 실패하게 된다. </p>
<p>하지만 :is()와 :where()은 실수를 용납하고 선택자 목록 전체가 <strong>무효화 되는 것을 방지한다.</strong></p>
<pre><code>&lt;style&gt;
    :is(h1,h2,h3,h4) &gt; b { color: red; }    

    article :is(h2, h3, p) { 
        color: blue;
    }
&lt;/style&gt;
</code></pre><h2 id="2-where">2. :where()</h2>
<p>반복선택을 줄일 수 있다는 점에서 :is()와 비슷하면서도 다른데, :where()의 예제를 살펴보겠다.</p>
<pre><code>&lt;style&gt;
   article h2, article h3, article p {
           color: blue;
   }
&lt;/style&gt;</code></pre><pre><code>&lt;style&gt;
    article :where(h2, h3, p) { 
        color: blue;
    }
&lt;/style&gt;</code></pre><p>:where()를 사용해서 다시 작성한 예제 코드이다. 여기서 article 요소 선택자는 단 한번만 사용된다. :where()은 불필요한 중복을 없앨 수 있다.</p>
<p> -&gt; 이렇게만 보면 where과 is의 다른점을 찾기가 어려운데, 
 :is()는 기본적으로 :where과 같은 동작을 하기 때문이다.</p>
<h2 id="3-is와-where의-차이점">3. :is()와 :where()의 차이점</h2>
<p>:is()가 :where()과 다른 점은 명시도가 높다는것이다.
:where()은 명시도가 0이지만, :is()는 구체적인 명시도를 갖는다.</p>
<ul>
<li><p>:where()은 명시도가 없다.</p>
</li>
<li><blockquote>
<p>매개변수로 전달된 선택자 목록의 모든 명시도를 무시한다. 이러한 기능은 다른 선택자에서는 찾아볼 수 없다.</p>
</blockquote>
</li>
<li><p>:is()는 가장 구체적인 선택자의 명시도를 따라간다.</p>
</li>
<li><blockquote>
<p>:is(a,div,#id) 의 명시도는 ID의 명시도인 100점이라고 볼 수 있다.</p>
</blockquote>
</li>
</ul>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;

&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;:where()와 :is()의 차이점&lt;/title&gt;

    &lt;style&gt;
        :where(section.where, aside.where, footer.where) p {
            color: red;
        }

        :is(section.is, aside.is, footer.is) p {
            color: green;
        }

        footer p {
            color: blue;
        }
    &lt;/style&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;article&gt;
        &lt;h2&gt;:where()&lt;/h2&gt;
        &lt;section class=&quot;where&quot;&gt;
            &lt;p&gt;Section&lt;/p&gt;
        &lt;/section&gt;
        &lt;aside class=&quot;where&quot;&gt;
            &lt;p&gt;Aside&lt;/p&gt;
        &lt;/aside&gt;
        &lt;footer class=&quot;where&quot;&gt;
            &lt;p&gt;Footer&lt;/p&gt;
        &lt;/footer&gt;
    &lt;/article&gt;
    &lt;article&gt;
        &lt;h2&gt;:is()&lt;/h2&gt;
        &lt;section class=&quot;is&quot;&gt;
            &lt;p&gt;Section&lt;/p&gt;
        &lt;/section&gt;
        &lt;aside class=&quot;is&quot;&gt;
            &lt;p&gt;Aside&lt;/p&gt;
        &lt;/aside&gt;
        &lt;footer class=&quot;is&quot;&gt;
            &lt;p&gt;Footer&lt;/p&gt;
        &lt;/footer&gt;
    &lt;/article&gt;
&lt;/body&gt;

&lt;/html&gt;</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/2d65322a-d65a-4e51-8a70-5f806f9d7aac/image.png" alt=""></p>
<p>추가내용-
사실 차이점을 명확하게 이해하지 못했는데, 오늘 다시 코드를 보면서 생각해보니 이해가 되었다.
:is()의 명시도가 더 구체적이고, 높기 때문에 코드에서 
footer p {color:blue;} css가 적용된건 아래 html 에서 적용된 곳에서만 blue가 
적용되었다. </p>
<pre><code> &lt;footer class=&quot;where&quot;&gt;
     &lt;p&gt;Footer&lt;/p&gt;
 &lt;/footer&gt;</code></pre><footer class="is">
    <p>Footer</p>
</footer>

<p>-&gt; class 가 is인 footer는 blue가 적용되지 않았다.</p>
<h2 id="4-선택자의-그룹화">4. 선택자의 그룹화</h2>
<pre><code>&lt;style&gt;
  /*선택자 처음*/
  :where(h1,h2,h3,h4,h5,h6) &gt; b {
      color: hotpink;
  }

  /*선택자 중간*/
  article :is(header,footer) &gt; p {
      color: gray;
  }
  /*선택자 끝*/
  .dark-theme :where(button,a) {
      color: rebeccapurple;
  }

  /*여러 가지 사용*/
  :is(.dark-theme, .dim-theme) :where(button,a) {
      color: rebeccapurple;
  }

  /*결합*/
  :is(h1,h2):where(.hero,.subtitle) {
      text-transform: uppercase;
  }
  /*중첩*/
  .hero:is(h1,h2,:is(.header,.boldest)) {
      font-weight: 900;
  }
&lt;/style&gt;</code></pre><p>:is()나 :where()의 이점은 쉼표가 여려개있고 선택자가 반복되는 곳을 찾아서
사용하면 의사 클래스의 유연함을 깨달을 수 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] @supports 사용법]]></title>
            <link>https://velog.io/@munju_dev/CSS-supports-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@munju_dev/CSS-supports-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Mon, 27 Mar 2023 04:33:04 GMT</pubDate>
            <description><![CDATA[<p>지원하는 css에 따른 스타일 적용이 된다면 좀 더 스마트하고 효과적으로 css를 작성할 수 있을것이다. 오늘은 @supports css 사용법에 대해 알아보고자 한다.</p>
<blockquote>
<p>이 게시물은 <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@supports">@supports</a>, <a href="https://abcdqbbq.tistory.com/71">CSS Supports, @supports (지원하는 css에 따른 스타일 적용)</a> 사이트를 참고하여 작성하였습니다. </p>
</blockquote>
<h2 id="supports의-사용">@supports의 사용</h2>
<p>@supports 문법을 사용하면 CSS 기능 지원에 따라 달라지는 CSS 선언을 지정할 수 있다.
@supports 문법은 미디어 쿼리 문법과 유사한데, 
아래 예시 코드를 살펴보겠다.</p>
<p>html &gt;</p>
<pre><code>&lt;div&gt;
  &lt;h1&gt;@supports&lt;/h1&gt;
&lt;/div&gt;</code></pre><p>CSS &gt;</p>
<pre><code>&lt;style&gt;
  @supports (테스트할 프로퍼티 혹은 조건) {
      적용하려는 스타일
  }  
&lt;/style&gt;</code></pre><pre><code>&lt;style&gt; 
@supports(display: flex) {
  div h1 { 
        display: flex;
        justify-self: flex-start;
        color: red; 
        border: 3px solid red;
        padding: 20px;
        font-size: 40px;
     }

 &lt;/style&gt;
</code></pre><p><img src="https://velog.velcdn.com/images/munju_dev/post/080f2317-0e9b-4db8-8a85-beb0549c7525/image.png" alt=""></p>
<p>위의 예시 코드를 보면, @supports 로 작성된 스타일 시트가 적용된 것을 볼 수 있다.
display: flex를 지원하는 브라우저와 그렇지 않은 브라우저에서
적용될 소스가 다르게 된단 말이다.</p>
<p><strong>이처럼 css 속성이 지원하거나 지원하지 않는 상황에 따라 css 값을 달리 적용시킬 수 있다.</strong></p>
<h2 id="supports-연산자-사용">@supports 연산자 사용</h2>
<ul>
<li>not / and / or</li>
</ul>
<h3 id="1-not">1. not</h3>
<p>not 키워드는 조건 지정의 반대를 확인하는 데 사용할 수 있다. 
연산자 not 은 표현식 앞에 와서 표현식을 부정한다.
()괄호 안의 내용이 유효하지 않은 것으로 간주되면 true를 반환한다.</p>
<p>아래 예시에서는 브라우저가 플렉스가 아닐 때에 지원하기 때문에 
즉 특정 스타일을 해당 브라우저에 적용하기 위해 지원하지 않는 브라우저를 확인하는 것이다.
원한다면, 여러개의 &#39;not&#39;을 연결하여 부정의 부정문으로도 쓰일 수 있다.</p>
<pre><code>&lt;style&gt;
@supports not(:not( border-radius:10px)){

}
&lt;/style&gt;</code></pre><h3 id="2-and-연산자">2. and 연산자</h3>
<p>and 를 기점으로 작성한 조건의 css가 모두 (동시에) 참일 경우에만 관련 css값을 적용한다.</p>
<pre><code>&lt;style&gt;
@supports (display: flex) and (display:gird) {
}
&lt;/style&gt;
</code></pre><p>&#39;display: flex&#39;와 &#39;display:gird&#39;를 모두 동시에 지원하는 지 확인하고  {} 안의 내용을 실행한다.</p>
<pre><code>&lt;style&gt;
@supports (display: table-cell) and ((display: list-item) and (display: contents)) {

}
&lt;/style&gt;</code></pre><p>--&gt; 괄호 없이 여러 접속사를 병치 할 수 있다. </p>
<h3 id="3-or-연산자">3. or 연산자</h3>
<p>연산자 or은 하나 또는 둘다 참일 경우 참을 반환하여 실행한다.</p>
<pre><code>&lt;style&gt;
@supports (transform:rotate(45deg)) or (-webkit-transform:rotate(45deg)){
   .box{transform:rotate(45deg);}
 }
&lt;/style&gt;</code></pre><p>transform:rotate(45deg) 나 -webkit-transform:rotate(45deg)의 css 중 하나라도 브라우저에서 지원을 하게된다면 .box에 입력한 css 가 적용된다.
===&gt; 참고:and 및 연산자를 모두 사용하는 경우 or괄호를 사용하여 적용 순서를 정의해야 합니다. 그렇지 않으면 조건이 유효하지 않으며 전체 규칙이 무시된다.</p>
<h3 id="4-함수구문">4. 함수구문</h3>
<h4 id="1-seletor">1) seletor()</h4>
<p>브라우저에서 특정 선택자를 지원하는 문법을 통해 분별하여 스타일을 적용시킬 수 있다.</p>
<pre><code>&lt;style&gt;
    @supports selector(h2 &gt; p) {
    }

       @supports selector(A &gt; B){
      .contents &gt; .box {background:#000;}
       }
 &lt;/style&gt;</code></pre><ul>
<li>직계 자손 선택자 (&gt;) 를 지원하는 브라우저일 경우에</li>
<li>.contents &gt; .box에 입력한 css를 적용할 수 있게 만든다.</li>
<li>selector() 를 사용할 때는 selector 문법 뒤에 띄어 쓰기 없이 selector(선택자 조건)을 입력한다.<pre><code>          selector (A ~ B){}   ---- 안됨.
          selector(A ~ B){}    ---- 이렇게 써야합니다.</code></pre></li>
</ul>
<h4 id="2-글꼴지원font-format">2) 글꼴지원font-format</h4>
<p>다음 예제는 woff2 글꼴 형식을 지원하는경우 {} 안의 내용 실행한다.</p>
<pre><code>&lt;style&gt;
    @supports font-format(woff2) {
        font-family: &quot;Open Sans&quot;;
        src: url(&quot;open-sans.woff2&quot;) format(&quot;woff2&quot;);
    } 
&lt;/style&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[es6] javascript 문법 (1) 변수 ]]></title>
            <link>https://velog.io/@munju_dev/es6-javascript-%EB%AC%B8%EB%B2%95-1-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@munju_dev/es6-javascript-%EB%AC%B8%EB%B2%95-1-%EB%B3%80%EC%88%98</guid>
            <pubDate>Wed, 22 Mar 2023 07:02:41 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 포스트는 <a href="https://www.howdy-mj.me/javascript/var-let-const">var,let,const차이</a>,<a href="https://tech.toktokhan.dev/2021/08/22/es6/">es6 문법정리</a> 사이트를 참고하여 게시하였습니다. 많은 도움이 되었음에 작성자분들께 감사드립니다. :)</p>
</blockquote>
<h2 id="ecmascript란">ECMAScript란?</h2>
<p>-ECMA스크립트(ECMAScript, 또는 ES)는 자바스크립트를 표준화하기 위해 만들어진,
ECMA-262 기술 규격에 따라 정의하고 있는 표준화된 스크립트 프로그래밍 언어를 말한다.</p>
<p>자바스크립트에서 var로 변수 선언이 가능했는데, 왜 let과 const 가 나왔으며, 이 둘의 사용을 권장하는 것일까?
먼저 그동안 사용했었던 변수에 대해 알아보고 기초부터 개념정리를 한 후 넘어가도록 하겠다.</p>
<h2 id="변수">변수</h2>
<p>변수(variable)는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인이름을 말한다. 말그대로 변할수 있는 값이다.</p>
<p>자바스크립트는 매니지드 언어(managed language)이기 때문에 개발자가 직접 메모리를 제어하지 못기때문에 개발자가 직접 메모리 주소를 통해 값을 저장하고 참조할 필요가 없고 변수를 통해 안전하게 값에 접근이 가능하다. 변수명(식별자)인 myNumber는 변수의 값이 아닌 메모리 주소를 기억하고 있다. 
변수명을 사용하면, 자바스크립트 엔진이 변수명과 매핑된 메모리 주소를 통해 거기에 저장된 값(23)을 반환한다. 이처럼 변수에 값을 저장하는 것을 <strong>할당</strong>(assignment, 대입, 저장)이라 하며 변수에 저장된 값을 읽어 들이는 것을 <strong>참조</strong>(reference)라 한다. 그리고 변수명을 자바스크립트 엔진에 알리는 것을 <strong>선언</strong>(declaration)이라 한다.</p>
<p>--&gt;지금껏 그냥 변수 지정해서 스크립트를 짜왔는데, 이와 같은 설명을 보고 나니 이해하기가 쉬웠다.</p>
<h3 id="변수선언">변수선언</h3>
<p>자바스크립트에서 변수 선언은 선언 → 초기화 단계를 거쳐 수행된다.</p>
<ul>
<li>선언 단계: 변수명을 등록하여 자바스크립트 엔진에 변수의 존재를 알린다.</li>
<li>초기화 단계: 값을 저장하기 위한 메모리 공간을 확보하고
암묵적으로 undefined를 할당하고 초기화한다. </li>
</ul>
<pre><code>&lt;script&gt;
  var munju
  console.log(munju) 
  // output: undefined
&lt;/script&gt;</code></pre><p>var 키워드를 이용한 변수 선언은 선언 단계와 초기화 단계가 <strong>동시에 진행</strong>되어,
munju에 암묵적으로 undefined를 할당해 초기화한다. 반대로, console을 먼저 찍어도 반환 값이 undefined로 나온다.</p>
<pre><code>&lt;script&gt; 
  console.log(mj) 
  // output: undefined
  var mj
&lt;/script&gt;</code></pre><p>이는 변수 선언이 런타임에서 되는 것이 아니라, 그 <strong>이전 단계</strong>에서 먼저 실행되기 때문이다. 
자바스크립트 엔진은 소스코드를 한 줄씩 <strong>순차적으로</strong> 실행하기에 앞서, 변수 선언을 포함한 모든 선언문(ex. 변수 선언문, 함수 선언문 등)을 찾아내 먼저 실행한다.</p>
<p>즉, 변수 선언이 어디에 있든 상관없이 다른 코드보다 먼저 실행되는 특징을 <strong>호이스팅</strong>(hoisting)이라 한다. 변수 선언 뿐만 아니라, var, let, const, function, function*, class 키워드를 사용해 선언한 모든 식별자(변수, 함수, 클래스 등)는 호이스팅이 된다.
이내용은 아래 호이스팅에 대해 더 자세히 알아보도록 하겠다.</p>
<pre><code>&lt;script&gt;

  var mj // 변수 선언 
  mj = &#39;mandu&#39; // 값의 할당

  var mj = &#39;mandu&#39; // 변수 선언과 할당새로운 변수에 새로운 값을 재할당할 수 있다
  console.log(mj) // output: mandu 

  var mj = fff
  console.log(mj) // output: fff

&lt;/script&gt;</code></pre><p>재할당은 변수에 저장된 값을 다른 값으로 변경하는 것으로, 만약 변경할 수 없는 값이라면 
변수가 아니라 <strong>상수</strong>(constant)라 부른다.</p>
<h2 id="변수-let--const">변수 let / const</h2>
<p>변수의 선언은 var, const, let 키워드로 할 수 있으며, ES6에서 const와 let이 추가되었다.
우선, var는 변수 선언방식에 있어 큰 단점을 가지고 있다.</p>
<pre><code>&lt;script&gt;
  var name = &#39;munju&#39;
  console.log(name) // munju

  var name = &#39;javascript&#39;
  console.log(name) // javascript
&lt;/script&gt;</code></pre><p> 변수를 한번 더 선언했음에도 불구하고 에러가 나오지 않고 각각 변수에 따라 다른 값이 콘솔창에 출력되었다. 유연한 변수 선언으로 간단한 테스트에는 편리할 수 있으나 코드량이 많아진다면 어디에서 어떻게 변수가 사용되었는지 파악하기가 어렵고 값이 바뀔 우려가 있다.</p>
<h3 id="var-변수를-쓸-경우">var 변수를 쓸 경우</h3>
<ul>
<li>변수 중복 선언가능하나 예기치 못한 값을 반환할 수 있다.</li>
<li>함수 레벨 스코프로 인해 함수 외부에서 선언한 변수는 모두 전역변수로 된다.</li>
<li>변수 선언문 이전에 변수를 참조하면 언제나 undefined 를 반환한다.</li>
</ul>
<p>es6에서 나온 let과 const는 위의 문제점을 해결해준다.</p>
<pre><code>&lt;script&gt;
  let name = &#39;munju&#39;
  console.log(name) // munju

  let name = &#39;javascript&#39;
  console.log(name) 
  // Uncaught SyntaxError: Identifier &#39;name&#39; has already been declared
&lt;/script&gt;</code></pre><p>name 이 이미 선언되었다는 에러메시지가 출력된다. (const로 바꿔서 넣어도 동일하게)</p>
<h2 id="let과-const의-차이점">let과 const의 차이점</h2>
<h3 id="let">let</h3>
<ul>
<li>let은 변수에 재할당이 가능하다.</li>
</ul>
<pre><code>&lt;script&gt;
  let name = &#39;munju&#39;

  name = &#39;velog&#39;
  console.log(name) // output: velog
&lt;/script&gt;</code></pre><h3 id="const">const</h3>
<ul>
<li>const는 반드시 선언과 초기화를 동시에 진행하여야한다.</li>
</ul>
<pre><code>&lt;script&gt;             
const name; // output: Uncaught SyntaxError: Missing initializer in const declaration
const name = &#39;mj&#39;
&lt;/script&gt;</code></pre><ul>
<li>const는 변수 재선언, 변수 재할당 모두 불가능하다.
재할당의 경우, 원시 값은 불가능하지만, 객체는 가능하다. const 키워드는 재할당을 금지할 뿐, &#39;불변&#39;을 의미하지 않는다.</li>
</ul>
<pre><code>&lt;script&gt; 
    // 원시값의 재할당
    const name = &#39;mj&#39;
    name = &#39;mj&#39; 
    // output: Uncaught TypeError: Assignment to constant variable.

    // 객체의 재할당
    const name = {
      eng: &#39;mj&#39;,
    }
    name.eng = &#39;munju&#39;

    console.log(name) // output: { eng: &quot;munju&quot; }
&lt;/script&gt;</code></pre><h2 id="스코프">스코프</h2>
<p>스코프(scope)는 식별자(변수명, 함수명, 클래스명등)의 유효범위를 뜻하며, 선언된 위치에 따라 유효범위가 달라진다. 전역에 선언된 변수는 전역 스코프를, 지역에 선언된 변수는 지역 스코프를 갖는다.</p>
<p>전역 변수는 어디에서든지 참조가 가능한 값이다. 반면, 지역 변수는 함수 몸체 내부라고 볼 수 있고, 지역 변수는 자신의 지역 스코프와 그 하위 지역 스코프에서 유효하다.</p>
<p>한 가지 주의해야 할 점은, 자바스크립트에서 모든 코드 블록(if, for, while, try/catch 등)이 지역 스코프를 만들며, 이러한 특성을 <strong>블록 레벨 스코프</strong>라 한다. </p>
<p>하지만 var 키워드로 선언된 변수는 오로지 함수의 코드 <strong>블록만을 지역 스코프로 인정</strong>한다.
이를 <strong>함수 레벨 스코프</strong>라 한다.</p>
<pre><code>&lt;script&gt;
    var a = 1

    if (true) {
    var a = 5
    }

    console.log(a) // output: 5
&lt;/script&gt;</code></pre><p>함수가 아닌 곳에서 var 키워드를 이용해 a를 선언했기 때문에 전역 변수로 취급한다. 
기존에 있던 a 변수가 중복 선언되면서, 최하단의 console에서도 출력 값이 5로 바뀐 것을 확인할 수 있다.</p>
<blockquote>
<p>해당 예제는 코드가 짧아서 어디에서 문제가 일어난지 바로 알 수 있었지만, 실무에서는 그렇지 않다. 전역 변수로 인해 재할당이 발생하거나, 전역 스코프를 공유하기 때문에 어딘가에 동일한 이름이 있다면 예상치 못한 결과를 가져올 수 있는 위험이 있다. 따라서 오로지 함수 코드 블록만을 지역 스코프로 인정하는 var 대신, 블록 레벨 스코프를 지원하는 const와 let을 사용하는 것을 권장한다.</p>
</blockquote>
<h2 id="함수-호이스팅">함수 호이스팅</h2>
<p>호이스팅(Hoisting)이란, var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성을 말한다. -&gt; 위에서 변수 선언 뿐만 아니라, var, let, const, function, function*, class 키워드를 사용해 선언한 모든 식별자(변수, 함수, 클래스 등)는 호이스팅이 된다.라고 했었는데,</p>
<p><strong>function 키워드로 선언한 모든 식별자도 호이스팅이 가능하다.</strong></p>
<p>var 로 선언된 변수와는 달리 let 로 선언된 변수를 선언문 이전에 참조하면 참조 에러(ReferenceError)가 발생한다.</p>
<pre><code>&lt;script&gt;
  console.log(abc); // undefined
  var abc;

  console.log(aaa); // Error: Uncaught ReferenceError: bar is not defined
  let aaa;
&lt;/script&gt;</code></pre><p>let으로 선언된 변수는 스코프의 시작에서 변수의 선언까지 일시적 사각지대에 빠지기 때문인데, 
앞에서 말했듯이, 변수는 <strong>선언 &gt; 초기화 &gt; 할당 단계</strong>에 걸쳐 생성된다.</p>
<p>함수는 크게 네가지로 작성 할 수 있는데,</p>
<pre><code>&lt;script&gt;
   //함수선언문 - 함수 이름 생략 불가
   function add(x,y) {
       return x + y
   }

   //함수 표현식 -함수 이름 생략가능
   var add = function(x,y) {
       return x+y
   }

    //함수이름으로 작성
    var add = function plus(x,y){
       return x+y
    }

    //Function 생성자 함수
    var add = new Function(&#39;x&#39;,&#39;y&#39;,&#39;return x+y&#39;)

    //화살표함수
    var add = (x,y) =&gt; x + y
&lt;/script&gt;     </code></pre><pre><code>&lt;script&gt;
        //var
        // 스코프의 선두에서 선언 단계와 초기화 단계가 실행된다.
        // 따라서 변수 선언문 이전에 변수를 참조할 수 있다.

        console.log(foo); // undefined

        var foo;
        console.log(foo); // undefined

        foo = 1; // 할당문에서 할당 단계가 실행된다.
        console.log(foo); // 1

        let 으로 선언된 변수는 선언과 초기화 단계가 분리되어 진행된다.

        // 스코프의 선두에서 선언 단계가 실행된다.
        // 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않았다.
        // 따라서 변수 선언문 이전에 변수를 참조할 수 없다.

        console.log(foo); // ReferenceError: foo is not defined

        let foo; // 변수 선언문에서 초기화 단계가 실행된다.
        console.log(foo); // undefined

        foo = 1; // 할당문에서 할당 단계가 실행된다.
        console.log(foo); // 1


        // 함수 참조
        console.dir(add) // output: f add(x, y)
        console.dir(sub) // output: undefined

        // 함수 호출
        console.log(add(2, 5)) // output: 7
        console.log(sub(2, 5)) // output: Uncaught TypeError: sub is not a function

        // 함수 선언문
        function add(x, y) {
        return x + y
        }

        // 함수 표현식
        var sub = function(x, y) {
        return x + y
        }
&lt;/script&gt;</code></pre><p>함수선언문의경우에는 함수 자체를 호이스팅 시킬 수 있다. 반면 <strong>함수 표현식</strong>은 변수 호이스팅과 같이 런타임 이전에 해당값을 <strong>undefined로 초기화</strong>만 시키고 런타임에서 해당 함수 표현식이 할당되어 객체가 된다.</p>
<blockquote>
<ol>
<li>변수 선언에는 기본적으로 const를 사용하고, 재할당이 필요한 경우에는 한정적으로 let을 사용하는것이 좋겠다.</li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li>재할당이 필요없는 상수와 객체에는 const사용 / ( 객체를 재할당 하는 경우는 흔하지 않다. const를 사용하면 의도치 않은 재할당을 방지해주기 때문에 보다 안전하겠다. )</li>
</ol>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>