자바스크립트 해시체인지 이벤트는 단독으로 사용하는 것보다 Ajax 기술을 접목했을 때 이상적인 결과물을 만들어낼 수 있습니다. 대표적인 사례를 들어보면, 페이스북 트위터 등의 소셜 미디어가 있습니다. 그리고 인터넷 가계부인 후잉가계부에서도 이 방법을 잘 활용하고 있습니다. Ajax와 해시체인지 이벤트를 활용하면 문서 이동 없이 다른 문서에 있는 내용을 그대로 가져올 수 있습니다. 이 글에서는 Ajax와 웹브라우저 앵커(해시태그)를 활용하는 동적 페이지 이동 개념을 설명하겠습니다.
※ 이 글에서 소개하는 해시체인지 이벤트를 활용한 동적 페이지 이동 기능은 jQuery가 필요합니다. jQuery를 블로그 또는 사이트에서 사용하는 방법은 다음 글을 참고하시기 바랍니다. → 2017/11/08 [자바스크립트] CDN을 활용하여 jQuery 사용하는 방법 by Walter Erzsamatory
예제 소스코드로 시작하기
이 글에서 설명하는 소스코드는 아래와 같습니다. 예제 소스코드는 이전 블로그에서 실제로 사용되었습니다. 블로그 상단 메뉴를 클릭하면 링크 이동은 발생하지 않으면서 문서 내용이 변경되는 스크립트입니다.
문서 일부만 불러오면 되는 이유로 이 방법은 속도면에 있어서 큰 장점이 있습니다. 그러나 이 방법으로 자바스크립트 결과 값까지는 못 가져옵니다. 따라서 구글 애드센스와 같은 자바스크립트가 포함되어 있는 경우에는 오류가 발생합니다. 그러므로 이 글에서 설명하는 소스코드는 HTML(CSS 포함)만으로 구성된 문서를 불러올 때에만 사용해야 합니다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="utf-8"/> <title>해시체인지 이벤트 테스트 페이지</title> <script type="text/javascript" src="/scripts/jquery.min.js"></script> <script> // 해시가 변경되었을 때 실행합니다. $(window).on('hashchange', function () { goToFromHash(); }); // 윈도우가 모드 로드되었을 때 실행합니다. // goToFromHash() 함수에 매개변수를 넣음으로써 윈도우 로드 후 가장 처음 실행되는 함수임을 알립니다. // 매개변수를 전달함으로써 해시가 변경되지 않는 상황에 대처할 수 있습니다. $(window).on('load', function () { goToFromHash('onload'); }); // 해시를 분석하여 적당한 페이지로 이동할 때 사용하는 함수입니다. function goToFromHash (a) { // 해시태그에서 맨 앞의 #을 제거하고 공백을 %20으로 치환합니다. // 해시태그를 쉽게 분석하기 위한 작업니다. var hashtag = location.hash.substring(1, location.hash.length).replace(/ /gi, '%20'); // 태그 페이지의 이중 주소 정규표현식입니다. var tag = /^tag\/([\s|0-9|a-z|A-Z|ㄱ-ㅎ|ㅏ-ㅣ|가-힝|\-|\_]+)$/i; // 글 목록 페이지의 이중 주소 정규표현식입니다. var archive = /^archive\/([0-9]+)$/i; var category = /^category\/([\s|0-9|a-z|A-Z|ㄱ-ㅎ|ㅏ-ㅣ|가-힝|\%|\/]+)$/i; // 검색 페이지의 이중 주소 정규표현식입니다. var s = /^search\/([\s|0-9|a-z|A-Z|ㄱ-ㅎ|ㅏ-ㅣ|가-힝|\%|\/|\-|\_|\[|\]]+)$/i; // 스크립트에서 정한 해시를 입력한 경우에만 해시체인지 함수를 실행하도록 합니다. (보안) // 자바스크립트에서 정규표현식을 어떻게 적용하는지 주의깊게 살펴봅니다. if (hashtag == 'guestbook' || hashtag == 'tag' || hashtag == 'location' || hashtag == 'keylog' || tag.test(hashtag) || archive.test(hashtag) || s.test(hashtag) ) { // ID가 content인 블럭의 내용을 해당 해시에 맞는 내용으로 바꿉니다. (실시간) jQuery('#content').load('http://www.erzsamatory.net/'+hashtag+' #content'); // 내용이 변경되었으니 스크롤바를 최상단으로 옮깁니다. jQuery(window).scrollTop(0); } else if (category.test(hashtag) || hashtag == 'category') { // 글 목록 페이지를 이동시킬 때 실행되는 작업입니다. 이중 주소를 처리합니다. jQuery('#content').load('http://www.erzsamatory.net/'+hashtag+' #content'); jQuery(window).scrollTop(0); } else if (hashtag == 'home') { // 해시가 home일 때 실행합니다. jQuery('#content').load('http://www.erzsamatory.net/ #content'); jQuery(window).scrollTop(0); } else if (!hashtag && a != 'onload') { // 매개변수로 'onload'가 입력되지 않았을 때, // 해시가 비어있을 때 새로고침합니다. // 해시가 없는 페이지로 뒤로가기를 하였을 때를 대처하기 위한 스크립트입니다. location.reload(); } } </script> </head> <body> <div style="padding:10px; font-size:12px;"> <a href="#home">홈</a> <a href="#tag">태그</a> <a href="#tag/웹프로그래밍">|웹프로그래밍 태그|</a> <a href="#category">글 목록</a> <a href="#category/컴퓨터 및 첨단기술">|컴퓨터 및 첨단기술|</a> <a href="#guestbook">방명록</a> </div> <div style="height:30px;"></div> <div id="content" style="border:3px solid #efefef;"></div> </body> </html>
예제 소스코드를 세 부분으로 나누어 분석해보도록 하겠습니다. 가장 먼저 이 스크립트 핵심 함수인 goToFromHash() 함수를 설명하겠습니다. 그 다음으로는 HEAD 이벤트 스크립트 부분과 BODY 부분을 설명하겠습니다.
goToFromHash() 함수
이 함수는 사용자가 요청한 앵커(해시태그)를 분석한 후 해당 문서를 불러오는 역할을 수행합니다. 웹브라우저 앵커가 변경되는 것을 감지하여 개별 앵커에 해당하는 문서를 불러오는 기능을 합니다. 따라서 이 함수는 예제 소스코드에서 중요한 역할을 담당하고 있다고 보면 됩니다. 예제 소스코드에서는 블로그 홈, 태그 페이지, 글 목록 페이지, 방명록 페이지를 불러오는 기능을 구현하였습니다.
방문자가 해당 문서의 앵커를 웹브라우저에 직접 입력할 수도 있습니다. 그리고 예제 스크립트에는 띄어쓰기와 이중 주소에 대한 처리를 위한 스크립트가 포함되어 있습니다.
이중 주소 처리를 위하여 예제 소스코드에서는 자바스크립트 정규표현식을 활용하였습니다. 이중 주소로 표현되는 문서로는 태그 페이지, 글 목록 페이지 등이 있습니다. 웹브라우저에 따라 지원여부가 달라지지만 일부 웹브라우저에서는 URL에 포함되어 있는 공백을 지원하지 않기 때문에 예제 스크립트에서는 띄어쓰기를 %20으로 강제로 변환하여 모든 웹브라우저에서 잘 작동하도록 하였습니다.
이 기능을 구현하는데 jQuery가 필요한 이유는 jQuery load() 메소드를 사용하기 때문입니다. jQuery load() 메소드는 같은 도메인에 소속된 다른 문서의 내용을 불러올 때 사용합니다. 이 메소드는 Ajax 기술을 구현할 때 사용하는 메소드입니다. 특히 load() 메소드는 해당 문서의 아이디 또는 클래스만 지정하면 해당되는 내용만 별도로 불러올 수도 있습니다. 예제 스크립트에서는 해당 문서의 #content(ID가 content인 부분)만 불러오고 있습니다. 이렇게 함으로써 방문자는 원하는 문서의 전체내용을 불러올 필요 없이 content만 불러오면 되므로 빠르게 사이트를 검색할 수 있습니다.
HEAD 이벤트 스크립트 부분
예제 스크립트는 2개의 이벤트를 사용합니다. 하나는 웹브라우저 앵커(해시태그)가 변경되었을 때 발생하는 해시체인지 이벤트이고 다른 하나는 문서가 모두 로드되었을 때 발생하는 윈도우 로딩 이벤트입니다. 웹브라우저 앵커는 #으로 표현되는데 # 이하의 내용이 변경되는 경우 자바스크립트 해시체인지 이벤트가 발생합니다.
그리고 문서가 모두 로드되었을 때에는 window.load() 이벤트가 발생합니다. 문서가 모두 로드되었을 때 예제 스크립트를 실행하는 이유는 해시체인지에 의하여 변경되는 HTML DOM 요소는 #content인데 이 부분을 수정하려면 해당 문서가 모두 로드되어 있어야 하기 때문입니다.
jQuery에서 이벤트를 감지하는 메소드는 on()입니다. jQuery.on([이벤트명], 함수)과 같은 방법으로 사용하며 예제 소스코드에서 필요로 하는 해시체인지 이벤트와 윈도우 로드 이벤트의 명칭은 각각 hashchange와 load입니다. 제어하고 싶은 이벤트가 있으면 jQuery.on() 메소드의 첫 번째 매개변수에 해당 이벤트 명칭을 입력한 후 두 번째 매개변수에 함수명을 입력하거나 직접 함수를 정의하면 됩니다. 예제 소스코드에서는 직접 함수를 정의하는 방법을 사용하였습니다.
BODY 부분
HTML BODY 태그 내부에는 출력되는 모든 문서 내용이 들어갑니다. 예제 소스코드에서는 BODY 내부에 간단하게 링크 몇 개와 방문자가 요청한 내용이 출력되는 영역인 DIV 태그를 넣었습니다. 모든 링크는 앵커 해시태그(#)로 이루어졌기 때문에 HEAD 부분 예제 자바스크립트가 없다면 링크를 클릭했을 때 아무런 내용도 출력되지 않습니다. #content는 jQuery.load() 메소드에 의하여 사용자가 요청한 문서의 내용이 출력되는 영역입니다. 방문자가 링크를 클릭하여 앵커가 변경되면 #content의 내용이 바뀝니다.
마무리
지금까지 jQuery와 자바스크립트, 해시 체인지 이벤트를 활용한 동적 페이지 이동 방법을 알아보았습니다. 동적 서버 네트워크 기술이 발전하면서 이 글에서 설명하는 방법은 점점 인터넷에서 많이 사용되고 있는 추세입니다. 이 글에서 소개한 소스코드가 완벽하지는 않지만 동적으로 문서를 불러오는 알로리즘이 어떻게 구현될 수 있는지 이해하는 데에는 도움이 되었으리라 생각합니다. 앞으로도 jQuery와 자바스크립트를 활용한 예제 소스코드를 다양하게 소개하겠습니다.
타이틀이미지: Christiaan Colen, JavaScript source code ransomware, Flickr. CC BY-SA 2.0.