<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NARADESIGN:BLOG</title>
	<atom:link href="http://naradesign.net/wp/feed/" rel="self" type="application/rss+xml" />
	<link>http://naradesign.net/wp</link>
	<description>웹표준, 웹접근성, 유니버설디자인, HTML, CSS, UI, UX, UD</description>
	<lastBuildDate>Thu, 10 May 2012 15:12:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>tabindex=&#8221;1&#8243;? tabindex=&#8221;0&#8243;? tabindex=&#8221;-1&#8243;?</title>
		<link>http://naradesign.net/wp/2012/05/10/1786/</link>
		<comments>http://naradesign.net/wp/2012/05/10/1786/#comments</comments>
		<pubDate>Thu, 10 May 2012 14:59:53 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[웹 기획]]></category>
		<category><![CDATA[웹 접근성]]></category>
		<category><![CDATA[웹 표준]]></category>
		<category><![CDATA[웹접근성]]></category>
		<category><![CDATA[웹표준]]></category>
		<category><![CDATA[유니버설디자인]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1786</guid>
		<description><![CDATA[요 며칠 사이 tabindex 속성이 저를 좀 당황스럽게 했습니다. 일반적으로 tabindex 속성은 키보드 접근성을 훼손할 우려가 있기 때문에 평소에 거들떠 보지도 않던 속성인데요. 해외 오픈소스 위지윅 에디터를 벤치마킹 하다가 tabindex=&#8221;-1&#8243; 이라는 코드를 발견한 겁니다. 제가 알기로 소시적에 이런 코드는 표준이 아니었거든요. HTML4 명세는 tabindex를 다음과 같이 설명합니다. 이 설명은 XHTML 문서에도 동일하게 적용됩니다. 이 속성은 문서의 [...]]]></description>
			<content:encoded><![CDATA[<p>요 며칠 사이 tabindex 속성이 저를 좀 당황스럽게 했습니다. 일반적으로 tabindex 속성은 <a title="tabindex 속성이 오히려 접근성을 해친다." href="http://naradesign.net/wp/2009/04/07/744/">키보드 접근성을 훼손할 우려</a>가 있기 때문에 평소에 거들떠 보지도 않던 속성인데요. 해외 오픈소스 위지윅 에디터를 벤치마킹 하다가 tabindex=&#8221;-1&#8243; 이라는 코드를 발견한 겁니다. 제가 알기로 소시적에 이런 코드는 표준이 아니었거든요.</p>
<p>HTML4 명세는 <a title="Tabbing navigation" href="http://www.w3.org/TR/html401/interact/forms.html#h-17.11.1">tabindex</a>를 다음과 같이 설명합니다. 이 설명은 XHTML 문서에도 동일하게 적용됩니다.</p>
<ul>
<li>이 속성은 문서의 탭 순서 안에서 현재 요소의 순번을 결정한다. 값은 0부터 32767 사이의 숫자여야 한다. 브라우저는 값 앞에 0이 붙어있으면 무시해야 한다.</li>
<li>탭 순서는 사용자가 키보드를 통해 탐색할 때 어떤 요소가 초점을 받는 순서가 되는지를 결정한다.</li>
<li>초점을 받을 요소는 브라우저에서 다음과 같은 규칙에 따라 탐색되어야 한다.</li>
<ol>
<li>요소가 tabindex 속성을 지원하고 양의 값이 할당되어 있으면 먼저 탐색되어야 한다. 탐색은 tabindex 값의 가장 작은 수에서 시작하여 가장 큰 값으로 향한다. 값은 연속되는 일련의  숫자가 아니어도 상관이 없고 어떤 수로 시작해도 무방하다. 요소에 동일한 tabindex 값이 지정되어 있다면 코드 안에서 먼저 등장하는 순서대로 탐색되어야 한다.</li>
<li>tabindex 속성 지원 여부에 관계 없이 &#8220;0&#8243;의 값이 할당된 요소는 그 다음으로 탐색된다. 이 요소들은 코드 안에서 등장하는 순서대로 탐색된다.</li>
<li>disabled 속성이 사용된 요소는 탭 순서에 관여하지 않는다.</li>
</ol>
<li>a, area, button, input, object, select, textarea 요소가 tabindex 속성을 지원하는 요소이다.</li>
</ul>
<p>어쨌거나 표준에 따르면 tabindex 속성에는 음수 값을 사용할 수 없습니다. 그러나 현존하는 브라우저들은 tabindex=&#8221;-1&#8243; 속성이 부여된 요소에 대해 키보드가 접근하지 않는 방식으로 구현을 해놨더라구요. 결국 이 방식이 사실상 표준이거나 또는 공식 표준이 아닐까 하는 생각이 들어 HTML5 명세를 찾아 봤습니다.</p>
<p>HTML5 명세는 <a title="Sequential focus navigation and the tabindex attribute" href="http://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute">tabindex</a> 속성의 음수 값을 다음과 같이 설명합니다.</p>
<ul>
<li>tabindex 값이 음의 정수라면 요소에 초점이 도달하지 않도록 해야 한다.</li>
</ul>
<p>결국 tabindex 속성에서 음수 값을 사용하여 초점을 받을 수 없도록 하는 스펙을 추가한 것입니다. 그리고 현존하는 웹 브라우저들은 문서의 DTD에 관계 없이 이런 새로운 스펙을 낡은 문서에서도 사용할 수 있도록 구현해 둔 것입니다.</p>
<p>지구인들이 가장 많이 사용하고 있는 위지윅 에디터 <a title="TinyMCE Demo" href="http://www.tinymce.com/tryit/full.php">TinyMCE</a>와 <a title="CKEditor Demo" href="http://ckeditor.com/demo">CKEditor</a>는 이런 코드를 도구모음 버튼에 적용하여 키보드 사용자들이 도구모음 블럭을 아예 건너 뛰도록 해 놨더라구요. 이런 구현방식에 대해 어떤 분들은 키보드 사용자를 고려하지 않았다고 주장할 수 있는데요. 제가 보기에는 이 친구들 센스있게 잘 처리한 것으로 봅니다. 키보드만으로 위지윅 에디터를 사용해 본 분들은 이런 처리를 이해할 수 있습니다.</p>
<p><a title="네이버 스마트에디터 데모" href="http://jindo.dev.naver.com/smarteditor/demo/SmartEditor2.html">네이버 스마트에디터</a>와 <a title="다음에디터 데모" href="http://uie.daum.net/openeditor/sample/5.4.0/editor.html">다음 에디터</a>는 도구모음 블럭에 키보드가 접근할 수 있도록 처리해 놨지만 실제로는 키보드만으로는 절대로 사용할 수가 없습니다. 일단 본문 영역에 초점이 들어가면 빠져나올 방법이 없기 때문에 문제가 시작됩니다. 편집 영역에 초점이 들어가면 Tab 키를 눌러서 빠져 나와야 하는데 Tab 키에 들여쓰기 기능을 맵핑해 놓았기 때문에 편집 영역에서 빠져나올 수 없습니다. 결국 키보드만 사용하는 시각 장애인 또는 상지 장애인(팔이 없거나 불편한)은 글쓰기 과업을 수행할 수 없었습니다.</p>
<h2>tabindex=&#8221;1&#8243;</h2>
<p>문서 안에서 가장 먼저 초점을 받을 수 있습니다. 그러나 자연스러운 마크업 순서를 거스르기 때문에 주의해서 사용해야 합니다. 검색엔진 사이트에서 검색창에 사용하면 적합하지만(이 대신 <a title="자동 초점 예제" href="http://naradesign.net/html5/form/input_autofocus.html">autofocus=&#8221;autofocus&#8221;</a> 속성이 더 적절할 듯 해요) 그 외 적합한 경우는 잘 떠오르지 않는군요.</p>
<h2>tabindex=&#8221;0&#8243;</h2>
<p>키보드 초점을 받을 수 없는 div, span과 같은 요소도 초점을 받을 수 있도록 만들어 줍니다. 초점을 받되 초점을 받는 순서는 자연스러운 마크업 순서를 따릅니다.</p>
<h2>tabindex=&#8221;-1&#8243;</h2>
<p>키보드 초점을 받을 수 있는 요소도 초점을 받을 수 없도록 만들어 줍니다. 초점을 받을 수 없기 때문에 &#8220;-1&#8243; 이외의 다른 음의 정수 값은 사실상 의미가 없습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2012/05/10/1786/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>input type=&#8221;search&#8221; in Webkit Browser.</title>
		<link>http://naradesign.net/wp/2012/05/10/1780/</link>
		<comments>http://naradesign.net/wp/2012/05/10/1780/#comments</comments>
		<pubDate>Thu, 10 May 2012 13:27:27 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[웹 디자인]]></category>
		<category><![CDATA[웹 표준]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Webkit]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1780</guid>
		<description><![CDATA[SNS를 사용하다 보니 왠만한 글은 짧게 압축해서 간단하게 쓰는 버릇이 생겼습니다. 대신 블로깅은 뒷전이 됐구요. 오늘은 놀고 있는 블로그에 미안한 생각이 들어서 앞으로 가급적 짧은 내용이라도 블로그에 적어야겠다는 생각을 했습니다. 웹킷 엔진을 사용하는 크롬과 사파리 브라우저는 &#60;input type=&#8221;search&#8221;  /&#62; 요소를 다른 브라우저와 다르게 표시하는 특징(또는 버그)이 있습니다. search 타입은 HTML5 문서에서 새로 등장한 속성입니다. 보통의 [...]]]></description>
			<content:encoded><![CDATA[<p>SNS를 사용하다 보니 왠만한 글은 짧게 압축해서 간단하게 쓰는 버릇이 생겼습니다. 대신 블로깅은 뒷전이 됐구요. 오늘은 놀고 있는 블로그에 미안한 생각이 들어서 앞으로 가급적 짧은 내용이라도 블로그에 적어야겠다는 생각을 했습니다.</p>
<p>웹킷 엔진을 사용하는 크롬과 사파리 브라우저는 &lt;input type=&#8221;search&#8221;  /&gt; 요소를 다른 브라우저와 다르게 표시하는 특징(또는 버그)이 있습니다. search 타입은 HTML5 문서에서 새로 등장한 속성입니다.</p>
<p>보통의 경우 input 요소에 적용되어 있는 브라우저의 기본 CSS는 웹 제작자의 CSS 코드를 이용하여 덮어 쓸 수 있는데요. 크롬과 사파리 브라우저는 유독 &lt;input type=&#8221;search&#8221;  /&gt; 요소에 border 속성을 덮어쓰지 않도록 처리를 해 놨습니다. 원인을 찾다가 보니 크롬 브라우저에서 다음과 같은 코드가 UA(User Agent) 스타일시트 안에 포함되어 있더라구요.</p>
<blockquote><p>input[type="search"] {<br />
-webkit-appearance:searchfield;<br />
box-sizing:border-box;<br />
}</p></blockquote>
<p>다른 타입의 input은 이렇지 않은데요. 유난히 search 타입만 이렇습니다.</p>
<ul>
<li>-webkit-appearance:searchfield; 라는 코드는 웹 제작자가 검색 input에 대한 border 속성을 덮어 쓸 수 없도록 만듭니다.</li>
<li>box-sizing:border-box; 속성은 다른 일반적인 박스와 다르게 패딩과 보더를 너비값에 포함시켜 버리는 방식으로 면적(너비와 높이)을 계산합니다.</li>
</ul>
<p>결국 웹 제작자는 검색 인풋을 의도한 대로 디자인 하기 어렵고 다른 브라우저와 다른 면적 계산 방식 때문에 당황하게 됩니다. 다른 input 요소와 동일한 방법으로 검색 input에 border 속성을 제공하고 일반적인 면적 계산 방식을 가질 수 있도록 하려면 웹 제작자는 다음과 같은 코드를 사용해서 UA 스타일을 덮어쓰기 할 수 있습니다.</p>
<blockquote><p>input[type="search"] {<br />
-webkit-appearance:textfield;<br />
box-sizing:content-box;<br />
}</p></blockquote>
<p>끝입니다. 웹킷 개발자는 어떤 의도로 이렇게 처리를 해놓은 것일까요?</p>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2012/05/10/1780/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>iPhone에서 HTML(CSS, JS) 소스 보기.</title>
		<link>http://naradesign.net/wp/2012/02/22/1754/</link>
		<comments>http://naradesign.net/wp/2012/02/22/1754/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 15:37:17 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[생활의 발견]]></category>
		<category><![CDATA[웹 표준]]></category>
		<category><![CDATA[자바스크립트]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[view-source]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1754</guid>
		<description><![CDATA[가끔은 아이폰에서 블로깅도 하고 싶고 웹 페이지 소스 코드를 보고 싶을 때가 있습니다. 제가 오늘 그 둘을 모두 해보려고 해요. 몇 글자 쓰지도 않았는데 벌써 손가락에 쥐가 나네요. 아래 코드를 아이폰 사파리에 북마크 해보세요. javascript:location=&#39;http://shauninman.com/vs/?url=&#39;+escape(location) 북마클릿은 원래 책갈피 등록이 되지 않기 때문에 아무 주소나 먼저 즐겨찾기에 추가한 다음 등록된 URL을 이 북마클릿 코드로 교체하면 됩니다. [...]]]></description>
			<content:encoded><![CDATA[<p>가끔은 아이폰에서 블로깅도 하고 싶고 웹 페이지 소스 코드를 보고 싶을 때가 있습니다. 제가 오늘 그 둘을 모두 해보려고 해요. 몇 글자 쓰지도 않았는데 벌써 손가락에 쥐가 나네요. 아래 코드를 아이폰 사파리에 북마크 해보세요.</p>
<blockquote>
<p>javascript:location=&#39;http://shauninman.com/vs/?url=&#39;+escape(location)</p>
</blockquote>
<p>북마클릿은 원래 책갈피 등록이 되지 않기 때문에 아무 주소나 먼저 즐겨찾기에 추가한 다음 등록된 URL을 이 북마클릿 코드로 교체하면 됩니다. 그 다음 소스 보기를 원하는 페이지에서 이 북마클릿을 실행합니다.</p>
<p>스크린샷은 데스크탑에서 넣어야겠네요. 이런 짓을 왜 하냐고 물으신다면 다른 사람의 소스 코드가 미치도록 궁금해서 애달아 그럽니다.</p>
<p><strong>단계1</strong>: 북마클릿을 아이폰 사파리 책갈피에 추가</p>
<p><img alt="" height="480" src="http://naradesign.net/wp/wp-content/uploads/iPhoneViewSource1.png" width="320" /></p>
<p><strong>단계2</strong>: 소소 보기를 원하는 페이지에 접속</p>
<p><img alt="" height="480" src="http://naradesign.net/wp/wp-content/uploads/iPhoneViewSource2.png" width="320" /></p>
<p><strong>단계3</strong>: 책갈피에서 북마클릿 실행</p>
<p><img alt="" height="480" src="http://naradesign.net/wp/wp-content/uploads/iPhoneViewSource3.png" width="320" /></p>
<p><strong>단계4</strong>: HTML 소스를 볼 수 있다</p>
<p><img alt="" height="480" src="http://naradesign.net/wp/wp-content/uploads/iPhoneViewSource4.png" width="320" /></p>
<p><strong>단계5</strong>: CSS 소스를 볼 수 있다</p>
<p><img alt="" height="480" src="http://naradesign.net/wp/wp-content/uploads/iPhoneViewSource5.png" width="320" /></p>
<p>참고: <a href="http://goo.gl/LyRxH">http://goo.gl/LyRxH</a></p>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2012/02/22/1754/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Mobile first strategy for CSS designer.</title>
		<link>http://naradesign.net/wp/2012/01/18/1742/</link>
		<comments>http://naradesign.net/wp/2012/01/18/1742/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 15:13:20 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[웹 기획]]></category>
		<category><![CDATA[웹 디자인]]></category>
		<category><![CDATA[웹 표준]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Media Query]]></category>
		<category><![CDATA[Mobile First]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1742</guid>
		<description><![CDATA[마지막으로 블로그에 글을 포스팅 했던 날짜가 작년 여름이네요. 오늘 주제는 CSS 디자이너를 위한 모바일 퍼스트 전략 인데요. 작년에 썼던 &#39;HTML5 &#38; Responsive Web Design&#39; 포스팅과 관련이 있습니다. 모바일 퍼스트 전략이라는 것은 IT 기업들 입에 자주 오르내리는 단어 인데요. 이 개념은 CSS 개발에도 적용할 수 있습니다. 말 그대로 모바일 우선 전략입니다. 2013년 말 또는 2014년 초에는 [...]]]></description>
			<content:encoded><![CDATA[<p>마지막으로 블로그에 글을 포스팅 했던 날짜가 작년 여름이네요. 오늘 주제는 CSS 디자이너를 위한 모바일 퍼스트 전략 인데요. 작년에 썼던 &#39;<a href="http://naradesign.net/wp/2011/05/27/1483/">HTML5 &amp; Responsive Web Design</a>&#39; 포스팅과 관련이 있습니다. 모바일 퍼스트 전략이라는 것은 IT 기업들 입에 자주 오르내리는 단어 인데요. 이 개념은 CSS 개발에도 적용할 수 있습니다. 말 그대로 모바일 우선 전략입니다. <a href="http://gigaom.com/2010/04/12/mary-meeker-mobile-internet-will-soon-overtake-fixed-internet/">2013년 말 또는 2014년 초에는 모바일 인터넷 사용자가 데스크탑 인터넷 사용자를 앞지를 것이라는 전망</a>이 우리를 두근거리게 만들고 있습니다. CSS 디자이너를 위한 모바일 퍼스트 전략이란 무엇인지 알아보죠.</p>
<h2>CSS3 Media Queries</h2>
<p>여러분이 CSS3를 배울 기회가 있었다면 다음과 같은 코드&nbsp;<code>@media (조건문) {실행문}</code>&nbsp;으로&nbsp;무엇을 할 수 있는지 알 수 있습니다. CSS3 미디어 쿼리를 이용하면 모바일 환경의 뷰와 데스크탑 환경의 뷰를 원하는 해상도에 따라 완벽하게 분기 처리할 수 있습니다. 단 하나의 HTML 문서만가지고 말입니다.</p>
<blockquote>
<p><code>@media (max-width:799px) { ... CSS for Mobile ... }&nbsp; /* 이 코드는 799px 이하의 해상도에서 해석 됩니다 */&nbsp;<br />
@media (min-width:800px) { ... CSS for Desktop ... } /* 이 코드는 800px 이상의 해상도에서 해석 됩니다 */</code></p>
</blockquote>
<p>현존하는 최신 버전의 브라우저들은 CSS3 미디어 쿼리를 잘 지원하기 때문에 문제가 없지만 이 코드는 두 가지 문제가 있습니다. 첫째, 미디어 쿼리를 지원하지 않는 모바일 브라우저에 적용되지 않습니다. 둘째, 미디어 쿼리를 지원하지 않는 데스크탑 브라우저에 적용되지 않습니다. 두 가지 문제를 하나씩 풀어 보도록 하지요.</p>
<h2>Mobile First CSS</h2>
<p>미디어 쿼리를 지원하지 않는 모바일 브라우저에 대응하기 위해 저는 다음과 같이 코드를 작성 했습니다. 모바일에 대응하기 위한 코드를 미디어 쿼리 밖에 작성한 것입니다.</p>
<blockquote>
<p><code>... CSS for Mobile ...<br />
@media (min-width:800px) { ... CSS for Desktop ... }</code></p>
</blockquote>
<p>이것으로 첫 번째 문제를 해결 했습니다. 미디어 쿼리를 지원하지 않는 모바일 브라우저는 미디어 쿼리 조건문 밖에 있는 코드를 해석합니다. 미디어 쿼리 구문은 지원하지 않으므로 해석하지 않습니다. 미디어 쿼리를 지원하는 모바일 브라우저는 해상도가 800px이 넘지 않는 이상 미디어 쿼리 구문을 해석하지 않습니다. 조건에 맞지 않으니까요. 미디어 쿼리 지원 여부에 관계 없이 799px 이하의 해상도를 지닌 모든 브라우저는 모바일용 CSS 코드만 해석합니다. 간단 명료하죠? 한편 미디어 쿼리를 지원하지 않는 IE 6~8 브라우저에서는 어떻게 보일까요?</p>
<h2>IE 6, 7, 8 Compatibility</h2>
<p>미디어 쿼리를 지원하지 않는 데스크탑 브라우저(IE 6~8)는 모바일 퍼스트 CSS 코드만 해석하기 때문에 모바일 뷰로 보일 것입니다. 낡은 데스크탑 브라우저가 미디어 쿼리문을 바르게 해석하도록 하기 위해 저는 다음과 같이 CSS3 미디어 쿼리 활성 스크립트를 HTML 문서에 추가 했습니다.&nbsp;</p>
<blockquote>
<p><code>&lt;!--[if lt IE 9]&gt;</code><br />
<span class="Apple-tab-span" style="white-space: pre; "> </span><code>&lt;script src=&quot;http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js&quot;&gt;&lt;/script&gt;</code><br />
<code>&lt;![endif]--&gt;</code></p>
</blockquote>
<p>IE 조건부 주석 &#39;<u>if lt IE 9 = if less than IE 9 = IE 9 미만이면 해석</u>&#39;을 사용하여 IE 9 보다 버전이 낮은 브라우저에서만 이 스크립트를 해석하게 됩니다. 표준계열 브라우저는 이 부분을 주석으로 처리하죠. 이제 IE 6~8 브라우저는 미디어 쿼리 구문을 올바르게 해석할 수 있게 됐습니다. 간단 명료하죠?</p>
<h2>Tip 1: Performance Improvement</h2>
<p>미디어 쿼리를 이용하여 데스크탑용 배경 이미지(background-image)와 모바일용 배경 이미지를 다르게 설정해 보세요. 미디어 쿼리를 이용하여 해상도별로 배경 이미지를 다르게 설정하면 다른 해상도에 필요한 배경 이미지는 서버로 전송 요청하지 않습니다. 즉, 특정 해상도에서 필요로하는 이미지만 요청(http request)하므로 미디어 쿼리를 통해 네트워크 자원을 아낄 수 있습니다. 웹 브라우저 개발자 도구의 네트워크(Network) 탭을 통해서 직접 확인해 보세요.</p>
<h2>Tip 2: Override Mobile by Desktop CSS</h2>
<p>모바일 퍼스트 CSS 코드는 낮은 해상도의 모바일용 브라우저에서만 해석하는 것이 아니라 높은 해상도의 데스크탑 브라우저에서도 동시에 해석하게 됩니다. 따라서 미디어 쿼리 조건문 안에서는 데스크탑용 CSS 코드가 모바일용 CSS 코드보다 더 높은 우선순위를 가질 수 있도록 덮어쓰기 하는 작업이 필요합니다.&nbsp;손이 많이 갈것 같지만 모바일용 코드는 비교적 단순하기 때문에 그리 어렵지는 않을 것입니다.</p>
<h2>References</h2>
<ul>
<li><a href="http://webdesignerwall.com/tutorials/responsive-design-with-css3-media-queries">Responsive Design with CSS3 Media Queries<br />
</a></li>
<li><a href="http://net.tutsplus.com/tutorials/html-css-techniques/flexible-mobile-first-layouts-with-css3/">Flexible, Mobile-First Layouts with CSS3</a></li>
<li><a href="http://naradesign.net/wp/2011/05/27/1483/">HTML5 &amp; Responsive Web Design</a></li>
<li><a href="http://gigaom.com/2010/04/12/mary-meeker-mobile-internet-will-soon-overtake-fixed-internet/">Mary Meeker: Mobile Internet Will Soon Overtake Fixed Internet</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2012/01/18/1742/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>jQuery 입문: form 데이터 유효성 검사.</title>
		<link>http://naradesign.net/wp/2011/07/20/1663/</link>
		<comments>http://naradesign.net/wp/2011/07/20/1663/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 01:32:20 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[자바스크립트]]></category>
		<category><![CDATA[Form Validation]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Regular Expression]]></category>
		<category><![CDATA[정규 표현식]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1663</guid>
		<description><![CDATA[사용자가 form 안에서 올바른 값을 입력했는지 여부(데이터 유효성)는 기본적으로 서버측 스크립트로 확인해야 합니다. 사용자가 입력한 form을 서버로 전송하면 서버측 스크립트는 사용자 값을 받아서 맞는지 틀린지 확인하고 틀린 경우 다시 입력 페이지를 내놓습니다. 이 과정의 문제는 서버측 스크립트로부터 데이터 유효성 검사를 받으려면 네트웍 환경이 좋지 못한 환경에서 너무 오랜 시간을 기다려야한다는 점입니다. 사실 네트웍 환경이 좋아도 [...]]]></description>
			<content:encoded><![CDATA[<p>사용자가 form 안에서 올바른 값을 입력했는지 여부(데이터 유효성)는 기본적으로 서버측 스크립트로 확인해야 합니다. 사용자가 입력한 form을 서버로 전송하면 서버측 스크립트는 사용자 값을 받아서 맞는지 틀린지 확인하고 틀린 경우 다시 입력 페이지를 내놓습니다. 이 과정의 문제는 서버측 스크립트로부터 데이터 유효성 검사를 받으려면 네트웍 환경이 좋지 못한 환경에서 너무 오랜 시간을 기다려야한다는 점입니다. 사실 네트웍 환경이 좋아도 같은 페이지를 자꾸 갱신하는 것은 짜증스러운 일이죠. form이 포함된 페이지를 아무런 실수 없이 한번에 유효하게 작성해서 전송 OK! 하는 사람들이 얼마나 많을까요?</p>
<p>그래서 웹 개발자는 언제부터인가 이런 불편을 개선할 목적으로 데이터 유효성 확인과 같은 핵심 기능을 자바스크립트에 의존하기 시작했습니다. 데이터 유효성 검사를 자바스크립트로 처리하면 서버에 한번 다녀오지 않아도 데이터 유효성 확인이 가능하기 때문에 잘못된 데이터를 페이지 갱신 없이 즉석에서 정정할 수 있습니다. 자바스크립트에 의존한 것은 창의적으로 UX를 개선한 일로써 전혀 문제가 되지 않는데요. 문제는 자바스크립트에만 의존하는 것입니다. 개발자가 작성한 자바스크립트 가운데 전부 또는 일부를 해석하지 못하는 브라우저는 현재도 존재하고 앞으로도 존재할지 모릅니다. 대중적인 브라우저만 지원하면 그만이라는 생각은 학생증이 있는 청소년에게만 책을 빌려주는 도서관 운영 방침과 같은 겁니다.</p>
<p>자바스크립트를 지원하는 환경에서는 자바스크립트에 의존하여 사용성(만족, 효율)을 높이고, 자바스크립트를 지원하지 않는 환경에서는 HTML, CSS, 서버측 스크립트에 의존하도록 양쪽 방향을 모두 고려하여 설계함으로써 상호 운용성(JS 지원 여무에 무관한 운용성)을 확보할 수 있습니다. 이런 설계 기법을 겸손한 자바스크립트(Unobtrusive Javasript)라고 합니다. <a href="http://miya.pe.kr/2007/11/25/%EA%B2%B8%EC%86%90%ED%95%9C-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%EA%B8%B0%EB%B3%B8/">겸손한 자바스크립트 관련글 하나</a>, <a href="http://hyeonseok.com/docs/accessible-javascript/">겸손한 자바스크립트 관련글 둘</a>. 이런 개념을 탑재하고 나서 자바스크립트 실력을 향상시켜도 늦지 않습니다.</p>
<p>오늘의 주제는 jQuery를 이용한 데이터 유효성 검사 입니다. 서버측 유효성 검사 방법은 다루지 않겠지만 서버측 스크립트에 의한 데이터 유효성 검사 또한 진행할 것이라는 전제 아래 자바스크립트로 데이터 유효성 검사 기능을 구현해 봤습니다.</p>
<h2>데이터 유효성 검사 예제 미리보기&nbsp;</h2>
<form action="" class="form">
<p>(*) 항목은 반드시 입력해 주세요.</p>
<ul>
<li><label for="uid">ID(*):</label><br />
<input id="uid" /> 영문, 숫자, 언더스코어(_), 하이픈(-)이 포함 3~16 문자.</li>
<li><label for="upw">PW(*):</label><br />
<input id="upw" type="password" /> 영문, 숫자, 언더스코어(_), 하이픈(-) 포함 6~18 문자.</li>
<li><label for="mail">Email(*):</label><br />
<input id="mail" value="@" /></li>
<li><label for="url">Web(*):</label><br />
<input id="url" value="http://" /></li>
<li><label for="tel">Tel(*):</label><br />
<input id="tel" /> 하이픈(-)은 입력하지 마세요.</li>
</ul>
<input type="submit" value="전송" /></form>
<div><script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script><script type="text/javascript">
// <![CDATA[
jQuery( function($) { // HTML 문서를 모두 읽으면 포함한 코드를 실행
	// 정규식을 변수에 할당
	// 정규식을 직접 작성할 줄 알면 참 좋겠지만
	// 변수 우측에 할당된 정규식은 검색하면 쉽게 찾을 수 있다 
	// 이 변수들의 활약상을 기대한다
	// 변수 이름을 're_'로 정한것은 'Reguar Expression'의 머릿글자
	var re_id = /^[a-z0-9_-]{3,16}$/; // 아이디 검사식
	var re_pw = /^[a-z0-9_-]{6,18}$/; // 비밀번호 검사식
	var re_mail = /^([\w\.-]+)@([a-z\d\.-]+)\.([a-z\.]{2,6})$/; // 이메일 검사식
	var re_url = /^(https?:\/\/)?([a-z\d\.-]+)\.([a-z\.]{2,6})([\/\w\.-]*)*\/?$/; // URL 검사식
	var re_tel = /^[0-9]{8,11}$/; // 전화번호 검사식
	// 선택할 요소를 변수에 할당
	// 변수에 할당하지 않으면 매번 HTML 요소를 선택해야 하기 때문에 귀찮고 성능에도 좋지 않다
	// 쉼표를 이용해서 여러 변수를 한 번에 선언할 수 있다
	// 보기 좋으라고 쉼표 단위로 줄을 바꿨다 
	var 
		form = $('.form'), 
		uid = $('#uid'), 
		upw = $('#upw'), 
		mail = $('#mail'), 
		url = $('#url'), 
		tel = $('#tel');
	// 선택한 form에 서밋 이벤트가 발생하면 실행한다
	// if (사용자 입력 값이 정규식 검사에 의해 참이 아니면) {포함한 코드를 실행}
	// if 조건절 안의 '정규식.test(검사할값)' 형식은 true 또는 false를 반환한다
	// if 조건절 안의 검사 결과가 '!= true' 참이 아니면 {...} 실행
	// 사용자 입력 값이 참이 아니면 alert을 띄운다
	// 사용자 입력 값이 참이 아니면 오류가 발생한 input으로 포커스를 보낸다
	// 사용자 입력 값이 참이 아니면 form 서밋을 중단한다
	form.submit( function() {
		if (re_id.test(uid.val()) != true) { // 아이디 검사
			alert('[ID 입력 오류] 유효한 ID를 입력해 주세요.');
			uid.focus();
			return false;
		} else if(re_pw.test(upw.val()) != true) { // 비밀번호 검사
			alert('[PW 입력 오류] 유효한 PW를 입력해 주세요.');
			upw.focus();
			return false;
		} else if(re_mail.test(mail.val()) != true) { // 이메일 검사
			alert('[Email 입력 오류] 유효한 이메일 주소를 입력해 주세요.');
			mail.focus();
			return false;
		} else if(re_url.test(url.val()) != true) { // URL 검사
			alert('[Web 입력 오류] 유효한 웹 사이트 주소를 입력해 주세요.');
			url.focus();
			return false;
		} else if(re_tel.test(tel.val()) != true) { // 전화번호 검사
			alert('[Tel 입력 오류] 유효한 전화번호를 입력해 주세요.');
			tel.focus();
			return false;
		}
	});
	// #uid, #upw 인풋에 입력된 값의 길이가 적당한지 알려주려고 한다
	// #uid, #upw 다음 순서에 경고 텍스트 출력을 위한 빈 strong 요소를 추가한다
	// 무턱대고 자바스크립트를 이용해서 HTML 삽입하는 것은 좋지 않은 버릇
	// 그러나 이 경우는 strong 요소가 없어도 누구나 form 핵심 기능을 이용할 수 있으니까 문제 없다
	$('#uid, #upw').after('<strong></strong>');
	// #uid 인풋에서 onkeyup 이벤트가 발생하면
	uid.keyup( function() {
		var s = $(this).next('strong'); // strong 요소를 변수에 할당
		if (uid.val().length == 0) { // 입력 값이 없을 때
			s.text(''); // strong 요소에 포함된 문자 지움
		} else if (uid.val().length < 3) { // 입력 값이 3보다 작을 때
			s.text('너무 짧아요.'); // strong 요소에 문자 출력
		} else if (uid.val().length > 16) { // 입력 값이 16보다 클 때
			s.text('너무 길어요.'); // strong 요소에 문자 출력
		} else { // 입력 값이 3 이상 16 이하일 때
			s.text('적당해요.'); // strong 요소에 문자 출력
		}
	});
	// #upw 인풋에서 onkeyup 이벤트가 발생하면
	upw.keyup( function() {
		var s = $(this).next('strong'); // strong 요소를 변수에 할당
		if (upw.val().length == 0) { // 입력 값이 없을 때
			s.text(''); // strong 요소에 포함된 문자 지움
		} else if (upw.val().length < 6) { // 입력 값이 6보다 작을 때
			s.text('너무 짧아요.'); // strong 요소에 문자 출력
		} else if (upw.val().length > 18) { // 입력 값이 18보다 클 때
			s.text('너무 길어요.'); // strong 요소에 문자 출력
		} else { // 입력 값이 6 이상 18 이하일 때
			s.text('적당해요.'); // strong 요소에 문자 출력
		}
	});
	// #tel 인풋에 onkeydown 이벤트가 발생하면
	// 하이픈(-) 키가 눌렸는지 확인
	// 하이픈(-) 키가 눌렸다면 입력 중단
	tel.keydown( function() {
		if(event.keyCode==109 || event.keyCode==189) {
			return false;
		}
	});
});
// ]]&gt;
</script></div>
<h2>데이터 유효성 검사 예제 코드</h2>
<blockquote><pre>&lt;form action=&quot;&quot; class=&quot;form&quot;&gt;
	&lt;p&gt;(*) 항목은 반드시 입력해 주세요.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;
			&lt;label for=&quot;uid&quot;&gt;ID(*):&lt;/label&gt;
			&lt;input id=&quot;uid&quot; /&gt;
			영문, 숫자, 언더스코어(_), 하이픈(-)이 포함된 3~16 문자.
		&lt;/li&gt;
		&lt;li&gt;
			&lt;label for=&quot;upw&quot;&gt;PW(*):&lt;/label&gt;
			&lt;input id=&quot;upw&quot; type=&quot;password&quot; /&gt;
			영문, 숫자, 언더스코어(_), 하이픈(-)이 포함된 6~18 문자.
		&lt;/li&gt;
		&lt;li&gt;
			&lt;label for=&quot;mail&quot;&gt;Email(*):&lt;/label&gt;
			&lt;input id=&quot;mail&quot; value=&quot;@&quot; /&gt;
		&lt;/li&gt;
		&lt;li&gt;
			&lt;label for=&quot;url&quot;&gt;Web(*):&lt;/label&gt;
			&lt;input id=&quot;url&quot; value=&quot;http://&quot; /&gt;
		&lt;/li&gt;
		&lt;li&gt;
			&lt;label for=&quot;tel&quot;&gt;Tel(*):&lt;/label&gt;
			&lt;input id=&quot;tel&quot; /&gt;
			하이픈(-)은 입력하지 마세요.
		&lt;/li&gt;
	&lt;/ul&gt;
	&lt;input type=&quot;submit&quot; value=&quot;전송&quot; /&gt;
&lt;/form&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
// &lt;![CDATA[
jQuery( function($) { // HTML 문서를 모두 읽으면 포함한 코드를 실행

	// 정규식을 변수에 할당
	// 정규식을 직접 작성할 줄 알면 참 좋겠지만
	// 변수 우측에 할당된 정규식은 검색하면 쉽게 찾을 수 있다
	// 이 변수들의 활약상을 기대한다
	// 변수 이름을 &#39;re_&#39;로 정한것은 &#39;Reguar Expression&#39;의 머릿글자
	var re_id = /^[a-z0-9_-]{3,16}$/; // 아이디 검사식
	var re_pw = /^[a-z0-9_-]{6,18}$/; // 비밀번호 검사식
	var re_mail = /^([\w\.-]+)@([a-z\d\.-]+)\.([a-z\.]{2,6})$/; // 이메일 검사식
	var re_url = /^(https?:\/\/)?([a-z\d\.-]+)\.([a-z\.]{2,6})([\/\w\.-]*)*\/?$/; // URL 검사식
	var re_tel = /^[0-9]{8,11}$/; // 전화번호 검사식

	// 선택할 요소를 변수에 할당
	// 변수에 할당하지 않으면 매번 HTML 요소를 선택해야 하기 때문에 귀찮고 성능에도 좋지 않다
	// 쉼표를 이용해서 여러 변수를 한 번에 선언할 수 있다
	// 보기 좋으라고 쉼표 단위로 줄을 바꿨다
	var
		form = $(&#39;.form&#39;),
		uid = $(&#39;#uid&#39;),
		upw = $(&#39;#upw&#39;),
		mail = $(&#39;#mail&#39;),
		url = $(&#39;#url&#39;),
		tel = $(&#39;#tel&#39;);

	// 선택한 form에 서밋 이벤트가 발생하면 실행한다
	// if (사용자 입력 값이 정규식 검사에 의해 참이 아니면) {포함한 코드를 실행}
	// if 조건절 안의 &#39;정규식.test(검사할값)&#39; 형식은 true 또는 false를 반환한다
	// if 조건절 안의 검사 결과가 &#39;!= true&#39; 참이 아니면 {...} 실행
	// 사용자 입력 값이 참이 아니면 alert을 띄운다
	// 사용자 입력 값이 참이 아니면 오류가 발생한 input으로 포커스를 보낸다
	// 사용자 입력 값이 참이 아니면 form 서밋을 중단한다
	form.submit( function() {
		if (re_id.test(uid.val()) != true) { // 아이디 검사
			alert(&#39;[ID 입력 오류] 유효한 ID를 입력해 주세요.&#39;);
			uid.focus();
			return false;
		} else if(re_pw.test(upw.val()) != true) { // 비밀번호 검사
			alert(&#39;[PW 입력 오류] 유효한 PW를 입력해 주세요.&#39;);
			upw.focus();
			return false;
		} else if(re_mail.test(mail.val()) != true) { // 이메일 검사
			alert(&#39;[Email 입력 오류] 유효한 이메일 주소를 입력해 주세요.&#39;);
			mail.focus();
			return false;
		} else if(re_url.test(url.val()) != true) { // URL 검사
			alert(&#39;[Web 입력 오류] 유효한 웹 사이트 주소를 입력해 주세요.&#39;);
			url.focus();
			return false;
		} else if(re_tel.test(tel.val()) != true) { // 전화번호 검사
			alert(&#39;[Tel 입력 오류] 유효한 전화번호를 입력해 주세요.&#39;);
			tel.focus();
			return false;
		}
	});

	// #uid, #upw 인풋에 입력된 값의 길이가 적당한지 알려주려고 한다
	// #uid, #upw 다음 순서에 경고 텍스트 출력을 위한 빈 strong 요소를 추가한다
	// 무턱대고 자바스크립트를 이용해서 HTML 삽입하는 것은 좋지 않은 버릇
	// 그러나 이 경우는 strong 요소가 없어도 누구나 form 핵심 기능을 이용할 수 있으니까 문제 없다
	$(&#39;#uid, #upw&#39;).after(&#39;&lt;strong&gt;&lt;/strong&gt;&#39;);

	// #uid 인풋에서 onkeyup 이벤트가 발생하면
	uid.keyup( function() {
		var s = $(this).next(&#39;strong&#39;); // strong 요소를 변수에 할당
		if (uid.val().length == 0) { // 입력 값이 없을 때
			s.text(&#39;&#39;); // strong 요소에 포함된 문자 지움
		} else if (uid.val().length &lt; 3) { // 입력 값이 3보다 작을 때
			s.text(&#39;너무 짧아요.&#39;); // strong 요소에 문자 출력
		} else if (uid.val().length &gt; 16) { // 입력 값이 16보다 클 때
			s.text(&#39;너무 길어요.&#39;); // strong 요소에 문자 출력
		} else { // 입력 값이 3 이상 16 이하일 때
			s.text(&#39;적당해요.&#39;); // strong 요소에 문자 출력
		}
	});

	// #upw 인풋에서 onkeyup 이벤트가 발생하면
	upw.keyup( function() {
		var s = $(this).next(&#39;strong&#39;); // strong 요소를 변수에 할당
		if (upw.val().length == 0) { // 입력 값이 없을 때
			s.text(&#39;&#39;); // strong 요소에 포함된 문자 지움
		} else if (upw.val().length &lt; 6) { // 입력 값이 6보다 작을 때
			s.text(&#39;너무 짧아요.&#39;); // strong 요소에 문자 출력
		} else if (upw.val().length &gt; 18) { // 입력 값이 18보다 클 때
			s.text(&#39;너무 길어요.&#39;); // strong 요소에 문자 출력
		} else { // 입력 값이 6 이상 18 이하일 때
			s.text(&#39;적당해요.&#39;); // strong 요소에 문자 출력
		}
	});

	// #tel 인풋에 onkeydown 이벤트가 발생하면
	// 하이픈(-) 키가 눌렸는지 확인
	// 하이픈(-) 키가 눌렸다면 입력 중단
	tel.keydown( function() {
		if(event.keyCode==109 || event.keyCode==189) {
			return false;
		}
	});
});
// ]]&gt;
&lt;/script&gt;
</pre>
</blockquote>
<h2>jQuery 코드 해설</h2>
<ul>
<li>변수 할당은 &#39;var 변수이름 = 할당 값&#39; &nbsp;형식으로 작성한다. re_* 라는 변수에 다양한 정규식을 할당했다. 정규식 표현은 사용자 입력 값이 유효한지 검사해 줄 것이다.</li>
<li>정규 표현식을 어떤 값과 비교하면 true 또는 false 값을 얻을 수 있다. true라면 form을 서밋하고 false라면 form 서밋을 중단한다. 정규 표현식으로 데이터 유효성을 확인하려면 &#39;정규식.test(어떤값)&#39; 형식으로 작성한다.&nbsp;</li>
<li>.val() 메소드는 선택한 input 또는 select 요소의 value 값을 구한다. uid.val()은 $(&#39;#uid&#39;).val()과 같다. 이렇게 val() 괄호 안쪽이 비어있으면 값을 구해온다. 만약&nbsp;val()&nbsp;괄호 안쪽에 명시적으로 어떤 값이 있으면 값을 구해오는 것이 아니라 값을 넣는다. 여기서 val() 값은 사용자가 #uid 인풋에 입력한 값이다.</li>
<li>if(좌변의 정규식과 != 우변의 사용자 입력 값이 같지 않으면) 사용자가 입력한 값은 오류이다. 이 조건문은 사용자 입력 값이 올바르지 않은 경우 {실행문}을 실행한다. 조건문 안에서는 ==(같음), !=(같지않음), !(아님), &gt;(보다큰), &lt;(보다작은), &gt;=(같거나 큰), &lt;=(같거나 작은) 이런 등호가 자주 쓰인다. 등호는 어떤 값을 true, false와 같은 참 거짓 또는 숫자와 자주 비교한다.&nbsp;</li>
<li>.after() 메소드는 선택한 요소의 다음(형제 노드) 순서에 문자열이나 HTML 요소를 넣는다. 이 예제는&nbsp;$(&#39;#uid, #upw&#39;).after(&#39;&lt;strong&gt;&lt;/strong&gt;&#39;) 두 요소를 선택하고 두 요소의 다음에 strong 요소를 넣었다. 반대 개념의 메소드 .before()는 선택한 요소의 이전 형제노드에 문자열을 넣는다.&nbsp;</li>
<li>.length 메소드는 선택한 HTML 요소의 개수 또는 val() 값의 문자 개수를 구해온다. 이 경우는 선택한 HTML 요소의 개수를 구한 것이 아니라 val() 값의 문자 개수를 구했다.</li>
<li>.next() 메소드는 선택한 요소의 바로 다음에 등장하는 형제를 선택한다.&nbsp;$(this).next(&#39;strong&#39;) 예제는 선택된 본인의 다음에 등장하는 strong 요소를 선택한다. 반대 개념의 메소드 .prev()는 이전 형제 요소를 선택한다.&nbsp;</li>
<li>.text() 메소드는 .val() 메소드와 사용법이 유사하다. HTML 요소 내부에 포함된 문자열을 구하거나 셋팅한다. 값이 비어있으면 값을 구해오지만 값이 설정되어 있으면 값을 셋팅한다. 이 코드는 값을 셋팅하는 예제만 포함하고 있다.</li>
<li>event.keyCode는 사용자가 누른 키의 값을 구한다. 키 값은 숫자를 반환하는데. 109, 189는 하이픈(-)의 키 값이다. 즉 하이픈(-) 키가 눌리면 keydown 동작을 취소함으로써 하이픈(-) 입력을 제한한다.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2011/07/20/1663/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>jQuery 입문: 네비게이션 만들기.</title>
		<link>http://naradesign.net/wp/2011/07/02/1634/</link>
		<comments>http://naradesign.net/wp/2011/07/02/1634/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 18:48:25 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[자바스크립트]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Navigation]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1634</guid>
		<description><![CDATA[오늘은 jQuery를 이용해서 네비게이션(div&#62;ul&#62;li&#62;ul&#62;li) 만들기를 해볼까 합니다. 수직 형태의 네비게이션과 수평 형태의 네비게이션 동작이 약간 달라서 예제를 두 개 준비 했습니다. 예제의 마크업은 같지만 수직, 수평 네비게이션을 구분하기 위해 클래스 이름을 다르게 지정하고 각각 다른 동작을 입혔습니다. CSS를 사용해서 수직 수평 모양을 지정할 수 있지만 적용하지 않았습니다. 수직 네비게이션 만들기 수직 네비게이션의 요구 조건은 다음과 [...]]]></description>
			<content:encoded><![CDATA[<p>오늘은 jQuery를 이용해서 네비게이션(div&gt;ul&gt;li&gt;ul&gt;li) 만들기를 해볼까 합니다. 수직 형태의 네비게이션과 수평 형태의 네비게이션 동작이 약간 달라서 예제를 두 개 준비 했습니다. 예제의 마크업은 같지만 수직, 수평 네비게이션을 구분하기 위해 클래스 이름을 다르게 지정하고 각각 다른 동작을 입혔습니다. CSS를 사용해서 수직 수평 모양을 지정할 수 있지만 적용하지 않았습니다.</p>
<h2>수직 네비게이션 만들기</h2>
<p>수직 네비게이션의 요구 조건은 다음과 같습니다.</p>
<ul>
<li>큰 메뉴를 클릭하면&nbsp;
<ul>
<li>열려있는 서브 메뉴가 모두 닫히고</li>
<li>클릭한 메뉴의 하위 메뉴가 열리며</li>
<li>클릭한 메뉴의 글꼴이 굵어진다&nbsp;</li>
</ul>
</li>
<li>포커스가 맺히면 클릭한 것처럼 동작한다</li>
</ul>
<h3>수직 네비게이션 예제</h3>
<p><script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<div class="gnbVr">
<ul>
<li><a href="#">#1</a>
<ul>
<li><a href="#">#1-1</a></li>
<li><a href="#">#1-2</a></li>
</ul>
</li>
<li><a href="#">#2</a>
<ul>
<li><a href="#">#2-1</a></li>
<li><a href="#">#2-2</a></li>
</ul>
</li>
<li><a href="#">#3</a>
<ul>
<li><a href="#">#3-1</a></li>
<li><a href="#">#3-2</a></li>
</ul>
</li>
</ul>
</div>
<p><script type="text/javascript">
$(function(){
	var gnbVr = $('.gnbVr');
	gnbVr.find('>ul>li>ul').hide();
	gnbVr.find('>ul>li>a[href=#]')
		.click(function(){
			gnbVr
				.find('>ul>li>ul:visible')
				.slideUp(200).parent('li')
				.removeClass('active')
				.find('>a')
				.css('fontWeight','');
			$(this)
				.next('ul:hidden')
				.slideDown(200)
				.parent('li')
				.addClass('active')
				.find('>a')
				.css('fontWeight','bold');
			return false;
		})
		.focus(function(){
			$(this).click();
		});
});
</script><br />
<h3>수직 네비게이션 HTML</h3>
<blockquote><pre>&lt;div class=&quot;<strong>gnbVr</strong>&quot;&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#1&lt;/a&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#1-1&lt;/a&gt;&lt;/li&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#1-2&lt;/a&gt;&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#2&lt;/a&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#2-1&lt;/a&gt;&lt;/li&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#2-2&lt;/a&gt;&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#3&lt;/a&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#3-1&lt;/a&gt;&lt;/li&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#3-2&lt;/a&gt;&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;
</pre>
</blockquote>
<h3>수직 네비게이션 JS</h3>
<blockquote><pre>&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
	var gnbVr = $(&#39;.gnbVr&#39;);
	gnbVr.find(&#39;&gt;ul&gt;li&gt;ul&#39;).hide();
	gnbVr.find(&#39;&gt;ul&gt;li&gt;a[href=#]&#39;)
		.click(function(){
			gnbVr
				.find(&#39;&gt;ul&gt;li&gt;ul:visible&#39;)
				.slideUp(200)
				.parent(&#39;li&#39;)
				.removeClass(&#39;active&#39;)
				.find(&#39;&gt;a&#39;)
				.css(&#39;fontWeight&#39;,&#39;&#39;);
			$(this)
				.next(&#39;ul:hidden&#39;)
				.slideDown(200)
				.parent(&#39;li&#39;)
				.addClass(&#39;active&#39;)
				.find(&#39;&gt;a&#39;)
				.css(&#39;fontWeight&#39;,&#39;bold&#39;);
			return false;
		})
		.focus(function(){
			$(this).click();
		});
});
&lt;/script&gt;
</pre>
</blockquote>
<h2>수평 네비게이션 만들기</h2>
<p>수평 네비게이션의 요구 조건은 다음과 같습니다.</p>
<ul>
<li>큰 메뉴를 마우스 오버 하면&nbsp;
<ul>
<li>열려있는 서브 메뉴가 모두 닫히고</li>
<li>마우스 오버 메뉴의 하위 메뉴가 열리며</li>
<li>마우스 오버 메뉴의 글꼴이 굵어진다</li>
</ul>
</li>
<li>포커스가 맺히면 마우스 오버한 것처럼 동작한다</li>
<li>메뉴 영역에서 마우스가 떠나면
<ul>
<li>서브 메뉴가 모두 닫히고</li>
<li>굵은 글꼴을 제거한다</li>
</ul>
</li>
</ul>
<h3>수평 네비게이션 예제</h3>
<div class="gnbHr">
<ul>
<li><a href="#">#1</a>
<ul>
<li><a href="#">#1-1</a></li>
<li><a href="#">#1-2</a></li>
</ul>
</li>
<li><a href="#">#2</a>
<ul>
<li><a href="#">#2-1</a></li>
<li><a href="#">#2-2</a></li>
</ul>
</li>
<li><a href="#">#3</a>
<ul>
<li><a href="#">#3-1</a></li>
<li><a href="#">#3-2</a></li>
</ul>
</li>
</ul>
</div>
<p><script type="text/javascript">
$(function(){
	var gnbHr = $('.gnbHr');
	gnbHr.find('>ul>li>ul').hide();
	gnbHr.find('>ul>li>a')
		.mouseover(function(){
			gnbHr
				.find('>ul>li>ul:visible')
				.slideUp(200)
				.parent('li')
				.removeClass('active')
				.find('>a')
				.css('fontWeight','');
			$(this)
				.next('ul:hidden')
				.slideDown(200)
				.parent('li')
				.addClass('active')
				.find('>a')
				.css('fontWeight','bold');
		})
		.focus(function(){
			$(this).mouseover();
		})
		.end()
		.mouseleave(function(){
			gnbHr
				.find('>ul>li>ul')
				.slideUp(200)
				.prev('a')
				.css('fontWeight','');
		});
});
</script><br />
<h3>수평 네비게이션 HTML</h3>
<blockquote><pre>&lt;div class=&quot;<strong>gnbHr</strong>&quot;&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#1&lt;/a&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#1-1&lt;/a&gt;&lt;/li&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#1-2&lt;/a&gt;&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#2&lt;/a&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#2-1&lt;/a&gt;&lt;/li&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#2-2&lt;/a&gt;&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#3&lt;/a&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#3-1&lt;/a&gt;&lt;/li&gt;
				&lt;li&gt;&lt;a href=&quot;#&quot;&gt;#3-2&lt;/a&gt;&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;
</pre>
</blockquote>
<h3>수평 네비게이션 JS</h3>
<blockquote><pre>&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
	var gnbHr = $(&#39;.gnbHr&#39;);
	gnbHr.find(&#39;&gt;ul&gt;li&gt;ul&#39;).hide();
	gnbHr.find(&#39;&gt;ul&gt;li&gt;a&#39;)
		.mouseover(function(){
			gnbHr
				.find(&#39;&gt;ul&gt;li&gt;ul:visible&#39;)
				.slideUp(200)
				.parent(&#39;li&#39;)
				.removeClass(&#39;active&#39;)
				.find(&#39;&gt;a&#39;)
				.css(&#39;fontWeight&#39;,&#39;&#39;);
			$(this)
				.next(&#39;ul:hidden&#39;)
				.slideDown(200)
				.parent(&#39;li&#39;)
				.addClass(&#39;active&#39;)
				.find(&#39;&gt;a&#39;)
				.css(&#39;fontWeight&#39;,&#39;bold&#39;);
		})
		.focus(function(){
			$(this).mouseover();
		})
		.end()
		.mouseleave(function(){
			gnbHr
				.find(&#39;&gt;ul&gt;li&gt;ul&#39;)
				.slideUp(200)
				.prev(&#39;a&#39;)
				.css(&#39;fontWeight&#39;,&#39;&#39;);
		});
});
&lt;/script&gt;
</pre>
</blockquote>
<p>오늘은 자세한 설명을 생략하겠습니다. 코드가 너무 길죠? 이렇게 메소드 체이닝이 길어지면 메소드 기준으로 줄을 바꿈으로써 코드 가독성을 높일 수 있습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2011/07/02/1634/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>jQuery 입문: 콘텐츠 로테이션 기능 만들기.</title>
		<link>http://naradesign.net/wp/2011/06/30/1593/</link>
		<comments>http://naradesign.net/wp/2011/06/30/1593/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 17:18:32 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[자바스크립트]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Rotation]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1593</guid>
		<description><![CDATA[저는 지난 포스팅에서 자바스크립트에 익숙하지 않다면서 &#8216;객체, 함수, 변수, 할당&#8217;이라는 용어를 사용했습니다. 솔직히 말해 저 용어들의 정확한 정의를 아직 모릅니다. &#160;&#8217;나중에 언젠가는 이해하게 되겠지&#8217;라는 막연한 기대를 하고 있을 뿐이예요. 기초부터 튼튼히 배우고 싶은 분들은 책을 찾아 보세요.(저도 책을 찾아 볼께요) 하지만 저런 용어들을 몰라도 jQuery를 시작할 수 있다는 이야기를 하고 싶습니다. 일단 흥미가 생겨야 책을 [...]]]></description>
			<content:encoded><![CDATA[<p>저는 지난 포스팅에서 자바스크립트에 익숙하지 않다면서 &#8216;객체, 함수, 변수, 할당&#8217;이라는 용어를 사용했습니다. 솔직히 말해 저 용어들의 정확한 정의를 아직 모릅니다. &nbsp;&#8217;나중에 언젠가는 이해하게 되겠지&#8217;라는 막연한 기대를 하고 있을 뿐이예요. 기초부터 튼튼히 배우고 싶은 분들은 책을 찾아 보세요.(저도 책을 찾아 볼께요) 하지만 저런 용어들을 몰라도 jQuery를 시작할 수 있다는 이야기를 하고 싶습니다. 일단 흥미가 생겨야 책을 볼 욕심도 날테니까요. 저는 HTML/CSS를 처음 배울 때에도 &#8216;요소, 선택자, 속성, 값&#8217;이 무엇을 의미하는지 몰랐습니다. 기초는 나중에 배우기로 하구요. 간단하게 지난 포스팅을 복습해 볼께요.</p>
<ul>
<li><a href="http://jquery.com/">jQuery 최신 버전 라이브러리</a>를 다운받아 서버에 올리거나 또는 <a href="http://code.jquery.com/jquery-latest.min.js">CDN 서버에 있는 최신 버전 jQuery 라이브러리</a>를 직접 링크할 수 있다.</li>
<li>jQuery 라이브러리는 문서 body가 닫히기 직전에 삽입하는 것이 사용자의 체감 성능(속도)을 높이는데 도움이 된다.</li>
<li>웹 브라우저가 jQuery 라이브러리를 모두 해석한 후에 직접 작성한&nbsp;jQuery 코드를 해석할 수 있도록 라이브러리 참조 코드 &lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt; 를 먼저 작성한다.</li>
<li>직접 작성할 jQuery 코드는 웹 브라우저가 HTML을 모두 해석한 이후에 실행하도록 준비 $(&#8216;document&#8217;).ready(function(){ &#8230; }) 또는 $(function(){ &#8230; }) 한다.</li>
<li>달러($) 기호 사용 때문에 다른 라이브러리와 충돌할 우려가 있다면 jQuery.noConflict(); 를 선언해서 충돌을 방지할 수 있다.</li>
<li>코드를 작성하는 보통의 순서는 &#8216;HTML 요소를 선택하고, 이벤트를 설정하고, 동작을 실행하기&#8217; 이다.</li>
<li>$(&#8216;&#8230;&#8217;) 괄호 안에 CSS 선택자를 넣어서 HTML 요소를 선택할 수 있다. HTML 요소, ID, CLASS를 포함할 수 있고 문자열(string)로 해석해야 하기 때문에 따옴표를 빼먹으면 안된다. JS 변수를 넣을 때는 따옴표를 사용하지 않는다.</li>
<li>점(.)을 찍어서 선택한 객체(요소)와 이벤트(클릭 등)를 연결할 수 있다. 이를 메소드 체이닝이라고 하는데 용어 설명은 생락할께요.(궁금하면 책을 ^^)</li>
</ul>
<p>지난 포스팅에서 확실하게 기억하고 넘어가야 할 것은&nbsp;jQuery의 일반적인 코드 작성 순서입니다. 아래와 같은 패턴이 자주 등장하므로 익혀 두는게 좋겠습니다.</p>
<blockquote>
<p>//&nbsp;한 줄로 작성하면&#8230;<br />
$(&#8216;<b>선택한요소에</b>&#8216;).<b>이벤트가발생하면</b>(<b>기능을</b>(){<b>실행한다</b>});</p>
<p>// 코드 가독성을 위해 여러 줄로 작성하면&#8230;<br />
$(&#8216;<b>선택한요소에</b>&#8216;).<b>이벤트가발생하면</b>(<b>기능을</b>(){&nbsp;<br />
&nbsp; &nbsp; <b>실행한다</b><br />
});</p>
<p>// 실제 코드는&#8230;<br />
$(&#8216;<b>button.red</b>&#8216;).<b>click</b>(<b>function</b>(){ // 선택한 요소에 이벤트가 발생하면 기능을<br />
&nbsp; &nbsp;&nbsp;$(&#8216;body&#8217;).css(&#8216;background&#8217;,'red&#8217;); // 실행한다<br />
});<span class="Apple-tab-span" style="white-space:pre">	</span></p>
</blockquote>
<p>오늘 학습 목표는 &#8216;콘텐츠 로테이션&#8217; 기능입니다. 일단 다음과 같은 HTML을 작성해 봅니다.</p>
<blockquote>
<p>&lt;ul&nbsp;class=&quot;<b>rotation</b>&quot;&gt;<br />
&nbsp; &nbsp; &lt;li&gt;#1&lt;/li&gt;<br />
&nbsp; &nbsp; &lt;li&gt;#2&lt;/li&gt;<br />
&nbsp; &nbsp; &lt;li&gt;#3&lt;/li&gt;<br />
&nbsp; &nbsp; &lt;li&gt;#4&lt;/li&gt;<br />
&lt;/ul&gt;<br />
&lt;button type=&quot;button&quot; class=&quot;<b>prev</b>&quot;&gt;PREV&lt;/button&gt;<br />
&lt;button type=&quot;button&quot; class=&quot;<b>next</b>&quot;&gt;NEXT&lt;/button&gt;</p>
</blockquote>
<p>li 항목 4개를 모두 노출하지 않고 첫 번째 li 항목만 화면에 보이도록 설정할 예정입니다. 그리고 PREV/NEXT 가운데 어떤 버튼을 누르는지에 따라서 정방향 또는 역방향의 li 항목을 로테이션 형식으로 표시합니다. 저는 다음과 같은 순서로 코드를 작성할 계획을 세웁니다.</p>
<ol>
<li>첫 번째 li를 제외한 나머지 li를 감춘다.</li>
<li>.prev 버튼을 누르면; 마지막 li 항목의 위치를 첫 번째로 옮기고;&nbsp;모든 li를 감춘 다음&nbsp;첫 번째 li만 표시한다.</li>
<li>.next 버튼을 누르면; 첫 번째 li 항목의 위치를 마지막으로 옮기고;&nbsp;모든 li를 감춘 다음&nbsp;첫 번째 li만 표시한다.</li>
</ol>
<p>얻고자 하는 표현은 다음과 같습니다.</p>
<div style="border:1px solid #ccc; padding:0 2em">
<ul class="rotation">
<li>#1</li>
<li>#2</li>
<li>#3</li>
<li>#4</li>
</ul>
<p><button type="button" class="prev">PREV</button> <button type="button" class="next">NEXT</button></p>
</div>
<p><script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script> <script type="text/javascript">
$(function(){
	$('.rotation>li:gt(0)').hide();
	function onlyFirst(){
		$('.rotation>li').hide().eq(0).show();
	}
	$('.prev').click(function(){
		$('.rotation>li:last').prependTo('.rotation');
		onlyFirst();
	});
	$('.next').click(function(){
		$('.rotation>li:first').appendTo('.rotation');
		onlyFirst();
	});
});
</script></p>
<p>생각을 코드로 옮기면 다음과 같습니다. 코드가 낮설더라도 두려워 할 필요는 없으니 일단 주석 위주로 봐주세요. 코드 해설은 아래에서 추가할께요.</p>
<blockquote>
<p>&lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt;<br />
&lt;script type=&quot;text/javascript&quot;&gt;<br />
$(function(){ // HTML 문서가 완전히 해석되면 포함한 코드를 실행한다.<br />
<span style="white-space:pre">	</span>$(&#8216;.rotation&gt;li:gt(0)&#8217;).hide(); //&nbsp;첫 번째 li를 제외한 나머지 li를 감춘다.<br />
<span style="white-space:pre">	</span>$(&#8216;.prev&#8217;).click(function(){ //&nbsp;.prev 버튼을 누르면<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>$(&#8216;.rotation&gt;li:last&#8217;).prependTo(&#8216;.rotation&#8217;); //&nbsp;마지막 li를 첫 번째로 옮기고<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>$(&#8216;.rotation&gt;li&#8217;).hide().eq(0).show();&nbsp;//&nbsp;모든 li를 감추고 첫 번째 li만 표시한다.<br />
<span style="white-space:pre">	</span>});<br />
<span style="white-space:pre">	</span>$(&#8216;.next&#8217;).click(function(){ //&nbsp;.next 버튼을 누르면<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>$(&#8216;.rotation&gt;li:first&#8217;).appendTo(&#8216;.rotation&#8217;); //&nbsp;첫 번째 li를 마지막으로 옮기고<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>$(&#8216;.rotation&gt;li&#8217;).hide().eq(0).show(); //&nbsp;모든 li를 감추고 첫 번째 li만 표시한다.<br />
<span style="white-space:pre">	</span>});<br />
});<br />
&lt;/script&gt;</p>
</blockquote>
<p>그런데 이 코드에는 반복이 존재합니다.&nbsp;&nbsp;.prev .next 버튼을 눌렀을 때&nbsp;&#8217;모든 li를 감춘 다음 첫 번째 li만 표시한다&#8217;&nbsp;$(&#8216;.rotation&gt;li&#8217;).hide().eq(0).show();&nbsp;부분을 똑같이 반복하죠. 개발자라면 본능적으로 이렇게 반복하는 코드가 나올 때 간결하게 만들어야 합니다. 반복되는 동작을 onlyFirst() 라는 함수에 담겠습니다. onlyFirst() 라는 함수에는 &#8216;모든 li를 감춘 다음 첫 번째 li만 표시한다&#8217; 라는 명령이 포함되어 있고 이 함수를 어디선가 호출하기 전까지는 스스로 실행하지 않습니다. 함수는 한번 만들어 두면 어디서 몇 번이든 호출할 수 있습니다. 그래서 바꾼 코드는 다음과 같습니다.</p>
<blockquote>
<p>&lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt;<br />
&lt;script type=&quot;text/javascript&quot;&gt;<br />
$(function(){<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>$(&#8216;.rotation&gt;li:gt(0)&#8217;).hide();<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>function onlyFirst(){ // onlyFirst라는 함수를 선언하고 호출하기 전까지 실행하지 않는다.<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>$(&#8216;.rotation&gt;li&#8217;).hide().eq(0).show(); //&nbsp;모든 li를 감춘 다음 첫 번째 li만 표시한다.<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>}<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>$(&#8216;.prev&#8217;).click(function(){<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>$(&#8216;.rotation&gt;li:last&#8217;).prependTo(&#8216;.rotation&#8217;);<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>onlyFirst(); // onlyFirst 함수를 호출한다.<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>});<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>$(&#8216;.next&#8217;).click(function(){<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>$(&#8216;.rotation&gt;li:first&#8217;).appendTo(&#8216;.rotation&#8217;);<br />
<span class="Apple-tab-span" style="white-space:pre">		</span>onlyFirst();&nbsp;// onlyFirst 함수를 호출한다.<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>});<br />
});<br />
&lt;/script&gt;</p>
</blockquote>
<p>jQuery 초보인 분을 위해 낮설 수도 있는 코드를 해설해 드리겠습니다. HTML이나 CSS에서 다양한 요소, 속성, 값, 선택자 사용법을 기억해 두어야 많은 표현이 가능한데요. jQuery도 똑같습니다. 많은 메소드를 알아두면 표현 능력이 향상되겠죠.</p>
<ul>
<li>$(&#8216;.rotation&gt;li:gt(0)&#8217;).hide();&nbsp;// .rotation 요소의 자식 li를 찾아 숨깁니다. 그런데 조건이 있습니다. 첫 번째 li를 제외한 모든 li를 찾습니다. <a href="http://api.jquery.com/gt-selector/">:gt()</a> 라는 선택자는 CSS에는 존재하지 않는 선택자입니다. jQuery에서 확장한 <b>G</b>reater <b>T</b>han 선택자 입니다. JS에서는 특별한 경우를 제외하고 순서(index)를 0부터 세기 때문에 li:gt(0)은 곧 &#8216;첫 번째 li보다 큰 li를 선택&#8217;하는 것입니다. 결과는 #2, #3, #4 항목을 선택해서 <a href="http://api.jquery.com/hide/">.hide()</a> 숨깁니다. :gt() 선택자는 반대의 개념인 <a href="http://api.jquery.com/lt-selector/">:lt()</a> 선택자도 있습니다. <b>L</b>ess <b>T</b>han 이겠죠.</li>
<li>function onlyFirst() { &#8230; } // 반복하는 기능을 이 함수에 담아두면 필요할 때 호출(재 사용)할 수 있습니다. 모든 li를 숨긴 다음 첫 번째 li만 표시하는 기능을 담으려고 합니다.</li>
<li>$(&#8216;.rotation&gt;li&#8217;).hide().eq(0).show(); //&nbsp;.rotation 요소의 자식 li를 모두 찾아내어 숨깁니다.&nbsp;<a href="http://api.jquery.com/eq/">.eq()</a> 메소드를 이용하여 index가 (0)인 li를 선택해서 <a href="http://api.jquery.com/show/">.show()</a> 보여줍니다. .show() 메소드는 .hide()의 반대 동작입니다.</li>
<li>$(&#8216;.prev&#8217;).click(function(){ &#8230; }); // .prev 요소를 선택하고 선택한 요소에 .click() 이벤트가 발생하면 function(){ &#8230; } 함수를 실행합니다.</li>
<li>$(&#8216;.next&#8217;).click(function(){ &#8230; }); //&nbsp;.next 요소를 선택하고 선택한 요소에 .click() 이벤트가 발생하면 function(){ &#8230; } 함수를 실행합니다.</li>
<li>$(&#8216;.rotation&gt;li:last&#8217;).prependTo(&#8216;.rotation&#8217;); // .rotation 요소의 자식 li 중에서 마지막 li:last를 선택합니다. <a href="http://api.jquery.com/last-selector/">:last</a> 가상 선택자는 CSS에는 존재하지 않는 jQuery에서 확장한 선택자입니다. <a href="http://api.jquery.com/first-selector/">:first</a>는 :last와 반대 개념입니다. <a href="http://api.jquery.com/prependTo/">.prependTo()</a> 메소드는 선택한 마지막 li를 잘라낸 다음 .rotation 요소의 첫 번째 자식 위치로 붙여 넣습니다. 반대의 개념으로 <a href="http://api.jquery.com/appendTo/">.appendTo()</a> 메소드는 선택한 요소를 지정한 요소의 마지막 자식 위치로 옮깁니다.</li>
<li>onlyFirst(); // onlyFirst() 함수를 호출합니다.</li>
</ul>
<p>당장 뭔가 할 수 있다는 것을 보여주면서 jQuery 학습 동기를 유발하면 좋겠다고 생각했습니다. 구미가 좀 당기시는지 모르겠네요.</p>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2011/06/30/1593/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>jQuery 입문: 레이어 토글 기능 만들기.</title>
		<link>http://naradesign.net/wp/2011/06/18/1536/</link>
		<comments>http://naradesign.net/wp/2011/06/18/1536/#comments</comments>
		<pubDate>Fri, 17 Jun 2011 19:41:10 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[자바스크립트]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1536</guid>
		<description><![CDATA[아직 자바스크립트에 익숙하지 않지만 jQuery 이야기를 해 보려고 합니다. 제가 jQuery를 잘 다루게 된다면 이미 잘 알고 있는 것에 흥미를 잃어버리는 습성 때문에 jQuery 글쓰기를 시도하지 않을것 같아요. 그래서 초심자인 지금이 가장 좋은 타이밍이라고 생각합니다. jQuery를 잘 다루려면 초급 수준의 HTML/CSS 지식이 필요합니다. jQuery는 지구상에서 가장 인기있는 자바스크립트 라이브러리입니다. 2011년 6월 현재 w3techs.com 통계에 따르면 [...]]]></description>
			<content:encoded><![CDATA[<p><!-- jQuery 예제 실행을 위한 --><script src="http://code.jquery.com/jquery-latest.min.js"><!-- /jQuery 예제 실행을 위한 --></script></p>
<p>아직 자바스크립트에 익숙하지 않지만 jQuery 이야기를 해 보려고 합니다. 제가 jQuery를 잘 다루게 된다면 이미 잘 알고 있는 것에 흥미를 잃어버리는 습성 때문에 jQuery 글쓰기를 시도하지 않을것 같아요. 그래서 초심자인 지금이 가장 좋은 타이밍이라고 생각합니다. jQuery를 잘 다루려면 초급 수준의 HTML/CSS 지식이 필요합니다.</p>
<p><a href="http://jquery.com/">jQuery</a>는 지구상에서 가장 인기있는 자바스크립트 라이브러리입니다. 2011년 6월 현재 <a href="http://w3techs.com/technologies/overview/javascript_library/all">w3techs.com</a> 통계에 따르면 지구촌 1/3 웹 사이트가 jQuery를 사용하고 있고, 자바스크립트 라이브러리를 사용하는 사이트 중 4/5 웹 사이트가 jQuery를 사용하고 있습니다. 이 정도면 대세라 부를만 하지요.</p>
<p>책을 통해서 자바스크립트나 jQuery를 배우려고 할 때 가장 불만인것은 거의 모든 책들이 기초부터 가르치려고 한다는 점입니다. 물론 저도 책을 쓴다면 그럴것 같긴 해요. 하지만 제가 성질이 급한건지 &quot;당장 써먹을 수 있는 것을 알려주면 참 좋을텐데&quot; 라는 생각을 항상 합니다. 블로그는 당장 써먹을 수 있는 것을 알려주기 참 좋은 도구 입니다. 누군가 궁금해 하는 것을 콕 짚어서 짧게 쓸 수 있고 실행 코드와 예제를 눈앞에 보여줄 수 있으니까요.</p>
<p>오늘의 목표는 자바스크립트를 통해 가장 빈번하게 구현하는 레이어 토글(열고 닫기)을 구현해 볼까 합니다. 아무리 급해도 jQuery 라이브러리를 불러오는 방법 정도는 설명하고 넘어갈께요.</p>
<h2>jQuery 라이브러리 참조하기</h2>
<p>jQuery 라이브러리는&nbsp;<a href="http://jquery.com/">http://jquery.com/</a>&nbsp;웹 사이트를 통해서 최신 버전을 내려받을 수 있습니다. 그러나 jQuery 라이브러리 파일을 다운받지 않고 CDN 서버가 제공하는 파일을 직접 링크해도 됩니다. 저는 jQuery 버전이 올라갈 때마다 업데이트 하는일이 귀찮아서 아예 항상 최신 버전으로 업데이트 되는 경로의 파일 <a href="http://code.jquery.com/jquery-latest.min.js">http://code.jquery.com/jquery-latest.min.js</a>&nbsp;를 링크해서 사용합니다. 다음과 같이 jQuery 라이브러리를 참조할 수 있습니다.</p>
<blockquote>
<p>&lt;head&gt;<br />
&nbsp; &nbsp; &#8230;<br />
&nbsp; &nbsp; &lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&nbsp; &nbsp; &#8230;<br />
&nbsp; &nbsp;&nbsp;&lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt;<br />
&lt;/body&gt;</p>
</blockquote>
<p>일부러 head와 body에 jQuery를 두 번 로드했는데요. 실제로는 이렇게 사용하면 안됩니다. head 또는 body 안쪽의 원하는 위치에 넣을 수 있다는 것을 보여준 것 뿐입니다. head 또는 body 안쪽에 포함할 수 있지만 head, body 밖에서 작성하면 HTML 문법 오류입니다. 자바스크립트를 head에 포함하면 웹 브라우저가 자바스크립트 파일을 해석하는 동안 아직 body 부분을 해석하기 못했기 때문에 사용자는 빈 페이지를 보고 있어야 합니다. 웹 브라우저는 HTML 코드를 작성 순서대로 해석한다는 사실을 잊지 마세요. 물론 순식간에 일어날 일이겠지만 웹 페이지 체감 속도가 느려진다는 뜻입니다. 따라서 body에 넣는 것을 권장하며 body 중에서도 body 가장 아래쪽 body가 끝나기 직전에 삽입하는 것이 좋습니다. body가 로드되기 전에 자바스크립트를 먼저 해석해야만 하는 경우도 간혹 있는데요. 그런 상황이 오면 그 때 head로 옮겨도 늦지 않습니다. 제 블로그도 body 끝나기 직전에 해석하도록 로드해 놨습니다.</p>
<h2>jQuery 준비 함수 선언</h2>
<p>로드된 jQuery 라이브러리를 이용하려면 jQuery() 또는 $() &nbsp;함수 안쪽에 jQuery 문법의 스크립트를 작성하면 됩니다. jQuery()와 $()는 같은 표현입니다. 달러 &#8216;$&#8217; 표시는 jQuery 객체를 의미합니다. jQeury 라이브러리가 로드되면 앞으로 무수히 많이 등장할 모든 달러 &#8216;$&#8217; 기호를 웹 브라우저는 무조건 jQuery 객체라고 해석할 것입니다. 웹 브라우저는 jQuery 또는 달러 &#8216;$&#8217; 기호를 만나면 &quot;제이쿼리구만. 이제부터 jQuery 라이브러리에 있는 규칙을 참고해서 뭔가를 선택하거나 실행할께.&quot; 라고 말할 것입니다. <u>아래 코드는 항상 jQuery 라이브러리보다 나중에 선언</u>합니다.&nbsp;jQuery 라이브러리가 먼저 해석이 되어야 jQuery 라이브러리를 이용할 수 있습니다.&nbsp;</p>
<blockquote>
<p>&lt;script type=&quot;text/javascript&quot;&gt;<br />
$<u>(document).ready</u>(function(){ <br />
&nbsp; &nbsp; // 여기에 작성한 코드는 브라우저가 HTML을 해석을 마칠 때까지 기다렸다가 실행합니다.<br />
});<br />
&lt;/script&gt;</p>
</blockquote>
<p>이 코드는&nbsp;<u>(document).ready</u> 부분을 지워서&nbsp;다음과 같이 축약할 수 있습니다.</p>
<blockquote>
<p>&lt;script type=&quot;text/javascript&quot;&gt;<br />
$(function(){&nbsp;<br />
&nbsp; &nbsp; //&nbsp;여기에 작성한 코드는 브라우저가 HTML을 해석을 마칠 때까지 기다렸다가 실행합니다.<br />
});<br />
&lt;/script&gt;</p>
</blockquote>
<p>그러나 다른 자바스크립트 라이브러리와 jQuery를 함께 사용할 우려가 있는 경우 아래와 같이 작성합니다. 또 다른 자바스크립트 라이브러리에서도 달러 &#8216;$&#8217; 기호를 객체로 사용하고 있어 충돌이 날 수 있기 때문입니다. 이렇게 jQuery.noConflict() 라고 시작 부분에 선언하고 jQuery(function(){ &#8230; }) 함수 괄호() 안에 &#8216;$&#8217;를 넣어 두면 jQuery(function($){ &#8230; }) 안쪽에서는 충돌 없이 안전하게 달러 &#8216;$&#8217; 기호를 사용할 수 있습니다.</p>
<blockquote>
<p>&lt;script type=&quot;text/javascript&quot;&gt;<br />
jQuery.noConflict();<br />
jQuery(function($){&nbsp;<br />
&nbsp; &nbsp; //&nbsp;여기에 작성한 코드는 브라우저가 HTML을 해석을 마칠 때까지 기다렸다가 실행합니다.<br />
});<br />
&lt;/script&gt;</p>
</blockquote>
<p>웹 브라우저가 HTML 해석을 마칠 때까지 기다렸다가 스크립트를 실행하는 이유가 뭘까요? HTML을 해석하기 전에 스크립트가 실행되면 HTML 요소를 선택해서 뭔가를 실행해야 하는 스크립트는 제대로 실행이 되지 않습니다. 예를 들어 .help 요소를 감춤 상태로 두고 웹 페이지를 로드해야 하는 경우 브라우저가 아직 HTML을 해석하기 전이라면 스크립트는 .help 요소를 찾지 못해 오류를 내고 말 것입니다. 자바스크립트 코드를 어쩔 수 없이 문서 head에 넣어서 HTML보다 먼저 읽히도록 설정해야 하는 경우가 발생할 수 있으니 아예 항상 이렇게 작성하는것이 안전합니다.</p>
<h2>요소를 선택하고, 이벤트를 설정하고, 동작을 실행하기</h2>
<p>jQuery 사용법은 CSS와 유사합니다. 일단 HTML 객체를 선택하는 방법이 CSS 선택자 사용법과 유사해서 CSS를 잘 다루는 사람은 jQuery에 매우 빠르게 익숙해 질 수 있습니다. jQuery 문법은 대부분 &#8216;선택 &#8211; 실행&#8217; 또는 &#8216;선택 &#8211; 이벤트 받으면 &#8211; 실행&#8217; 순으로 작성합니다. button.red 요소를 클릭하면 웹 페이지의 배경색을 붉게 바꾸는 코드를 한번 작성해 보겠습니다. button.white 요소를 클릭하면 다시 흰색이 될 것입니다.</p>
<blockquote>
<p>&lt;button class=&quot;red&quot;&gt;Red&lt;/button&gt; <br />
&lt;button class=&quot;white&quot;&gt;White&lt;/button&gt;&nbsp;</p>
<p>&nbsp;&lt;script type=&quot;text/javascript&quot;&gt;<br />
$(function(){&nbsp;<br />
&nbsp; &nbsp; $(&#8216;button.red&#8217;).click(function(){&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $(&#8216;body&#8217;).css(&#8216;background&#8217;,'red&#8217;);&nbsp;<br />
&nbsp; &nbsp; });<br />
&nbsp; &nbsp; $(&#8216;button.white&#8217;).click(function(){<br />
&nbsp; &nbsp; &nbsp; &nbsp; $(&#8216;body&#8217;).css(&#8216;background&#8217;,'white&#8217;);<br />
&nbsp; &nbsp; });<br />
});<br />
&lt;/script&gt;</p>
</blockquote>
<p>HTML 요소를 선택할 때 $(&#8216;&#8230;&#8217;) 안쪽에 CSS 선택자를 넣습니다.&nbsp;$(&#8216;button.red&#8217;)를 선택했죠.&nbsp;그리고 마침표(.)를 이용하여 .click() 이벤트를 연결했고 .click() 이벤트가 발생했을 때 어떤 함수 (function(){ &#8230; }) 를 실행할지 적어줍니다. 함수 안에서는 다시&nbsp;$(&#8216;body&#8217;)를 선택하고 마침표(.)를 이용하여 .css() 함수를 연결합니다. .css() 함수 안에는 이렇게 (&#8216;property&#8217;,'value&#8217;) 속성과 값을 넣었구요. 아래 버튼을 이용해서 작성한 예제 코드가 웹 페이지를 어떻게 변화시키는지 확인해 보세요.</p>
<p><button class="red">Red</button> <button class="white">White</button></p>
<p><script>
$(function(){ 
    $('button.red').click(function(){
        $('body').css('background','red');
    });
    $('button.white').click(function(){
        $('body').css('background','white');
    });
});
</script></p>
<p>그러나 오늘의 학습 목표는 이게 아니었죠. 레이어를 토글하는게 목표입니다. 레이어를 토글하는 것은 이 예제보다 조금 더 복잡합니다. 사실 if 문이 필요해요. if (레이어가 닫혀있으면) {열기를 실행} else if (레이어가 열려있으면) {닫기를 실행} 그런데 첫날부터 이렇게 어려운걸 가르칠 리가 없잖아요. 다음을 보세요.</p>
<h2>레이어 토글하기</h2>
<p>일단 다음과 같은 HTML을 머리속에 그려 넣으세요.</p>
<p style="margin-left: 40px; ">&lt;p&gt;&lt;a href=&quot;<b>#first</b>&quot;&gt;First Anchor&lt;/a&gt;&lt;/p&gt;<br />
&lt;p&nbsp;id=&quot;<b>first</b>&quot;&gt;First Layer&lt;/p&gt;<br />
&lt;p&gt;&lt;a href=&quot;<b>#second</b>&quot;&gt;Second Anchor&lt;/a&gt;&lt;/p&gt;<br />
&lt;p&nbsp;id=&quot;<b>second</b>&quot;&gt;Second Layer&lt;/p&gt;</p>
<p>제 머리속에는 아래와 같은 그림이 그려졌습니다. DOM 구조, HTML 요소, href 값, id 값 이름을 머리속에 넣었습니다.</p>
<ul>
<li>p &gt;&nbsp;a[href=<b>#first</b>]</li>
<li>p<b>#first</b></li>
<li>p &gt;&nbsp;a[href=<b>#second</b>]</li>
<li>p<b>#second</b></li>
</ul>
<p><span class="Apple-style-span">스크립트를 작성하기 위한 시나리오를 떠올립니다. 일단 레이어 요소 #first, #second를 모두 찾아내어 숨깁니다. 그 다음 href 값이&nbsp;</span>#first, #second인<span class="Apple-style-span">&nbsp;요소를 찾습니다. 클릭하는 경우 자신의 href 속성 값을 변수에 할당하고 변수에 할당된 값을 id 값으로 지니고 있는 요소를 선택한 다음 .toggle() 함수를 실행합니다. 마지막에 return false 를 추가하여 .click() 이벤트를 취소합니다. 웹 페이지가 자동으로 URL까지 스크롤 하는 것을 방지하는 목적입니다. 다음과 같은 코드를 작성 했습니다.</span></p>
<blockquote>
<p>&lt;script type=&quot;text/javascript&quot;&gt;<br />
$(function(){<br />
&nbsp; &nbsp; $(&#8216;<b>#first</b>, <b>#second</b>&#8216;).hide();<br />
&nbsp; &nbsp; $(&#8216;<b>a[href=#first], a[href=#second]</b>&#8216;).click(function(){<br />
&nbsp; &nbsp; &nbsp; &nbsp; var <b>myHref</b> = <u>$(this).attr(&#8216;href&#8217;)</u>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $(<b>myHref</b>).toggle();<br />
&nbsp; &nbsp; &nbsp; &nbsp; return false;<br />
&nbsp; &nbsp; });<br />
});<br />
&lt;/script&gt;</p>
</blockquote>
<p>사실 이 코드는 변수 var <b>myHref</b> =&nbsp;$(this).attr(&#8216;href&#8217;);&nbsp;를 사용하지 않음으로써 다음과 같이 더 단순하게 줄일 수 있습니다.</p>
<blockquote>
<p>&lt;script type=&quot;text/javascript&quot;&gt;<br />
$(function(){<br />
&nbsp; &nbsp; $(&#8216;<b>#first</b>,&nbsp;<b>#second</b>&#8216;).hide();<br />
&nbsp; &nbsp; $(&#8216;<b>a[href=#first], a[href=#second]</b>&#8216;).click(function(){<br />
&nbsp; &nbsp; &nbsp; &nbsp; $(<u>$(this).attr(&#8216;href&#8217;)</u>).toggle();<br />
&nbsp; &nbsp; &nbsp; &nbsp; return false;<br />
&nbsp; &nbsp; });<br />
});<br />
&lt;/script&gt;</p>
</blockquote>
<p>실행 결과는 다음과 같습니다. 링크를 클릭할 때 URL이 닫혀있으면 열리고 URL이 열려있으면 닫히는 동작입니다.</p>
<p><a href="#first">First Anchor</a></p>
<p id="first">First Layer</p>
<p><a href="#second">Second Anchor</a></p>
<p id="second">Second Layer</p>
<p><script type="text/javascript">
$(function(){ 
    $('#first, #second').hide();
	$('a[href=#first], a[href=#second]').click(function(){
		var myHref = $(this).attr('href');
		$(myHref).toggle();
		return false;
	});
});
</script></p>
<p>사용된 코드를 한 라인씩 설명하면 다음과 같습니다.</p>
<ul>
<li>$(&#8216;<b>#first</b>, <b>#second</b>&#8216;) &#8211; #first 요소와 #second 요소를 동시에 선택 합니다.</li>
<li>.hide() &#8211; 선택한 요소를 display:none 처리합니다.</li>
<li>$(&#8216;a[href=#first], a[href=#second]&#8216;) &#8211; href 속성 값이 #first, #second인 a 요소를 선택합니다.</li>
<li>.click() &#8211; 사용자가 클릭 이벤트를 발생시켰을 때 함수를 실행합니다.</li>
<li>var <b>myHref</b> = $(this).attr(&#8216;href&#8217;) &#8211; myHref 라는 변수를 만들고 변수에&nbsp;$(this).attr(&#8216;href&#8217;)&nbsp;값을 할당 했습니다. $(this)는 클릭된 a 요소입니다. 이어지는 .attr(&#8216;href&#8217;) 함수는 href 속성의 값을 구해옵니다. 만약 어딘가에서 .attr(&#8216;href&#8217;,'#five&#8217;) 이런 작성법을 본다면 이것은 href 속성에 #five라는 값을 셋팅하겠다는 뜻입니다. 그러나 값을 작성하지 않고 속성만 작성하는 경우에는 이미 셋팅되어 있는 값을 구해오라는 명령입니다. 다시한번 정리하면 이 코드는 클릭된 a 요소의 href 속성 값을 구해와서 myHref라는 변수에 담아라 입니다.</li>
<li>$(<b>myHref</b>).toggle() &#8211; myHref 변수에 저장된 값은 a 요소의 href 속성 값으로써 #first 아니면 #second 일 것입니다. 즉, 숨은 레이어 중에서 클릭된 a 요소의 목적지를 선택했습니다. 이어지는 .toggle() 함수는 선택한 요소에 대하여 display:none과 display:block 상태를 반복합니다. 선택한 요소가 닫혀 있으면 열고, 열려 있으면 닫히도록 동작합니다.</li>
<li>return false &#8211; .click() 함수가 실행되면 웹 브라우저는 URL까지 자동으로 스크롤을 하는데 이것을 원치 않는 경우 return false 를 반환하여 .click() 이벤트가 취소되었음을 브라우저에 알립니다. 단, 이미 실행된 동작은 취소가 되지 않기 때문에 레이어가 열리고 닫히는 동작은 실행이 취소되지 않습니다.</li>
</ul>
<p>CSS 선택자를 이용하여 DOM으로부터 HTML 요소를 선택하고, 이벤트 함수를 설정하고, 이벤트가 발생했을 때 실행할 동작을 정의하는 순서로 코드를 작성하는 경우가 대부분입니다. $(&#8216;&#8230;&#8217;)과 $(&#8230;)은 어떻게 다를까요? 괄호() 안에서는 홀따옴표 또는 쌍따옴표 모두 사용할 수 있는데요. 따옴표로 감싸는 경우 브라우저는 감싼 부분을 &#8216;string(문자열)&#8217;으로 해석합니다. 즉, HTML 요소 이름, 아이디 이름, 클래스 이름은 모두 따옴표를 사용해서 감싸줘야 합니다. 그러나 myHref와 같은 경우는 자바스크립트 변수이기 때문에 따옴표로 감싸면 안됩니다. 재미있는 것은 레이어를 토글할 때 .toggle() 함수만 사용할 수 있는게 아니라는 겁니다. 슬라이드 .slideToggle() 페이드 .fadeToggle() 함수를 사용하면 조금 더 미려한 동작이 가능합니다.</p>
<h2>참고</h2>
<ul>
<li>IBM에서 소개하는 &#8216;jQuery로 Ajax 개발을 단순화 하기&#8217;도 읽어보세요. -&nbsp;<a href="http://www.ibm.com/developerworks/kr/library/x-ajaxjquery.html">http://www.ibm.com/developerworks/kr/library/x-ajaxjquery.html</a></li>
<li>TAEYO.NET에서 소개하는 &#8216;jQuery 프로그래밍&#8217;도 읽어보세요. -&nbsp;<a href="http://www.taeyo.net/Columns/List.aspx?SEQ=29&amp;IDX=1">http://www.taeyo.net/Columns/List.aspx?SEQ=29&amp;IDX=1</a></li>
<li>제가 만든 jQuery UI 예제들도 참고해 보세요. -&nbsp;<a href="http://naradesign.net/xeui/">http://naradesign.net/xeui/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2011/06/18/1536/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>글쓰기 기술.</title>
		<link>http://naradesign.net/wp/2011/06/15/1525/</link>
		<comments>http://naradesign.net/wp/2011/06/15/1525/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 16:44:59 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[생활의 발견]]></category>
		<category><![CDATA[Writing]]></category>
		<category><![CDATA[글쓰기]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1525</guid>
		<description><![CDATA[몇일전 블로터포럼에 &#8216;우린 왜 스타 개발자가 없나&#8216;라는 주제의 글이 올라왔습니다. 그리고 트위터에는 스타 개발자는 어떤 모습인지 의견을 묻는 윤석찬님 트윗도 있었습니다. 저는 딱히 의견을 내지 않았지만 이런 생각을 하고 있습니다. 보통 스타 개발자라고 하면 해당 분야에서 유명하고 그 증거로 수천 수만 RSS 구독자와 트위터 팔로어 수를 보유한 사람이겠지요. 그리고 롤 모델로 인정받는 사람일 것이구요. 한편 [...]]]></description>
			<content:encoded><![CDATA[<p>몇일전 블로터포럼에 &#8216;<a href="http://www.bloter.net/archives/63682">우린 왜 스타 개발자가 없나</a>&#8216;라는 주제의 글이 올라왔습니다. 그리고 트위터에는 <a href="http://twitter.com/#!/channyun/status/80113806239469569">스타 개발자는 어떤 모습인지</a> 의견을 묻는 윤석찬님 트윗도 있었습니다. 저는 딱히 의견을 내지 않았지만 이런 생각을 하고 있습니다. 보통 스타 개발자라고 하면 해당 분야에서 유명하고 그 증거로 수천 수만 RSS 구독자와 트위터 팔로어 수를 보유한 사람이겠지요. 그리고 롤 모델로 인정받는 사람일 것이구요. 한편 그렇게 유명하지 않더라도 주변에서 롤 모델이 될만한 사람은 항상 있다고 생각합니다. 은둔 고수지만 아쉽게도 스타라고 부르지는 않죠.</p>
<p>저는 오늘 스타 개발자가 가진 어떤 능력에 대해서 말하고 싶습니다. 일단 스타 개발자는 회사에서 밀어줘서 되는 것이 절대 아니라고 생각합니다. 회사에서 밀어줘서 스타가 된 개발자 있으면 알려주세요. 저는 없다고 생각합니다. 100% 본인의 &#8216;커뮤니케이션 + 브랜딩&#8217; 능력이라고 생각합니다. 커뮤니케이션 능력이란 글을 쓰고 대화를 하는 능력을 말하구요. 브랜딩 능력이란 본인 스스로 자신의 가치를 높이는 마케팅 능력이라고 생각합니다.</p>
<p>여러분은 스타 개발자를 알게 된 경위가 무엇인가요? 제가 생각하는 스타 개발자는 100% 자기 블로그에 글을 씁니다. &#8216;글&#8217;이요. 이것이 오늘 제 포스팅의 주제입니다. 스타 개발자가 강의를 나가고 책을 쓰고 많은 사람들이 그를 알아보고 롤 모델로 삼는것은 모두 그의 블로그 때문이라고 생각합니다. 블로그가 유명해야 강의도 들어오고 출판사에서 연락도 옵니다. 블로그가 있어야 사람들이 SNS로 글도 전파해 줍니다. 간혹 블로그 없이 SNS 위주의 활동으로만 유명세를 타는 사람도 있지만 저는 그런 분들이 그 분야에 정통한 사람인지 확신을 갖지 못합니다. 저는 그 사람의 블로그 글을 읽고 그의 팬이 됩니다. 이렇게 스스로 대중과 커뮤니케이션 하고 브랜딩 하는 능력이 없는데 회사에서 멍석 깔아주면 잘 할까요? 아니라고 생각합니다.</p>
<p>굳이 스타 개발자 아니라도 범위를 좁혀서 적어도 그 분야에서 인정받는 개발자가 되려면 커뮤니케이션 기술이 있어야 한다고 생각합니다. 혹시라도 &quot;엔지니어가 개발만 잘 하면 그만 아닌가? 나는 개발 능력으로만 인정받고 싶은데. 스타 개발자까지는 되고 싶지 않아.&quot; 이런 생각을 가진 분이 있을 수 있습니다. 스타 개발자는 피곤할 수도 있습니다. 그러나 엔지니어가 개발만 잘 하면 될꺼라는 생각은 위험하다고 생각합니다. 혼자 일할 때 천재적인 기질을 보일지는 모르겠지만 커뮤니케이션 기술이 부족하면 협업하기 어려운 사람으로 보이게 됩니다.</p>
<p>저는 커뮤니케이션 기술이 글쓰기에서 나온다고 생각합니다. 글을 잘 쓰는 사람이 말도 잘한다고 생각하구요. 글은 잘 쓰지 않으면서 말을 잘 하는 사람을 신뢰하지 못합니다. 같은 분량의 책을 읽더라도 평소에 글을 쓰는 사람은 그렇지 않는 사람과 비교할 때 생각이나 지식의 깊이가 다르다고 생각합니다. 저는 효과적으로 커뮤니케이션하기 위한 도구로써 글을 잘 써야겠다는 생각을 해오며 틈틈이 오직 글을 잘 쓰기 위한 글을 읽기도 했습니다. 제가 배운 글쓰기 기술은 학문적이지 않고 실용적이며 커뮤니케이션 도구로써의 글쓰기 였습니다. 꼭 전달하고 싶은 내용만 간략하게 추려 봤습니다.</p>
<p>한국어 문법을 익히는 것은 커뮤니케이션 도구로써의 글쓰기 관점에서 볼 때 우선순위가 낮다고 판단해서 아예 언급조차 하지 않았습니다. 제 나름대로 정리한 글쓰기 기술은 다음과 같습니다. 주로 임재춘 교수의 &#8216;기술 글쓰기&#8217;에 관한 내용들을 찾아 읽어 봤는데 저는 &#8216;글쓰기 기술&#8217;이라고 제목을 뒤집어 달았습니다. 기술 글쓰기란 과학 또는 사실을 전달하는 글쓰기이고 제가 말하는 글쓰기 기술이란 일상에서 메일을 주고 받거나 블로그에 글을 작성하기 위한 비교적 가벼운 커뮤니케이션 기술입니다. 누구나 공감할 수 있을 정도의 내용으로만 쉽게 적으려고 노력했습니다. 일상에서 제가 요약한 정도만 유념하며 글을 써도 글을 잘 쓰는 사람이라고 생각합니다.</p>
<p><iframe src="https://docs.google.com/present/embed?id=dd9gps8g_715dwd5jpgz&amp;size=m" frameborder="0" width="600" height="451"></iframe></p>
<p><a href="http://naradesign.net/doc/WritingTechnique.pdf">&nbsp;PDF 버전</a> | <a href="http://naradesign.net/doc/WritingTechnique.txt">TEXT 버전</a></p>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2011/06/15/1525/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>HTML5 &amp; Responsive Web Design(반응형 웹 디자인).</title>
		<link>http://naradesign.net/wp/2011/05/27/1483/</link>
		<comments>http://naradesign.net/wp/2011/05/27/1483/#comments</comments>
		<pubDate>Thu, 26 May 2011 17:36:48 +0000</pubDate>
		<dc:creator>정찬명</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[웹 기획]]></category>
		<category><![CDATA[웹 디자인]]></category>
		<category><![CDATA[웹 표준]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Media Query]]></category>
		<category><![CDATA[Responsive Web Design]]></category>

		<guid isPermaLink="false">http://naradesign.net/wp/?p=1483</guid>
		<description><![CDATA[최근 블로그를 HTML5와 반응형 웹 디자인으로 리팩토링 했습니다. 제목은 거창한데 사실 별것 없습니다. 바꾸는데 하루도 걸리지 않았고 무엇을 바꾸었는지 소스 코드를 한 줄씩 설명해 보겠습니다. HTML5 HTML5로 변경하는데는 약 2~3시간 정도 밖에 걸리지 않았습니다. 하지만 고민했던 시간은 꽤 길었습니다. div, section, article 요소를 혼동하지 않기 위해서 의미를 정확하게 이해해야 했습니다. DTD를 변경하고 header, footer 같은 [...]]]></description>
			<content:encoded><![CDATA[<p>최근 블로그를 HTML5와 반응형 웹 디자인으로 리팩토링 했습니다. 제목은 거창한데 사실 별것 없습니다. 바꾸는데 하루도 걸리지 않았고 무엇을 바꾸었는지 소스 코드를 한 줄씩 설명해 보겠습니다.</p>
<h2>HTML5</h2>
<p>HTML5로 변경하는데는 약 2~3시간 정도 밖에 걸리지 않았습니다. 하지만 고민했던 시간은 꽤 길었습니다. div, section, article 요소를 혼동하지 않기 위해서 의미를 정확하게 이해해야 했습니다. DTD를 변경하고 header, footer 같은 새 요소들을 사용하면 IE6와 같은 낡은 브라우저에서 저 낮선 요소들을 어떻게 처리하는지 걱정도 했습니다.</p>
<h3>HTML5 DTD declaration</h3>
<p>HTML5 DTD는 매우 간단합니다. 예전에는 DTD를 외워보려고 갖은 애를 써도 그러지 못했는데 이제는 잊으려 애를 써도 잊지를 못합니다. &lt;!doctype html&gt; 이라고 적으면 끝입니다.&nbsp;case-insensitive.&nbsp;대소문자를 구별하지 않으니 대문자로 쓰거나 소문자로 쓰거나 섞어 쓰거나 상관 없습니다. HTML5는 DTD 뿐만 아니라 요소와 속성 모두 case-insensitive 입니다. 대소문자를 구별하지 않습니다. 그러나 요소 이름과 속성을 대문자로 쓴다고 하면 말리고 싶습니다. 다른 이유는 없구요. 보기 불편하니까요.</p>
<h3>Human language declaration</h3>
<p><a href="http://naradesign.net/wiki/WCAG_2.0#.EC.A7.80.EC.B9.A8_3.1_.EC.9D.BD.EC.9D.84_.EC.88.98_.EC.9E.88.EB.8A.94:_.EC.BD.98.ED.85.90.EC.B8.A0.EB.8A.94_.EC.9D.BD.EA.B3.A0_.EC.9D.B4.ED.95.B4.ED.95.A0_.EC.88.98_.EC.9E.88.EB.8F.84.EB.A1.9D_.EC.A0.9C.EC.9E.91.ED.95.B4.EC.95.BC_.ED.95.9C.EB.8B.A4.">WCAG 2.0 지침의 3.1.1 항목</a>을 보면 다음과 같은 구문이 있습니다.</p>
<blockquote>
<p>&quot;페이지 언어: 모든 웹 페이지의 기본 휴먼 랭귀지는 기계적으로 판단할 수 있어야 한다. (수준 A)&quot;</p>
</blockquote>
<p>휴먼 랭귀지란 사람이 쓰는 자연어를 말합니다. 수준 A란 최소한의 요구 조건 입니다.</p>
<blockquote>
<p>&lt;html lang=&quot;ko&quot;&gt;</p>
</blockquote>
<p>이렇게 html 요소에 한국어 휴먼 랭귀지 선언을 할 수 있습니다. 웹 문서에 휴먼 랭귀지를 선언하면 텍스트를 음성으로 변환해주는 시각장애인용 화면낭독기는 적합한 음성 엔진을 이용해서 웹 문서를 읽어줍니다. 예를 들어 로마자는 영어에만 쓰이는 것이 아니라 유럽에서 두루 쓰이는데요. 휴먼 랭귀지 속성을 선언하면 시각장애인용 화면 낭독기가 로마자를 어떻게 발음을 해야 하는지 정확히 알 수 있습니다. 한국형 웹 콘텐츠 접근성 지침인 KWCAG 2.0 지침에도 동일한 내용이 포함되어 있습니다. KWCAG 2.0에 포함되어 있다는 것은 향후 웹 접근성 품질마크 심사 지표에도 반영이 된다는 의미 입니다. 다음 회차의 웹 접근성 품질마크에는 이 기준이 적용되므로 웹 접근성 품질마크 심사에 도전하는 제작자는 반드시 휴먼 랭귀지를 작성해야 합니다. 이것은 HTML5 뿐만 아니라 다른 버전의 마크업 언어(HTML, XHTML)에도 동일하게 적용됩니다.</p>
<h3>HTML5 enabling script</h3>
<p>HTML5에는 여러가지 새로운 요소들이 등장 했습니다. 그러나 낡은 브라우저들은 이것을 알아차리지 못하는 문제가 있기 때문에 새로운 HTML5 요소들을 해석하거나 렌더링하지 않습니다. 도통 사람들이 업데이트를 하려고 하지도 않고 자동으로 업그레이드를 해주지도 않는 IE 6~8 브라우저가 그렇습니다. 우리는 <a href="http://remysharp.com/2009/01/07/html5-enabling-script/">낡은 브라우저가 새 요소들을 인식할 수 있도록 스크립트로 처리</a>할 수 있습니다. 이 스크립트는 문서 head에 포함해서 브라우저가 낮선 태그를 만나 허둥대는 일이 없도록 처리하는 것이 좋습니다.</p>
<blockquote>
<p>&lt;!&#8211;[if lt IE 9]&gt; <br />
&nbsp; &nbsp; &lt;script src=&quot;http://html5shim.googlecode.com/svn/trunk/html5.js&quot;&gt;&lt;/script&gt; <br />
&lt;![endif]&#8211;&gt;</p>
</blockquote>
<p>&quot;if lt IE 9 = if less-than IE 9&quot;&nbsp;IE 조건부 주석을 사용해서 IE9 보다 버전이 낮은 브라우저에서만 이 스크립트를 해석하도록 한 것입니다. 스크립트는 새로나온 HTML5 요소들을 브라우저가 인식할 수 있도록 추가해서 낡은 브라우저들이 HTML5 요소들을 해석하고 렌더링 할 수 있도록 해줍니다.</p>
<h3>CSS Reset</h3>
<p>새로 추가된 요소들이 inline 요소인지 block 요소인지 브라우저들은 모를 수 있습니다. 따라서 다음과 같이 CSS display 상태를 정의해 줍니다. HTML5에서 새롭게 추가된 요소들을 모두 block으로 선언 했습니다.</p>
<blockquote>
<p>header, footer, section, article, aside, nav, hgroup, details, menu, figure, figcaption { <br />
&nbsp; &nbsp; display: block <br />
}</p>
</blockquote>
<h3>HTML5 Markup &#8211; Document Structure</h3>
<p>의미론적 마크업을 글로만 배우면 막상 실무에 적용할 때 생각하지 못했던 고려사항들이 발생해서 고민도 되고 마크업을 하더라도 확신이 서지 않게 됩니다. 그런 의미에서 개인 블로그는 좋은 실험 재료인 것이죠. 제 블로그의 마크업 구조는 다음과 같습니다.&nbsp;</p>
<ul>
<li>div
<ul>
<li>header
<ul>
<li>h1</li>
</ul>
</li>
<li>section
<ul>
<li>article
<ul>
<li>h1</li>
</ul>
</li>
<li>section
<ul>
<li>h2</li>
</ul>
</li>
<li>section
<ul>
<li>h2</li>
<li>form</li>
</ul>
</li>
<li>nav</li>
</ul>
</li>
<li>nav
<ul>
<li>ul
<ul>
<li>li</li>
</ul>
</li>
</ul>
</li>
<li>footer</li>
</ul>
</li>
</ul>
<p>조금 더 자세히 풀어 볼까요?</p>
<ul>
<li><b>div</b> &#8211; 본문의 폭을 제한하거나 중앙으로 배치하는 역할만 합니다. 별 의미는 없기에 div 요소를 사용 했습니다.
<ul>
<li><b>header</b> &#8211; 사이트 제목과 설명이 등장하는 헤더 섹션입니다.
<ul>
<li><b>h1</b> &#8211; 사이트 최상위 제목.</li>
</ul>
</li>
<li><b>section</b> &#8211; 헤더, 풋터, 네비게이션 섹션이 아닌 일반적인 섹션입니다. section 요소는 웹 문서의 구조를 결정하는 핵심 요소 입니다. 섹션은 통상 하나의 헤딩과 명시적인 관계를 갖는것이 좋습니다.&nbsp;section &amp; hx의 관계는 마치&nbsp;fieldset &amp; legend 요소와 구조적으로 흡사합니다. section 안에 포함된 hx는 section 내부에 포함된 콘텐츠의 제목이 됨과 동시에 현재 웹 문서의 개요 역할을 합니다. 제 블로그의 경우 section 요소와 hx 요소 사이에 article이 끼어들어 section이 제목 없이 글 본문, 댓글, 댓글 쓰기 폼을 감싸는 역할을 하고 있습니다. section은 바로 아래 첫 번째 자식으로 hx를 갖추는 것을 구조적으로 권장하지만 제 경우는 그러지 못했네요. 하지만 꼭 그런 구조를 갖추지 못해도 괜찮습니다. hx가 없어도 section은 section 이니까요.
<ul>
<li><b>article</b> &#8211; 포스트 본문 섹션으로써 처음에는 section 요소와 어떤 의미적 차이를 지니는지 구분하기 어려웠습니다. 그러나 article 요소는 이 영역을 독립적으로 다른곳에 옮겨놔도 하나의 완전한 문서 또는 섹션이 될 수 있는 &#39;재 사용&#39; 가능한 또는 &#39;배포 가능한&#39; 본문 영역이라고 설명할 수 있겠습니다. section 요소와 마찬가지로 hx 요소를 갖는것을 강력하게 권장합니다. section과 article 요소 가운데 무엇을 써야 할지 망설여질 때에는 주변의 맥락과 분리하여 독립해도 하나의 완전한 콘텐츠가 되는지 아닌지를 판단해 보세요. 독립적이라면 article에 가깝고 현재 문서의 개요와 구조를 결정하는 역할이라면 section에 가깝습니다.
<ul>
<li><b>h1</b> &#8211; 포스트 본문 제목. h1이 두 번째 등장하죠. h1은 하나의 웹 페이지에 2번 이상 등장할 수 있습니다. W3C 웹 사이트도 이런 구조를 가지고 있으며 검색엔진 최적화에 좋습니다. 게시판에서 게시물 제목도 h1으로 마크업 하면 검색엔진으로부터 좋은 점수를 받을 수 있습니다. h1에 포함된 텍스트가 문서 헤드의 title 요소에도 들어가 있으면 금상 첨화죠. 제 블로그는 그렇게 처리되어 있습니다. 검색엔진이 좋아합니다.</li>
</ul>
</li>
<li><b>section</b> &#8211; 댓글 목록 섹션.
<ul>
<li><b>h2</b> &#8211; 댓글 목록 제목.</li>
</ul>
</li>
<li><b>section</b> &#8211; 댓글 쓰기 섹션.
<ul>
<li><b>h2</b> &#8211; 댓글 쓰기 제목.</li>
<li><b>form</b> &#8211; 댓글 쓰기 폼.</li>
</ul>
</li>
<li><b>nav</b> &#8211; 이전 포스트 / 다음 포스트 네비게이션.</li>
</ul>
</li>
<li><b>nav</b> &#8211; 사이트 글로벌 네비게이션.
<ul>
<li><b>ul</b> &#8211; 비순차 목록 컨테이너.
<ul>
<li><b>li</b> &#8211; 네비게이션 항목.</li>
</ul>
</li>
</ul>
</li>
<li><b>footer</b> &#8211; 저작물 이용 안내 및 RSS 주소를 담은 풋터 섹션.</li>
</ul>
</li>
</ul>
<h3>HTML5 Markup &#8211; Form Controls</h3>
<p>HTML5 Form의 위력은 아이폰을 사용하는 분들이면 쉽게 체감할 수 있습니다. 제 블로그에서는 다음과 같은 타입의 Form Control을 사용 했습니다. 제 블로그의 End-user 페이지에서 Form Control 이라고 해 봐야 검색창과 글쓰기창 뿐인데요. 적용 결과는 다음과 같습니다.</p>
<blockquote>
<p>&lt;input type=&quot;search&quot; autocomplete=&quot;on&quot; /&gt; <br />
검색창의 인풋 타입이 search 입니다.</p>
<p>&lt;input type=&quot;url&quot;&nbsp;autocomplete=&quot;on&quot;&nbsp;&nbsp;/&gt; <br />
댓글 쓰기 창에서 웹 사이트 주소 입력 인풋 타입이 url 입니다.</p>
</blockquote>
<p>이 밖에도 HTML5에는 새롭게 추가된 다양한 input type이 있습니다. 아래 항목들은 HTML5에 새롭게 추가된 input type 입니다. 링크를 클릭하면 실제로 코딩된 페이지를 만날 수 있습니다. 현재는 오페라 브라우저만 input type을 거의 완벽하게 지원하고 있습니다. 오페라 브라우저를 통해 예제를 확인해 보세요. 다른 브라우저와는 다르게 인풋을 좀 더 편리하게 작성할 수 있도록 도울 것입니다.</p>
<blockquote>
<ul>
<li><a href="http://naradesign.net/html5/form/input_type_search.html">input type=&quot;search&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_tel.html">input type=&quot;tel&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_url.html">input type=&quot;url&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_email.html">input type=&quot;email&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_number.html">input type=&quot;number&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_datetime.html">input type=&quot;datetime&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_datetime-local.html">input type=&quot;datetime-local&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_date.html">input type=&quot;date&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_time.html">input type=&quot;time&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_month.html">input type=&quot;month&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_week.html">input type=&quot;week&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_range.html">input type=&quot;range&quot;</a></li>
<li><a href="http://naradesign.net/html5/form/input_type_color.html">input type=&quot;color&quot;</a></li>
</ul>
</blockquote>
<p>HTML5의 인풋 타입을 적절하게 사용하면 아이폰 사용자에게 다음과 같이 문맥에 알맞는 자판을 보여줄 수 있습니다. 입력 커서가 인풋에 들어갔을 때 인풋 타입을 인식해서 최적화된 자판 배열을 표시합니다.</p>
<p>input type=&quot;search&quot; 일 때 아이폰은 자판에 Search 키를 보여줍니다. <a href="http://naradesign.net/html5/form/input_type_search.html">아이폰으로 input type=&quot;search&quot; 테스트 해보기</a>.<br />
<img alt="input 타입이 search 일 때 아이폰 자판 - 자판에 검색 버튼이 등장" height="215" src="http://naradesign.net/wp/wp-content/uploads/image/inputTypeSearch.gif" width="320" /></p>
<p>input type=&quot;tel&quot; 일 때 아이폰은 자판에 숫자와 + * # 키를 보여줍니다. <a href="http://naradesign.net/html5/form/input_type_tel.html">아이폰으로&nbsp;input type=&quot;tel&quot;&nbsp;테스트 해보기</a>.</p>
<p><img alt="input 타입이 tel 일 때 아이폰 자판 - 숫자 입력 전용 키패드가 등장" height="215" src="http://naradesign.net/wp/wp-content/uploads/image/inputTypeTel.gif" width="320" /></p>
<p>input type=&quot;url&quot; 일 때 아이폰은 자판에 .com과 Go 키를 보여줍니다.&nbsp;<a href="http://naradesign.net/html5/form/input_type_url.html">아이폰으로&nbsp;input type=&quot;url&quot;&nbsp;테스트 해보기</a>.</p>
<p><img alt="input 타입이 url 일 때 아이폰 자판 - .com .net .co.kr 등과 같은 빠른 입력 키가 등장" height="215" src="http://naradesign.net/wp/wp-content/uploads/image/inputTypeUrl.gif" width="320" /></p>
<p>input type=&quot;email&quot; 일 때 아이폰은 자판에 @와 . 키를 보여줍니다.&nbsp;<a href="http://naradesign.net/html5/form/input_type_email.html">아이폰으로&nbsp;input type=&quot;email&quot;&nbsp;테스트 해보기</a>.</p>
<p><img alt="input 타입이 tel 일 때 아이폰 자판 - Space 입력키 우측에 @키와 .(닷)키가 등장" height="215" src="http://naradesign.net/wp/wp-content/uploads/image/inputTypeEmail.gif" width="320" /></p>
<p>input type=&quot;number&quot; 일 때 아이폰은 자판에 숫자와 특수문자 키를 보여줍니다.&nbsp;<a href="http://naradesign.net/html5/form/input_type_number.html">아이폰으로&nbsp;input type=&quot;number&quot;&nbsp;테스트 해보기</a>.</p>
<p><img alt="input 타입이 number 일 때 아이폰 자판 - 숫자키와 특수문자 키가 등장" height="215" src="http://naradesign.net/wp/wp-content/uploads/image/inputTypeNumber.gif" width="320" /></p>
<h2>Responsive Web Design</h2>
<p>사용자가 어떤 해상도의 단말을 사용하든 그에 알맞는 뷰를 보여줄 수 있는 유연한 레이아웃 설계 기법입니다. 이름은 정말 근사하지만 막상 내용 뜯어보면 참 볼것 없습니다.</p>
<h3>Mobile Viewport Declaration</h3>
<p>모바일 단말기는 기본적으로 PC용 화면 전체를 작은 화면 안에서 모두 보여줍니다. 작은 화면에 전체를 담으려니 다음과 같이 글씨가 깨알만해져서 확대하지 않고는 보기가 어렵겠지요.(물론 아이폰4는 그냥 봐도 보입니다. 326dpi &amp; 640*960px을 자랑하는&nbsp;<a href="http://www.apple.com/iphone/features/retina-display.html">레티나 디스플레이</a>잖아요.) 적당히 확대한 다음 수직 수평 스크롤을 해 가면서 어렵게 읽을 수 밖에 없습니다.</p>
<p><img alt="모바일 뷰포트를 설정하지 않고 아이폰에서 보는 화면" height="480" src="http://naradesign.net/wp/wp-content/uploads/image/mobileViewPortNone.png" width="320" /></p>
<p>모바일 뷰포트를 선언하면 모바일 단말에 탑재된 웹 브라우저(Safari Mobile for the iPhone, Android browser, webOS browser in Palm Pre and Pixi devices, Opera Mini, Opera Mobile and BlackBerry browsers)는 웹 페이지를 적절히 크게 확대해서 보여줍니다.</p>
<blockquote>
<p>&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=2, user-scalable=yes&quot; /&gt;<br />
<a href="https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html#//apple_ref/doc/uid/TP40008193-SW1">meta 태그의 각 속성에 대한 자세한 설명</a></p>
</blockquote>
<p>그러나 콘텐츠의 너비가 크기 때문에 당연히 수평 스크롤이 필요합니다. 아래 이미지를 보면 아시겠지만 오른쪽에 내용이 더 있는데 잘려서 보이지 않습니다. 사용자는 여전히 수직 수평 스크롤을 모두 해야만 하는데 이것은 여간 짜증스러운 일이 아닙니다.</p>
<p><img alt="모바일 뷰포트를 설정하여 아이폰에서 적당히 확대된 화면" height="480" src="http://naradesign.net/wp/wp-content/uploads/image/mobileViewPort.png" width="320" /></p>
<p>그래서 필요한 것이 바로 Responsive Web Design 입니다. 사용자가 어떤 해상도의 단말기를 가지고 있더라도 알아서 유연하게 콘텐츠를 정돈해서 보여주는 기술이 필요합니다. 한때는 320px의 화면 너비가 모바일 화면 크기의 대세가 될 줄 알았지만 지금은 그렇지 않습니다. 매우 다양한 해상도를 지닌 디바이스들이 쏟아져 나오고 있지요. 그렇게 새로운 단말기가 등장할 때마다 그 해상도에 맞는 웹 페이지 화면을 추가로 개발하시겠습니까? 세상에 그런 삽질을.</p>
<h3>CSS3 Media Queries</h3>
<p>CSS3에는 Media Query 라는 명세가 있고 최신 브라우저들(IE9, Chrome, Safari, Firefox, Opera)과 아이폰용 모바일 사파리 브라우저도 이를 지원하고 있습니다. 다음은 모바일 뷰포트를 설정해서 적당히 확대한 다음 Media Query를 이용해서 레이아웃을 알맞게 정돈한 제 블로그의 모바일 화면 입니다. 아름답지요.</p>
<p><img alt="" height="480" src="http://naradesign.net/wp/wp-content/uploads/image/mobileViewPort.MediaQuery.png" width="320" /></p>
<p>미디어 쿼리 문법을 간단하게 살펴보죠. 제 블로그는 모바일 환경이든 아니든 불문하고 브라우저의 너비가 980px 이하로 작아지면 화면 우측에 있는 글로벌 네비게이션이 화면 아래쪽으로 뚝 떨어집니다. 지금 브라우저의 폭을 조절해서 한번 확인해 보세요.</p>
<p>@media all and (min-width:980px) { &nbsp; &nbsp;/* 화면 너비가 980px 이상이고 미디어쿼리를 지원하는 브라우저라면 아래 코드를 해석함 */<br />
&nbsp; &nbsp;&nbsp;.content{ float:left; width:600px } &nbsp; &nbsp;/* 콘텐츠 플롯하고 너비를 고정 */<br />
&nbsp; &nbsp;&nbsp;.nav{ float:right; width:330px } &nbsp; &nbsp;/* 네비게이션 플롯하고 너비를 고정 */<br />
}</p>
<p>딱 이정도의 사용법만 알아도 반응형 웹 디자인은 <strike><a href="http://mediaqueri.es/">게임 끝</a></strike>입니다. <u>게임 끝 아닙니다. <a href="http://naradesign.net/wp/2012/01/18/1742/">모바일 퍼스트 CSS 전략</a>에 대해 더 자세히 알아보세요.</u></p>
<ul>
<li>W3C Media Queries -&nbsp;<a href="http://www.w3.org/TR/css3-mediaqueries/">http://www.w3.org/TR/css3-mediaqueries/</a></li>
<li>CSS3 Media Queries Vol.1 -&nbsp;<a href="http://mydeute.com/txp/article/631">http://mydeute.com/txp/article/631</a></li>
<li>Mobile first strategy for CSS designer -&nbsp;<a href="http://naradesign.net/wp/2012/01/18/1742/">http://naradesign.net/wp/2012/01/18/1742/</a></li>
</ul>
<p>&nbsp;게임 끝.</p>
]]></content:encoded>
			<wfw:commentRss>http://naradesign.net/wp/2011/05/27/1483/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
	</channel>
</rss>

