Rollover Menu

  • jQuery
  • JavaScript
  • CSS
  • HTML

HTML

							
  • jQuery
  • JavaScript
  • CSS
  • HTML

메뉴 부분은 ul/li 태그로 만들고 li태그 안에 a태그를, 그 안에 img 태그를 기술하고 있습니다. li 태그 뒤와 그 다음 li태그 사이를 <!-- 와 -->로 코멘트 처리하고 있는 것은 CSS로 li태그를 수평으로 나열했을 때에 빈틈이 생기지 않게 하기 위해서입니다. 코멘트를 넣지 않으면 CSS로 display:inline을 설정했을 때 반각 스페이스분의 공백이 나타납니다. 지워서 확인!

Step1

							$(document).ready(function(){
								$("img[src='/florakid_lib/images/sample/jquery.jpg']").mouseover(function(){
									$(this).attr("src","/florakid_lib/images/sample/jquery_on.jpg");
								}).mouseout(function(){
									$(this).attr("src","/florakid_lib/images/sample/jquery.jpg");
								});

								$("img[src='/florakid_lib/images/sample/javascript.jpg']").mouseover(function(){
									$(this).attr("src","/florakid_lib/images/sample/javascript_on.jpg");
								}).mouseout(function(){
									$(this).attr("src","/florakid_lib/images/sample/javascript.jpg");
								});

								$("img[src='/florakid_lib/images/sample/css.jpg']").mouseover(function(){
									$(this).attr("src","/florakid_lib/images/sample/css_on.jpg");
								}).mouseout(function(){
									$(this).attr("src","/florakid_lib/images/sample/css.jpg");
								});

								$("img[src='/florakid_lib/images/sample/html.jpg']").mouseover(function(){
									$(this).attr("src","/florakid_lib/images/sample/html_on.jpg");
								}).mouseout(function(){
									$(this).attr("src","/florakid_lib/images/sample/html.jpg");
								});
							});// end ready						
						

셀렉터 부분에는 속성 셀렉터를 이용하여 "src"속성이 images/javascript.jpg인 이미지 태그"를 지정하고 있습니다.
mouseover 이벤트가 발생하면 attr()를 사용하여 img태그의 src속성을 롤오버 되었을 때 이미지인 "images/javascript_on.jpg"로 변경합니다. 그리고 mouseout 이벤트가 발생하면 원래의 "images/javascript.jpg"로 돌아오도록 설정하고 있습니다.
위와 같은 처리를 롤오보 효과를 표현하고 싶은 이미지의 수만큼 반복해서 기술하면 롤오보 효과를 내는 내비게이션 바를 완성할 수 있습니다.

Step2 - 범용적인 롤오보로 개선하기

							$(document).ready(function(){
								$("img", "ul.rollover").mouseover(function(){
									$(this).attr("src",$(this).attr("src").replace(/^(.+)(\.[a-z]+)$/, "$1_on$2"));
								}).mouseout(function(){
									$(this).attr("src",$(this).attr("src").replace(/^(.+)_on(\.[a-z]+)$/, "$1$2"));
								});
							});// end ready				
						

셀렉터로 ul.rollover 아래의 img 태그를 지정하고 mouseover 이벤트와 mouseout 이벤트로 롤오버 처리를 설정하고 있습니다. replace()는 문자열(텍스트)을 치환하는 javascript 명령입니다. 상기의 스크립트에서는 마우스 포인터가 올라가는 img 태그의 src 속성 안에 문자열(이미지의 경로)를 attr()로 가져와서 replace()로 확장자 앞에 "_on"을 추가합니다. 치환 처리에는 "정규표현"이라는 방법을 사용하고 있습니다.

Step3 - 이미지 preload 처리 추가

							$(document).ready(function(){
								$("img", "ul.rollover").mouseover(function(){
									$(this).attr("src",$(this).attr("src").replace(/^(.+)(\.[a-z]+)$/, "$1_on$2"));
								}).mouseout(function(){
									$(this).attr("src",$(this).attr("src").replace(/^(.+)_on(\.[a-z]+)$/, "$1$2"));
								}).each(function () {
									$("").attr("src", $(this).attr("src").replace(/^(.+)(\.[a-z]+)$/, $1_on$2));
								});
							});// end ready			
						

롤오버로 이미지를 변경할 때 src 속성을 변경하면서부터 브라우저가 이미지를 다운로드하여 롤오버 할 때까지는 짧지만 시간 비용이 발생됩니다. 짧은 시간이지만 이 시간으로 인해 이미지가 바뀌는 순간 깜박임이 발생하는 경우가 있습니다. 롤오버 효과의 마무리 작업으로 이미지가 먼저 다운로드 되어 브라우저가 캐시되는 "preload"(미리 읽기)의 처리를 추가하는 방법을 소개합니다.

.each 이후가 추가된 부분입니다. each(function() {...})는 셀렉터로 지정한 태그에 포함된 태그를 하나씩 가져와서 {...} 안의 처리를 반복해서 실행하는 명령입니다.
function() {...}의 안에는 $("")라는 낯선 기술 방법이 있습니다. jQuery에서는 #("...")안에 HTML을 기술하면 HTML을 "내부적"으로 만듭니다. 내부적으로 만든 HTML은 HTML을 표시하는 명령을 주지 않는 한 브라우저에 표시되지 않습니다.
이번에는 preload 동작을 구현하고 싶을 뿐이므로 브라우저에 표시할 필요는 없고 내부적으로 HTML을 만들어 두기만 하면 됩니다. 만든 img 태그의 src속성에는 attr()을 사용하여 롤오버 뒤에 이미지 파일명(원래 이미지의 파일명에 "_on"을 붙인 것)을 설정합니다. 여기까지 처리하면 each()에 의해 .rollover 아래의 img 태그 전체에 적용되어 롤오버에 사용하는 이미지는 preload할 수 있게 됩니다.

** 문자열 치환을 편리하게 해주는 정규표현 **

"정규표현"이라는 것은 문자열의 특징을 문자와 특수기호(메타문자)의 조합으로 나타낸 것입니다. 정규표현을 사용하면 복잡하게 표시된 문자열을 한번에 치환하거나 특정 패턴을 포함하는 복수의 문자열을 뽑아내거나 하는 것이 가능합니다. 정규표현은 javascript외에 많은 프로그래밍 언어에서 이용할 수 있고 Eclipse 등의 많은 소프트웨어에서도 지원하고 있습니다.

JavaScript에서 문자열을 치환하는 replace()에서는 아래와 같은 기술로 "문자열"의 내용으로부터 "패턴"이 일치하는 부분을 "치환후의 문자열"로 바꿀 수 있습니다.

							문자열.replace(패턴, 치환후의 무문자열)
						

상기의 샘플에서 등장하는 "_on"을 붙이는 처리를 한번 더 확인해 봅시다.

							$(this).attr("src").replace(/^(.+)(\.[a-z]+)$/, "$1_on$2");
						

$(this).attr("src")는 마우스 포인터가 올라가는 img 태그의 src 속성을 지정하고 있으므로 "images/javascript"와 같은 문자열을 가져올 수 있습니다. 즉 아래의 스크립트와 같은 의미입니다.

							"images/javascript.jpg".replace(/^(.+)(\.[a-z]+)$/, "$1_on$2")
						

replace()의 패턴에서는 /~/의 사이에 정규표현을 기술합니다. 맨 앞의 "^"는 "문자열의 맨 앞", 맨 뒤에 "$"은 "문자열의 맨 뒤"를 의미합니다. ^의 뒤에 (.+)는 "1개 이상의 어떤 문자의 반복"을 나타내고 그 뒤에 (\.[a-z]+)는 ".과 그 바로 뒤에 이어지는 1개 이상의 알파벳의 반복"을 의미합니다. 예를 들어서 "images/javascript.jpg"라는 문자열이라면 (.+)가 "images/javascript"를, (\.[a-z]+)는 ".jpg"의 부분을 표현합니다.

치환 후의 무문자열은 $1_on$2로 되어 있습니다. $1은 패턴에 지정한 최초 괄호의 내용(images/javascript), $2에는 두 번째 괄호 안의 내용(.jpg)이 들어옵니다. $1과 $2의 사이에 "_on"을 넣는 것으로 파일명 뒤(확장자 앞)에 "_on"이 붙는 문자열로 치환하는 처리가 됩니다.