93

jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

  • View
    261

  • Download
    7

Embed Size (px)

DESCRIPTION

조나단 채퍼, 칼 스웨드버그 지음 | 이승준 옮김 | 오픈소스 & 웹 시리즈 _ 015 | ISBN: 9788992939331 | 22,000원 | 2009년 09월 17일 발행 | 456쪽

Citation preview

Page 1: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리
Page 2: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리
Page 3: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

jQuery 1.3작고 강력한

자바스크립트 라이브러리

Page 4: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

iv

01 jQuery시작하기 1

jQuery란 무엇인가 ........................................................................ 1

jQuery, 왜 좋은가 ......................................................................... 3

jQuery 프로젝트의 역사 ................................................................. 5

첫 번째 jQuery 도큐먼트 ................................................................ 6

jQuery 다운로드 .................................................................... 6

HTML 도큐먼트 설정 ............................................................. 6

jQuery 코드 작성 ................................................................... 9

시 구절 찾기 ................................................................. 9

새로운 클래스 주입하기 .................................................10

코드 수행하기 ..............................................................10

완성된 산출물 ......................................................................12

요약 ..........................................................................................13

02 선택자 15

DOM ........................................................................................15

$() 팩터리 함수 ...........................................................................16

CSS 선택자들 ..............................................................................17

리스트 항목 레벨 단위로 스타일 입히기 ............................19

속성 선택자 ................................................................................21

링크에 스타일 입히기 ....................................................21

사용자정의 선택자들 ....................................................................23

·차 례·

Page 5: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

v

행에 징검다리 스타일 입히기 ..................................................23

폼 선택자 ............................................................................26

DOM 순회 메서드들 .....................................................................27

특정 셀에 스타일 입히기 ........................................................28

체인 ...................................................................................29

DOM 요소 접근하기 .....................................................................30

요약 ..........................................................................................31

03 이벤트 33

페이지 로드 시점에 작업 수행하기 ..................................................33

코드 실행 시간 .....................................................................33

하나의 페이지에 다중 스크립트 사용하기 ..................................34

간결하게 단축된 코드 ............................................................36

다른 라이브러리와 공존 .........................................................36

기본 이벤트들 .............................................................................37

간단한 스타일 변환기 ............................................................38

다른 버튼 활성화하기 ....................................................40

이벤트 핸들러 컨텍스트 .................................................42

좀 더 간소하게 만들기 ...................................................44

간소화된 이벤트 ...................................................................46

합성 이벤트 ................................................................................47

개선된 보이기와 숨기기 특징 ..................................................48

클릭 가능한 아이템들 강조하기 ...............................................49

이벤트의 여행 .............................................................................51

이벤트 버블링의 부작용 .........................................................53

진행 경로 수정하기 : 이벤트 객체 ...................................................54

이벤트 대상 .........................................................................54

이벤트 전파 멈추게 하기 ........................................................55

기본 동작들 .........................................................................56

Page 6: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

vi

이벤트 위임 .........................................................................57

이벤트 핸들러 제거하기 ................................................................59

이벤트 네임스페이스 .............................................................60

이벤트 다시 바인딩하기 .........................................................61

사용자 상호작용 흉내내기 .............................................................63

키보드 이벤트 ......................................................................64

요약 ..........................................................................................67

04 효과 69

인라인 CSS 변경 ..........................................................................69

기본적인 숨김과 보이기 ................................................................74

효과와 속도 ................................................................................76

속도 지정하기 ......................................................................76

페이드인, 페이드아웃 ............................................................77

복합 효과 ...................................................................................78

사용자 정의 애니메이션 만들기 ......................................................79

페이드 토글하기 ...................................................................80

여러 프로퍼티를 애니메이션하기 .............................................81

CSS로 위치 변경하기.....................................................83

동시효과 대 연속효과 ...................................................................84

요소들의 단일 집합 다루기 .....................................................84

요소들의 다중 집합 다루기 .....................................................87

콜백 ...................................................................................89

핵심정리 .............................................................................91

요약 ..........................................................................................92

Page 7: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

vii

05 DOM다루기 93

속성 조작하기 .............................................................................93

class 이외의 속성들 ...............................................................94

$() 함수 다시 보기 ................................................................96

새로운 요소 삽입하기 ...................................................................98

요소 이동 .................................................................................100

표시하기, 숫자 부여하기, 컨텍스트와 연결하기 ........................103

주석 추가하기 ....................................................................105

요소 감싸기 ..............................................................................107

요소 복사하기 ...........................................................................108

이벤트 복제하기 .................................................................109

인용표시 복제하기 ..............................................................110

CSS 나누기 .......................................................................110

코드 검토 ..........................................................................111

인용표시 꾸미기 .................................................................114

DOM 조작 메서드 핵심정리 .........................................................115

요약 ........................................................................................117

06 AJAX 119

필요할 때 데이터 로드하기 ..........................................................120

HTML 추가하기 .................................................................121

자바스크립트 객체로 작업하기 ..............................................124

자바스크립트 객체 이용하기 .........................................125

전역 jQuery 함수들 .....................................................126

스크립트 실행하기 ......................................................129

XML 도큐먼트 로드하기 ......................................................131

데이터 형식 선택하기 .................................................................135

서버로 데이터 전달하기 ..............................................................137

Page 8: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

viii

GET 요청 수행하기 .............................................................137

POST 요청 수행하기 ...........................................................141

폼 직렬화하기 ....................................................................142

요청이 처리 중임을 표시하기 .......................................................144

AJAX와 이벤트들 ......................................................................147

보안 제약사항들 .......................................................................148

원격 데이터를 위한 JSONP ..................................................150

추가적인 옵션 ...........................................................................151

저수준 AJAX 메서드 ...........................................................152

기본 옵션 변경하기 .............................................................153

HTML 페이지의 일부를 로드하기 ..........................................153

요약 ........................................................................................156

07 테이블다루기 157

정렬과 페이징 ...........................................................................158

서버 측 정렬 ......................................................................158

페이지 새로고침 방지하기 ............................................159

자바스크립트로 정렬 구현하기 ..............................................160

행 그룹핑 태그 ...........................................................161

알파벳 순서대로 정렬하기 ............................................162

플러그인의 힘 ............................................................167

수행 성능 ..................................................................168

정렬하기 위해 키를 만들기 ...........................................170

다양한 타입의 데이터 정렬하기 .....................................172

칼럼 하이라이트하기 ...................................................175

정렬 순서 변경하기 .....................................................175

서버 측 페이징 ...................................................................178

정렬과 페이징을 함께 적용하기 .....................................178

자바스크립트로 페이징하기 ..................................................180

페이저 출력하기 .........................................................181

Page 9: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

ix

페이저 버튼 활성화 .....................................................181

현재 페이지 만들기 .....................................................183

페이징에서의 정렬 ......................................................185

완성된 코드 .......................................................................185

테이블 외형 수정 .......................................................................188

행 하이라이트 ....................................................................188

행 스트라이프 ............................................................190

향상된 행 스트라이프 ..................................................192

대화적 행 하이라이팅 ..................................................194

툴팁 .................................................................................197

접기와 펼치기 ....................................................................202

필터링 ..............................................................................204

필터 옵션들 ...............................................................205

필터 해제하기 ............................................................207

다른 코드와 상호작용하기 ............................................208

완성된 코드 .......................................................................210

요약 ........................................................................................213

08 폼과함수 215

기본 폼의 기능 향상 ...................................................................215

폼 스타일의 단계적 기능향상 ................................................216

범례 .........................................................................218

필수 입력필드 메시지 ..................................................219

선택적으로 표시되는 필드들 .................................................224

폼 입력 유효성 검사 ............................................................226

필수 입력 필드들 ........................................................226

필수 입력 포맷 ...........................................................230

마지막 체크 ...............................................................232

체크박스 다루기 .................................................................234

완성된 코드 .......................................................................237

Page 10: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

x

단순한 폼 .................................................................................240

플레이스홀더 텍스트 ...........................................................240

AJAX 자동완성 ..................................................................244

서버 측 코드 ..............................................................244

브라우저 측 코드 ........................................................245

검색 필드 위치시키기 ..................................................247

키보드 내비게이션 ......................................................247

방향키 다루기 ............................................................249

필드에 추천 항목 집어넣기 ...........................................250

추천목록 제거하기 ......................................................251

자동완성 대 라이브 서치 ..............................................252

완성된 코드 .......................................................................252

수치입력 다루기 ........................................................................255

장바구니 테이블 구조 ..........................................................255

숫자가 아닌 입력 무시하기 ...................................................259

숫자 계산 ..........................................................................260

통화를 분석하고 포맷하기 ............................................261

소수 자리 다루기 ........................................................262

다른 계산들 ...............................................................264

값 반올림하기 ............................................................265

마무리하기 ................................................................266

물품(아이템) 삭제하기 .........................................................267

배송 정보 편집하기 .............................................................272

완성된 코드 .......................................................................275

요약 ........................................................................................277

09 셔플러와로테이터 279

헤드라인 로테이터 .....................................................................280

페이지 설정 .......................................................................280

피드 읽기 ..........................................................................282

Page 11: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xi

로테이터 설정 ....................................................................285

헤드라인 로테이션 함수 .......................................................286

호버 시 멈춤 ......................................................................289

다른 도메인에서 피드 읽어오기 .............................................292

로딩중 표시 ...............................................................293

점진적 페이드 효과 .............................................................294

완성된 코드 .......................................................................296

이미지 회전 ..............................................................................298

페이지 설정 .......................................................................298

자바스크립트로 스타일 변경하기 ...................................301

이미지 클릭시 셔플링하기 ....................................................302

슬라이딩 애니메이션 추가 ............................................304

동작 아이콘 표시 ........................................................306

이미지 확대 .......................................................................310

확대된 표지 이미지 감추기 ...........................................312

닫기 버튼 표시하기 .....................................................313

가격표시 달기 ............................................................315

표지 확대 애니메이션 ..................................................317

이미지가 로드된 다음 애니메이션시키기 .........................321

로딩중 표시 ...............................................................322

완성된 코드 .......................................................................323

요약 ........................................................................................327

10 플러그인 329

플러그인과 사용법 찾기 ..............................................................329

플러그인 사용법 ........................................................................330

폼 플러그인 ..............................................................................331

팁과 기교 ..........................................................................332

jQuery UI 플러그인 라이브러리 ....................................................333

효과 .................................................................................334

Page 12: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xii

컬러 애니메이션 .........................................................334

클래스 애니메이션 ......................................................335

향상된 점진적 변화 .....................................................335

기타 효과 .................................................................336

상호작용 컴포넌트 ..............................................................336

위젯 .................................................................................339

jQuery UI 테마롤러 .............................................................341

추천 플러그인 ...........................................................................343

폼 플러그인 .......................................................................343

Autocomplete(자동완성) ...............................................343

Validation (검증) .........................................................343

Jeditable....................................................................344

Masked input (마스크 입력) ..........................................344

테이블 플러그인 .................................................................345

Tablesorter (테이블소터) ..............................................345

jqGrid .......................................................................346

Flexigrid ...................................................................346

이미지 플러그인 .................................................................347

Jcrop ........................................................................347

Magnify ....................................................................348

라이트박스와 모달 다이얼로그 ..............................................348

FancyBox ..................................................................349

Thickbox...................................................................350

BlockUI ....................................................................350

jqModal ....................................................................351

차트 .................................................................................351

Flot .........................................................................352

Sparklines .................................................................352

이벤트 ..............................................................................353

hoverIntent ................................................................353

Live query .................................................................354

요약 ........................................................................................354

Page 13: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xiii

11 플러그인개발 355

새 전역 함수 추가 ......................................................................355

여러 함수 추가하기 .............................................................356

핵심은 무엇인가? ...............................................................357

유틸리티 메서드 만들기 .......................................................358

jQuery 객체 메서드 추가 .............................................................359

객체 메서드 컨텍스트 ..........................................................360

메서드 체인 .......................................................................362

DOM 탐색 메서드 ......................................................................363

새 단축 메서드 추가하기 .............................................................368

메서드 파라미터 ........................................................................371

간단한 파라미터 .................................................................373

파라미터 맵 .......................................................................374

기본 파라미터 값 ................................................................375

콜백함수 ...........................................................................376

커스터마이즈 가능한 기본 값 ................................................377

선택자 표현식 추가 ....................................................................379

플러그인 배포하기 .....................................................................382

이름 짓기 ..........................................................................382

$ 별칭 사용 .......................................................................383

메서드 인터페이스 ..............................................................383

문서화 스타일 ....................................................................384

요약 ........................................................................................384

Page 14: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xiv

A 온라인리소스 385

jQuery 문서 ..............................................................................385

jQuery 위키 .......................................................................385

jQuery API ........................................................................385

jQuery API 브라우저 ...........................................................386

비주얼 jQuery ....................................................................386

어도비 AIR jQueryAPI 브라우저 ............................................386

자바스크립트 참조문서 ...............................................................386

모질라 개발자 센터 .............................................................386

데브 오페라 .......................................................................386

MSDN JScript 레퍼런스 .......................................................387

쿼크스모드 ........................................................................387

자바스크립트 툴박스 ...........................................................387

자바스크립트 코드 압축기 ...........................................................387

YUI Compressor .................................................................387

JSMin ...............................................................................388

프리티 프린터 ....................................................................388

(X)HTML 레퍼런스 ....................................................................388

W3C 하이퍼텍스트 마크업 언어 홈페이지 ...............................388

CSS 레퍼런스 ............................................................................388

W3C 캐스케이딩 스타일 시트 홈페이지 ..................................389

메조블루 CSS 침대시트 .......................................................389

위치가 모든 것이다 .............................................................389

유용한 블로그들 ........................................................................389

jQuery 블로그 ....................................................................389

러닝 jQuery .......................................................................389

Ajaxian .............................................................................390

존 레식 .............................................................................390

자바스크립트 앤트 ..............................................................390

Page 15: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xv

로버트의 이야기 .................................................................390

상상력과 웹 표준 ................................................................390

스누크 ..............................................................................390

매트 스나이더 자바스크립트 리소스 .......................................391

아이캔트 ...........................................................................391

DOM 스크립팅 ...................................................................391

하루 하루를 지내며 .............................................................391

리스트 어파트 ....................................................................391

jQuery를 적용한 웹 개발 프레임워크 .............................................392

B 개발도구들 393

파이어폭스용 도구들 ..................................................................393

파이어버그 ........................................................................393

웹 디벨로퍼 툴바 ................................................................394

벤크맨 ..............................................................................394

정규식 테스터 ....................................................................394

인터넷 익스플로러용 도구들 ........................................................394

마이크로소프트 인터넷 익스플로러 디벨로퍼 툴바 ....................394

마이크로소프트 비주얼 웹 디벨로퍼 .......................................395

디버그바 ...........................................................................395

드립 .................................................................................395

사파리용 도구들 ........................................................................395

디벨롭 메뉴 .......................................................................396

웹 인스펙터 .......................................................................396

오페라를 위한 도구들 .................................................................396

드래곤플라이 .....................................................................396

기타 다른 도구들 .......................................................................396

파이어버그 라이트 ..............................................................397

니토비버그 ........................................................................397

텍스트메이트 jQuery 번들 ....................................................397

Page 16: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xvi

샤를 .................................................................................397

피들러 ..............................................................................398

앱테나 ..............................................................................398

C 자바스크립트클로저 399

내부 함수 .................................................................................399

멋진 탈출 ..........................................................................401

변수 범위 ..........................................................................402

클로저 간의 상호작용 .................................................................404

jQuery에서의 클로저 ..................................................................406

$(document).ready()로 인자 전달하기 .....................................406

이벤트 핸들러 ....................................................................407

메모리 누수 위험 .......................................................................409

우연한 참조 루프들 .............................................................410

인터넷 익스플로러 메모리 누수 문제 ......................................411

좋은 소식 ..........................................................................411

요약 ........................................................................................412

D 퀵레퍼런스 413

선택자 표현식 ...........................................................................413

DOM 순회 메서드들 ...................................................................415

이벤트 메서드 ...........................................................................416

효과 메서드 ..............................................................................419

DOM 조작 메서드 ......................................................................420

AJAX 메서드 ............................................................................422

기타 메서드 ..............................................................................423

Page 17: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xvii

옮긴이글

이 책을 번역하여 출간한 지 꼭 1년 만에 다시 책을 내게 되었다. 이 책은 jQuery 1.3을 기준으

로 하고 있으면, jQuery 이전 버전과 관련된 불필요한 내용들은 과감히 없어지고, 본문뿐만 아

니라 예제의 상당히 많은 부분이 수정되고 다듬어졌다. jQuery는 말 그대로 질의(query)를 강조

한 자바스크립트 프레임워크이다. 복잡한 스크립팅을 간편하게 만드는 핵심적인 요소가 바로

DOM에 대한 처리이며, jQuery는 바로 이 부분에 큰 강점을 가지고 있다.

몇 년 전, 웹 개발과는 먼 일을 하는 친구에게 이 책에 대한 이야기를 했더니, 이 친구가 “제2

쿼리 그게 뭔데?”라고 반문했었다. 다시 생각해 보면 결코 틀린 이야기만은 아니다. jQuery는

한 단계 진보한 그야 말로 ‘제2의 질의언어’라고도 할 수 있다. jQuery가 작성한 코드가 작고 가

벼우면서 동시에 지속적으로 확장할 수 있는 플러그인 구성을 가지고 있어, Ajax 사이트를 손

쉽게 그리고 강력하게 구현할 수 있도록 해준다는 장점도 그렇지만, jQuery를 선택자, 체인, 플

러그인을 사용해보면 그 설계 철학과 통찰력에 감복하게 된다.

2006년에 등장한 jQuery는 등장한 지 채 2년이 되지 않아 이미 프로토타입(prototype)과 도조

(Dojo)의 인지도를 넘어섰다. 이제는 Aptana와 같은 오픈소스 프로젝트뿐만 아니라, 마이크로소

프트 비주얼 스튜디오와 같은 많은 상용 제품에도 기본으로 포함되고 있다. jQuery의 간편함과

강력함을 접해본 사람들은 충분히 그럴 만하다고 이야기한다.

이 책은 jQuery 라이브러리에 대한 기본적인 내용과 함께, 당장 써먹을 수 있는 실용적인 코드

를 많이 담고 있으며, 특히, ‘단계적 기능 향상(Progressive Enhancement)’과 같은 웹 개발의 원칙을

충실하게 설명하고 구현하고 있어, 웹표준에 관심 있는 독자들에게도 더 없이 좋은 책이 될 것

이다. 이 책이 출간되기까지 어려운 작업을 함께 해준 박용우님, 그리고 리뷰에 참여해준 김경

윤, 김진수, 정위현, 허영남씨에게 감사한다. 원고의 내용을 꼼꼼하게 살피고, 최대한 우리나

라 독자들이 편하게 볼 수 있도록 소스코드와 스크린샷까지 꼼꼼하게 챙겨주신 위키북스 분들

께도 감사드린다.

이승준

Page 18: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xviii

지은이 소개

조나단 채퍼 Jonathan Chaffer

미시건주 그랜드 래피드에 위치한 ‘스트럭처 인터랙티브’ 사의 기술이사이다. 다양한 기술

을 사용하여 진행하는 웹 개발 프로젝트를 관리/감독 하고 있으며, 동시에 매일 지속적으로

협업하면서 실제 개발작업도 하고 있다. 드루팔(Drupal) CMS에 자바스크립트 프레임워크로

jQuery를 선정하여 적용하는 등 오픈소스 커뮤니티에서도 왕성하게 활동하고 있다. 드루팔 사

이트에서 구조적 콘텐츠를 관리하는 모듈로 널리 사용되는 ‘콘텐츠 컨스트럭션 키트(Content

Construction Kit)’의 제작자이기도 하며, 드루팔의 메뉴 시스템과 개발자 API 레퍼런스를 담당하

는 책임자 역할도 맡고 있다. 조나단은 그의 아내 제니퍼와 그랜드 래피드에 살고 있다.

이 책이 멋진 고통의 산물이라 것을 알아주는 아내 제니퍼에게 감사한다. 또, 문법적

인 오류가 없는 책이 될 수 있도록 언어학에 대한 관심사를 함께 나누어준 칼(Karl)

에게도 고마움을 전하고 싶다.

Page 19: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xix

칼 스웨드버그 Karl Swedberg

미시건주 그랜드 래피드에 있는 ‘스트럭처 인터랙티브’ 사의 웹 개발자로 시멘틱 HTML, 잘

구성된 CSS 그리고 간결한 자바스크립트 개발등 웹 표준과 연관된 개발을 주로 진행하고 있

다. 웹 개발에 투신하기 전까지 그는 카피 편집자, 고등학교 영어교사 그리고 커피매장 주인

이 있다.

아직도 식지 않는 기술에 대한 그의 열의는 1990년대 초반 워싱턴주 레드몬드에 있는 마이크

로소프트에서 일을 하면서 시작되었다. 칼은 사진, 가라데, 영문법 그리고 아버지의 역할에도

많은 관심을 가지고 있으며, 그의 아내 사라(Sara)와 두 자녀 벤자민(Benjamin)과 루시아(Lucia)와

그랜드 래피드에 살고 있다.

변함없는 사랑과 나의 폭넓은 관심사들에 지지를 보내준 아내 사라에게 감사하고 싶다. 나의

두 아이 벤자민과 루시아에게도 감사한다.

나와 함께 기꺼이 책을 쓰고, 내가 잘 모르는 난해한 프로그래밍의 관점을 친절

하게 설명해준 조나단 채퍼에게 깊은 존경과 감사를 보낸다. 마지막으로, 훌륭

한 라이브러리를 만들고 이 책에 아낌없는 격려를 보내준 존 레식(John Resig)

에게 감사하며, 레이 반고(Rey Bango), 브랜든 아론(Brandon Aaron), 클

라우스 하틀(Klaus Hartl), 존 제퍼러(Jörn Zaefferer), 데이브 메스빈(Dave

Methvin), 마이크 앨서프(Mike Alsup), 에후다 카츠(Yehuda Katz), 스테판 페

터(Stefan Petre), 폴 베커스(Paul Bakaus), 미셸 게리(Michael Geary), 글렌

립카(Glen Lipka)등 여러 가지로 도움과 창의적 영감을 제공해준 많은 분들께

감사한다.

Page 20: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xx

서문

때는 2005년. 모질라(Mozilla Corporation)에서 근무하는 존 레식(John Resig)은 자바스크립트의 고

수로 알려졌었다. 그는 이 분야의 선구자였던 딘 에드워드(Dean Edwards)와 시몬 윌리엄스(Simon

Willison)에게서 영감을 받아, 웹 프로그래밍할 때 손쉽게 요소를 찾아내는 함수들을 만들었다.

2006년 1월, 공식적으로 프로젝트를 발표하면서 DOM 조작과 기본적인 애니메이션 기능을 추

가한다. 자바스크립트에서 DOM 요소를 ‘질의(query)’한다는 의미를 강조하기 위해, jQuery란 이

름을 붙였다.

그로부터 몇 년 후, jQuery의 기능과 성능은 빠르게 발전하였고, 인터넷의 유명한 사이트들에

속속 적용되면서 널리 확산되었다.

존 레식은 이 프로젝트를 진정한 오픈소스 형태로 발전시켰으며, jQuery 프로젝트는 자바스크

립트의 고수들로 구성된 핵심 팀과 활발하게 활동하는 커뮤니티의 헌신과 노력으로 진행되고

있다.

jQuery 라이브러리는 여러분의 배경지식이 무엇이던, 여러분의 웹사이트를 한 단계 발전시켜

준다. 다양한 기능, 배우기 쉬운 문법, 강건한 크로스 플랫폼 호환성을 단 한 개의 파일로 제공

하고 있다. 또한, jQuery 기능을 기반으로 이미 100여 개가 넘는 플러그인이 개발되어, 거의 모

든 클라이언트 스크립팅의 요구사항들을 수용할 수 있는 핵심적인 도구로 자리잡았다.

이 책은 jQuery의 개념을 소개하고, 독자 여러분이 어렵게만 여겨왔던 상호작용과 애니메이션

을 여러분의 페이지에 손쉽게 추가하는 방법들을 알려준다. 이 책은 AJAX 사용상의 주의할 점

들과 이벤트, 효과 그리고 고급 자바스크립트 기능들을 소개하고 있으며, jQuery 전체에 대해

요약된 레퍼런스를 제공하여, jQuery에 대한 충실한 안내 역할을 할 것이다.

이 책의 내용

1장은 먼저 jQuery에 대한 이해를 돕기 위해 jQuery에 대한 기본적인 내용을 설명하고, 여러분

이 jQuery를 사용해서 무엇을 할 수 있는지 설명한다. jQuery 라이브러리를 다운로드해서 설치

하고, 스크립트를 작성하는 방법을 설명한다.

Page 21: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xxi

2장에서는 웹 페이지에서 요소들을 찾아내기 위해 jQuery의 선택자 표현식과 DOM 순회 메서

드들을 어떻게 사용하는지 공부한다. 어떤 요소든 선택자 표현식을 사용하여 여러분이 원하는

요소를 찾아낼 수 있으며, 심지어 순수 CSS만으로 하지 못했던 작업도 할 수 있게 된다.

3장에서는 이벤트 처리 메커니즘에 대해 살펴본다. jQuery의 이벤트 처리 메커니즘을 사용하

여 브라우저 이벤트들을 처리하는 방법과 jQuery의 강력한 이벤트 추가 기법을 살펴본다. 심

지어 페이지가 완전히 로딩되기 전에도 이벤트를 추가할 수 있다. 또한, 이벤트 버블링(event

bubbling), 위임(delegation), 네임스페이스(namespace)와 같은 고급 주제도 살펴보게 된다.

4장은 동작을 멋지게 꾸미는 방법을 설명한다. jQuery의 애니메이션 기법들을 살펴보고, 감추

기, 보이기, 페이지 요소 이동을 아주 간편하게 처리할 수 있는 방법을 소개한다.

5장에서는 페이지의 내용을 변경하는 방법을 살펴본다. 구조적인 HTML을 실행 중에 어떻게

바꿀 수 있는지 알아본다.

6장에서는 jQuery를 사용하여 서버측 기능에 쉽게 접근하는 방법을 살펴본다. 페이지를 새로

고침 하지 않고도 서버 측 기능을 사용할 수 있게 될 것이다.

이 책의 후반부(7장, 8장, 9장)에서는 실전 예제들을 다룬다. 이전에 공부한 내용들을 묶어 실제

응용 사례들을 살펴보고, jQuery를 사용하여 일반적인 문제들을 해결하는 방법들을 살펴본다.

7장에서는 정렬, 이동, 스타일 등 데이터를 좀 더 멋지게 표현하는 방법을 살펴본다.

8장은 클라이언트 측 데이터 검증 방법, 유연한 폼 레이아웃 그리고 자동완성과 같은 대화적인

클라이언트-서버 폼 기능들을 설명한다.

9장에서는 페이지의 미려함과 기능을 한층 더 개선하여 정보를 이해하기 쉽게 보여주는 기능

들을 설명한다. 자동으로 혹은 사용자의 제어에 의해 정보들이 화면상에서 움직이도록 만들수

있다.

10장과 11장에서는 핵심 jQuery을 넘어 확장할 수 있는 방법과 다른 개발자가 만든 확장기능을

어떻게 사용하는지 알아본다. 그리고, 여러분이 플러그인을 직접 만드는 방법도 살펴본다.

10장에서는 Form 플러그인과 공식 사용자 인터페이스 플러그인 jQuery UI를 사용한다. 이 외

에도 유용한 여러 플러그인을 어떻게 활용하는지 살펴본다.

Page 22: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xxii

11장에서 여러분은 바닥부터 시작하여 여러분만의 플러그인을 개발하는 독특한 방법들을 배

우게 될 것이다. 여러분만의 유틸리티 함수를 만들고, jQuery 객체 메서드를 추가하고, 사용자

정의 선택자 표현식을 만드는 방법 등을 살펴보게 된다.

부록 A는 jQuery와 자바스크립트 그리고 웹 개발과 관련된 jQuery, 자바스크립트, 일반적인 웹

개발등 여러 가지 유용한 리소스들을 소개 한다.

부록 B는 jQuery 개발에 유용하게 사용할 수 있는 jQuery 코드 디버깅 방법, 에디터 등 서드파

티 프로그램들과 유틸리티들을 소개한다.

부록 C는 사람들이 자바스크립트 언어의 기능 중에서 어려워하는 클로저에 대해 알아본다. 여

러분은 클로저의 역효과를 두려워하지 않고, 오히려 클로저의 힘을 적극 활용하게 될 것이다.

그리고 마지막 부록 D에서는 jQuery 라이브러리 전체의 메서드와 선택자 표현식 전체에 대해

요약된 레퍼런스를 제공한다. 여러분이 메서드에 대해 이미 알고 있건 아니건 상관없이 메서

드들과 선택자들을 손쉽게 찾아 볼 수 있을 것이다.

여러분이 준비할 것들

이 책에서 소개하는 예제와 데모를 실제로 실행해 보려면 다음과 같은 것들이 필요하다.

텍스트 편집기•

모질라 파이어폭스, 애플 사파리, 마이크로소프트 인터넷 익스플로러와 같은 최신 웹 •

브라우저

jQuery 소스파일 1.3.1 이후 버전. http://jquery.com/ 에서 다운로드할 수 있다.•

덧붙여, 6장의 AJAX 예제를 실행하려면, PHP가 실행 가능한 서버를 준비하여야 한다.

이 책은 누구를 위한 책인가

이 책은 상호대화적인 요소를 창조하고자 하는 웹 디자이너와 사용자 인터페이스를 만들고자

하는 웹 개발자를 위한 책이다. 기초적인 HTML과 CSS의 기초를 알고 있고, 자바스크립트 문

법에 어느 정도 익숙한 것이 좋다. jQuery에 대한 사전 지식이나 경험은 필요 없으며, 다른 자

바스크립트 라이브러리에 대한 경험도 필요 없다.

Page 23: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xxiii

표기법

이 책은 정보의 종류에 따라 각기 다른 스타일로 텍스트를 표현하고 있다. 몇 가지 예제를 통

해 이 책에서 사용하는 스타일과 의미에 대해 살펴보자.

코드에 사용된 단어는 그대로 기술하였다. 예를 들어, “우리는 include 지시어를 사용하여 다른

내용을 포함시킬 수 있다”

코드 블록의 모양은 다음과 같다.

<html> <head> <title>the title</title> </head> <body> <div> <p>This is a paragraph.</p> <p>This is another paragraph.</p> <p>This is yet another paragraph.</p> </div> </body></html>

코드 블록 중에 강조하고자 하는 항목이나 연관된 라인은 굵은 글자로 표시하였다.

$(document).ready(function() { $('a[href^=mailto:]').addClass('mailto'); $('a[href$=.pdf]').addClass('pdflink'); $('a[href^=http][href*=henry]') .addClass('henrylink');});

명령줄 입력과 출력은 다음과 같이 표시하였다.

outerFn():Outer functionInner function

새로운 용어와 중요한 어휘는 굵은 글자로 표시하였다. 예를 들어, 메뉴 혹은 다이얼로그 박스

등 화면상에 표시되는 단어는 다음과 같이 표시된다: “햄릿 링크 오른쪽에 PDF 아이콘, 이메

일 링크 다음에 오는 봉투 아이콘, 흰색 배경에 검정색을 가진 Henry V 링크를 살펴보자”

note! 중요한 노트 표시다.

Page 24: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xxiv

독자 의견

독자 여러분의 의견은 언제든지 환영이다. 이 책에 대해 어떻게 생각하는지, 어떤 것이 좋고

어떤 것이 나쁜지 알려주길 바란다. 독자 여러분의 의견은 책을 만드는 데 더없이 소중하다.

일반적인 의견은 책의 제목을 메일 제목에 적어 [email protected]로 메일을 보내주기

바란다. 출판되었으면 하는 책이 있다면 www.packtpub.com의 ‘추천 책 제목’ 폼을 이용하거나

[email protected]로 메일을 보내면 된다.

여러분이 가진 전문적인 지식이나 책을 출간하는 데 관심 있는 분들이라면 www.packtpub.

com/authors의 안내를 참조하기 바란다.

고객 지원

우리는 Packt 책의 소중한 독자들에게 다양한 지원을 제공하고 있다.

이 책의 예제 코드 다운로드

http://www.packtpub.com/files/code/6705_Code.zip 에서 이 책의 제목을 선택하면 이 책의 모

든 예제와 추가적인 리소스를 다운로드할 수 있다. 각 파일에는 파일의 내용들을 어떻게 활용

할 수 있는지에 대한 안내도 포함되어 있다. 또한 한글화 예제 및 좀 더 효율적인 학습을 위한

단계별 예제 코드가 http://jquery.collably.com/ 에 준비되어 있다.

정오표

이 책의 내용들은 많은 검토를 거치지만, 간혹 오자가 있을 수 있다. 이 책의 텍스트나 코드에

서 오류를 발견한다면 출판사에 알려주기 바란다. 여러분이 알려준 오류는 다른 독자들에게

도움이 될 것이며, 이 책의 내용을 개선하는데도 소중하게 사용될 것이다.

책의 오류는 http://www.packtpub.com/support 사이트를 방문하여, 오류 링크를 선택하여 오

류의 내용을 상세하게 적어주면 된다. 오류가 확인되면 정오표에 추가된다. 현재 오류들은

http://www.packtpub.com/support 에 공지하고 있다.

Page 25: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

xxv

저작권 침해

인터넷을 통해 이루어지는 모든 저작권 침해는 모든 중요한 사안이다. Packt 출판사는 우리의

저작권과 라이선스를 신중하게 보호하고 있다. 만일 여러분이 우리 출판물에 대한 불법적인

복사를 목격하게 된다면, 웹 사이트와 주소를 알려주기 바란다. 이에 대해 적절한 조치를 취할

것이다. [email protected]를 통해 링크와 침해한 내용에 대한 제보를 바란다. 저자를

보호하고, 좀 더 가치 있는 콘텐트를 만들려는 우리의 노력에 도움을 주시는 여러분께 감사 드

린다.

질문

이 책에 대한 모든 문제나 질문은 [email protected]로 메일을 보내 주길 바란다.

Page 26: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리
Page 27: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

1

오늘날 월드 와이드 웹은 매우 역동적인 환경이며, 사이트의 기능과 스타일에 대해 사용자들이

거는 기대치는 상당히 높다. 흥미롭고, 인터랙티브한 사이트를 구축하려는 많은 개발자들이,

일반적인 작업들을 자동화하고 복잡한 작업을 단순화 하기 위해 jQuery와 같은 자바스크립트

라이브러리를 사용하기 시작하고 있다. jQuery가 폭넓은 지지를 받는 주요한 이유는 개발에 필

요한 다양한 기능을 폭넓게 제공하기 때문이다.

jQuery는 매우 다양한 기능을 가지고 있기 때문에 어디서부터 시작해야 할지 금방 알아차리기

가 쉽지 않다. jQuery는 설계의 일관성과 균형을 유지하고 있으며, 대부분의 개념은 HTML의

구조와 캐스케이딩 스타일시트(CSS, Cascading Style Sheets)로부터 나온 것이다. jQuery 라이

브러리는 자바스크립트 프로그래밍 자체보다 HTML 혹은 CSS에 대한 경험을 더 많이 가지고

있는 웹 개발자들이 접근하기 쉽게 설계되어 있다. 우리는 1장의 초반부에서 단 3줄의 코딩만

으로 훌륭하게 동작하는 jQuery 프로그램을 작성해 볼 것이다. 쉽게 배울 수 있는 장점과 더불

어 jQuery는 경험이 많은 프로그래머들에게는 이러한 개념들의 일관성을 유지하는 데 큰 도움

을 준다. 앞으로 1장 이후에서 차근차근 살펴볼 것이다.

자 이제 jQuery를 가지고 무엇을 할 수 있는지 살펴보자.

jQuery란무엇인가

jQuery 라이브러리는 일반적인 웹 스크립팅에 폭넓게 사용될 수 있는 추상 계층(abstraction layer)

을 제공하므로, 스크립팅에서 필요로 하는 거의 모든 상황에 유용하게 활용할 수 있다. jQuery

01jQuery시작하기

Page 28: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2 l Learning jQuery 1.3

가 가지고 있는 확장성과 사용 가능한 모든 경우들을 한 권의 책에서 모두 설명하기란 불가

능하다. 새로운 기능을 가진 플러그인들을 계속 개발해서 추가하고 있기 때문이다. 따라서,

jQuery에 대해 꼭 알고 있어야 할 핵심 기능들을 중심으로 살펴보자.

• 도큐먼트 요소에 접근하기. 만일 여러분이 자바스크립트 라이브러리를 사용하지 않는다

면, 문서 객체 모델(DOM) 트리에 접근하고, HTML 도큐먼트 구조의 특정 영역을 탐색

하기 위해 상당히 많은 양의 코드를 작성해야만 한다. jQuery는 도큐먼트의 특정한 부

분을 탐색 혹은 조작하기 위한 명료하고 효과적인 선택자(selector) 메커니즘을 제공한다.

페이지가 보여지는 모습 변경하기.• CSS가 도큐먼트가 렌더링되는 방식을 결정하는 매우

효과적이고 강력한 기법이긴 하지만, 브라우저들이 동일한 표준을 제공하지 않기 때문

에 코드가 길어지는 경우가 많다. jQuery는 브라우저와 상관없이 동일한 표준을 제공하

므로, 브라우저 간의 차이를 극복하도록 해준다. 또한, jQuery는 페이지가 렌더링된 이

후에도 클래스를 변경하거나 도큐먼트 일부분의 스타일을 개별적으로 바꿀 수 있도록

해 준다.

• 도큐먼트의 콘텐트 변경하기. jQuery는 간단한 코드로 외관뿐만 아니라 도큐먼트 내용

자체를 바꿀 수 있다. 텍스트를 바꿀 수 있고, 이미지를 추가하거나 교체하고, 리스트의

순서를 바꾸거나 혹은 HTML 전체 구조를 완전히 새로 만들거나 확장할 수 있다–이 모

든 것이 간단한 API(Application Programming Interface)로 가능하다.

• 페이지와 사용자 간 상호작용 처리. 상호작용을 적절하게 제어할 수 없다면, 정교하고

강력한 기능이 별로 쓸모없게 된다. jQuery 라이브러리는 사용자의 링크 클릭 등을 포함

한 광범위한 이벤트를 가로채어 처리하는 세련된 방식을 제공하기 때문에 HTML 자체

에 이벤트 핸들러를 추가하여 HTML을 헤집어 놓을 필요가 없다. 동시에, 이벤트 핸들

링 API는 웹 개발자를 괴롭히는 브라우저 간의 불일치 문제도 깔끔하게 해결해 준다.

• 도큐먼트의 변화를 표시하는 애니메이션 추가하기. 디자이너는 효과적인 상호작용을 제

공하기 위해 사용자에게 시각적인 피드백을 제공해야 한다. jQuery 라이브러리는 페이

드(fade)1, 와이프(wipe)

2와 같은 일련의 효과 기능들을 제공할 뿐만 아니라 새로운 효과

를 만들 수 있는 툴킷을 제공하고 있다.

1  (옮긴이) 화면상에서 점차 나타나거나(페이드인, Fade-in), 점차 사라지는 효과(페이드아웃, Fade-out)를 말한다. 일반적으로 투명도를 조절하는 방법으로 구현한다.

2 (옮긴이) 하나의 화면이 다른 화면으로 바뀔 때 사용되는 화면 전환 기법을 말한다.

Page 29: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

1장 jQuery 시작하기 l 3

• 페이지를 새로고침하지 않고 서버로부터 정보를 가져오기. AJAX(Asynchronous JavaScript

And XML)로 알려진 코드 패턴과 부가적인 기능은 웹 개발자로 하여금 적절하게 응답하면

서도, 기능이 풍부한 사이트를 만들 수 있게 해준다. jQuery 라이브러리는 브라우저에 얽

매이지 않는 AJAX 기능을 제공하므로, 개발자가 서버 측 기능에만 집중할 수 있도록 해

준다.

• 일반적인 자바스크립트 작업을 단순화하기. jQuery의 모든 도큐먼트 처리 기능에는 순

환과 배열 조작과 같은 자바스크립트 확장기능이 추가로 제공된다.

jQuery,왜좋은가

최근, 동적인 HTML에 대한 관심이 다시 늘어나면서, 수많은 자바스크립트 라이브러리들이 등

장하였다. 어떤 라이브러리들은 앞서 이야기한 기능들 중 한두 가지 기능에 특화되어 있고, 어

떤 것은 가능한 모든 동작과 애니메이션을 제공하려 하고 있으며, 또 몇몇 라이브러리들은 이

런 모든 것을 묶어서 제공하고 있다. jQuery는 앞서 이야기한 포괄적인 기능들을 다루면서도

최대한 컴팩트하게 유지하기 위해 다음과 같은 전략을 구사하고 있다.

• CSS에 대한 지식을 최대한 활용. jQuery는 CSS 선택자로 페이지 요소의 위치를 찾아내

는 메커니즘을 기반으로 하고 있어, 도큐먼트의 구조를 명료하면서도 읽기 쉬운 형식으

로 표현할 수 있도록 한다. 디자이너들이 페이지에 동작을 추가하려면 상당히 전문적인

CSS 문법을 구사해야하는데, 이러한 측면에서 볼 때 jQuery 라이브러리는 좋은 시작점

이 될 수 있다.

• 확장 지원. jQuery는 피처 크리프(feature creep)3를 피하기 위해 보편적이지 않은 기능은

플러그인으로 이관하였다. 새로운 플러그인을 만드는 것은 그리 어렵지 않으며, 문서화

가 잘 되어 있고, 다른 사람들이 개발한 창의적인 산출물들과 여러 유용한 모듈들의

도움을 받아 직접 개발할 수 있다. jQuery는 플러그인 아키텍처를 기본 구성으로 가지

고 있어 필요한 기능을 골라서 사용할 수 있으며, 더 작은 라이브러리가 필요하다면 이

플러그인 아키텍처 자체를 제거하여 더 가볍게 사용할 수도 있다.

3  (옮긴이) 불필요하고 복잡한 기능(feature)이 은연중에 늘어나는(creep) 현상을 가리키는 말. 사용자는 더 많은 기능이 있는 제품이 더 좋은 제품이라고 믿는 경향이 있으며, 만드는 사람은 추가적인 기능이 판매를 높인다고 생각하기 때문에 실제 거의 사용하지 않는 불필요한 기능들이 계속 늘어나게 된다. 하지만, 시간이 지나면서 사용자는 불필요한 기능을 싫어하게 되며, 자신에게 꼭 필요한 단순한 기능의 제품을 더 선호하게 된다.

Page 30: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

4 l Learning jQuery 1.3

브라우저의 차이로부터 해방.• 불행히도 실제 웹 개발에서 브라우저는 표준과 약간씩 다

른 고유한 특징들을 가지고 있다. 웹 애플리케이션 개발의 상당 부분이 바로 플랫폼별

로 다른 기능들을 처리하는 데 할애된다. 브라우저는 끊임없이 발전하기 때문에 브라우

저 중립적인 고급 기능을 개발하는 것이 거의 불가능하지만, jQuery는 추상화된 레이어

를 제공함으로써 일상적인 작업들을 일반화하고, 코드의 크기를 줄이며, 아주 단순하게

개발할 수 있도록 해준다.

• 언제나 집합을 가지고 작업. 우리는 jQuery에게 “collapsible이란 이름의 스타일 클래스

를 가진 요소들을 찾아 감추기를 수행하라”라고 명령하는 방식으로 접근한다. 각각의

개별 요소를 처리하기 위해 루프를 돌릴 필요가 없다. 요소를 감추는 기능을 수행하는

.hide() 메서드를 각 개별 요소에 적용하는 대신 객체 집합에 적용한다. 이것을 묵시적

반복(implicit iteration) 기법이라고도 하는데, 루프를 구성할 필요가 없으므로 코드 양을

많이 줄여준다.

여러 동작을 한 줄에 쓴다• . 임시 변수 사용을 최소화하거나 불필요한 반복을 피하기 위

해, jQuery가 제공하는 메서드 체인(chaining)이라는 프로그래밍 패턴을 활용할 수 있다.

다음 조작이 해당 결과 객체에 적용 가능함을 의미한다.

이러한 전략으로 jQuery 패키지를 매우 작게 유지(압축형태로 대략 20K 정도)하고 있으며 동

시에 개발자의 코드 역시 작게 유지할 수 있도록 하는 기법들을 제공하고 있다.

라이브러리의 간결함은 자체 설계 때문이기도 하지만, jQuery 관련 프로젝트에 대한 주변의 매

우 왕성한 커뮤니티 활동 역시 간결함을 유지하는 데 큰 공헌을 하고 있다. jQuery 사용자들은

플러그인 개발뿐만 아니라 라이브러리의 핵심 부분을 개선하기 위해 모여서 토론하고 있다.

부록 A는 jQuery 개발자들에게 열려 있는 커뮤니티들에 대한 상세한 정보를 보여준다.

이렇게 유연하고 강건한 시스템에 기울이는 많은 엔지니어들의 엄청난 노력에도 불구하고, 최

종 산출물은 모든 사람들에게 무료로 제공하고 있다. 이 오픈소스 프로젝트는 GNU 퍼블릭 라

이선스(jQuery를 포함하는 다른 오픈소스 프로젝트에 적합)와 MIT 라이선스(jQuery를 상용 소

프트웨어의 일부로 사용할 때 적합)의 두 가지 라이선스로 제공되고 있다.

Page 31: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

1장 jQuery 시작하기 l 5

jQuery프로젝트의역사

이 책은 최신 버전 jQuery 1.3.x의 기능과 문법을 기준으로 하고 있다. jQuery 라이브러리의 개

발의 역사에서 ‘페이지 내의 요소를 쉽게 찾고 조작할 수 있도록 한다’는 기본 사상에는 변화가

없지만, 약간의 문법과 기능에 변화가 있었다. 아래는 버전이 바뀌면서 눈에 띄게 달라진 변화

를 요약한 것이다.

• 초기 개발 단계: 2005년 8월, 존 레식(John Resig)이 Prototype의 ‘Behaviour’라이브러리 개

선을 발표. 이 새로운 프레임워크는 2006년 1월 14일 공식적으로 jQuery로 명명된다.

jQuery 1.0• (2006년 8월): 첫 번째 안정화 버전 발표. 강력한 CSS 선택자 기능을 제공하

였으며, 이벤트와 AJAX 기능도 포함.

• jQuery 1.1 (2007년 1월): API를 일목요연하게 정리. 자주 사용하지 않는 메서드를 통합

하여, 학습해야 할 메서드의 수와 문서를 대폭 줄임.

• jQuery 1.1.3 (2007년 6월): 선택자 엔진을 개선하여 상당한 속도 향상을 가져옴. 이 버

전 부터 Prototype, Mootools, Dojo 등의 라이브러리와 견줄만한 성능을 가지게 됨.

jQuery 1.2• (2007년 11월): 손쉽게 사용할 수 있는

(namespaced events)• 기능을 도입하면서, 중복 기능인 XPath 관련 문법을 제거.

• jQuery UI (2007년 11월): 널리 사용되던 Interface 플러그인을 대체하는 새로운 플러그

인 슈트로 풍부한 위젯을 제공하며 그래드앤 드롭과 같은 정교하고 다양한 기능도 포함.

jQuery 1.2.6• (2008년 5월): 브랜든 애론(Brandon Aaron)의 유명한 Dimension 플러그인이

메인 라이브러리에 포함됨.

• jQuery 1.3 (2009년 1월): 선택자 엔진(Sizzle)에 대한 대대적인 업그레이드로 jQuery 라

이브러리 전체의 속도가 향상됨. 이벤트 위임 기능을 공식적으로 지원함.

note! 이전의 jQuery 버전들에 대한 변경 이력은 http://docs.jquery.com/History_of_jQuery 에

서 찾아 볼 수 있다.

Page 32: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

6 l Learning jQuery 1.3

첫번째jQuery도큐먼트

우리는 앞서 jQuery가 제공하는 기능을 전반적으로 살펴보았다. 이제 이 라이브러리를 실제로

어떻게 사용하는지 살펴보자.

jQuery 다운로드

공식 jQuery 웹사이트(http://jquery.com/)는 항상 jQuery 라이브러리에 대한 최신의 코드와

뉴스를 제공하고 있다. 시작하기 위해 먼저 이 사이트에서 jQuery를 다운로드한다. 몇 개의 다

른 버전들이 제공되는데, 대부분의 개발 단계에서는 압축되지 않은 버전을 사용하고 실제 운

영 단계에서는 압축된 버전으로 대체할 수 있다.

별도의 설치는 필요 없다. jQuery를 사용하기 위해서는 단지 HTML 문서에서 접근 가능한 위

치에 올려 놓기만 하면 된다.4 자바스크립트가 인터프리터 언어이기 때문에 컴파일이나 혹은

빌드 과정도 필요치 않다. 단지, 페이지에 jQuery가 필요할 때마다 HTML 도큐먼트에 jQuery

파일을 포함하기만 하면 된다.

HTML 도큐먼트 설정

대부분의 jQuery 예제는 HTML 도큐먼트, 스타일을 지정하는 CSS 파일, 그리고 함께 동작하는

자바스크립트의 3부분으로 구성된다. 첫 번째 예제를 만들기 위해, 다른 책의 내용을 인용하여

하나의 페이지를 구성하고, 내용의 각 부분에 여러 CSS 클래스를 적용할 것이다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<title>Through the Looking-Glass</title>

4  (옮긴이) Google AJAX Libraries API. http://code.google.com/apis/ajaxlibs/ Ajax 라이브러리들을 버전별로 다운로드하는 번거로움을 줄이기 위한 서비스를 활용하는 것도 좋은 방법이 될 수 있다. 구글의 AJAX 라이브러리 API는 Prototype, jQuery, Script.aculo.us, Dojo, MooTools같은 유명한 AJAX 라이브러리를 손쉽게 그리고 빠르게 로딩하는 방법을 제공하고 있다.

Page 33: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

1장 jQuery 시작하기 l 7

<link rel="stylesheet" href="alice.css" type="text/css" / media="screen" />

<script src="jquery.js" type="text/javascript"></script> <script src="alice.js" type="text/javascript"></script> </head>

<body> <h1>거울 나라의 앨리스</h1> <div class="author">루이스 캐롤 지음</div>

<div class="chapter" id="chapter-1"> <h2 class="chapter-title">1. Looking-Glass House</h2> <p>탁자 위에는 앨리스와 가까운 쪽에 책이 한 권 놓여 있었다. 앨리스는 앉아서 하얀 왕을 지켜보고 있는

동안 (아직도 하얀 왕이 걱정스러웠기 때문에, 하얀 왕이 또 기절하면 당장이라도 잉크를 끼얹을 준비를

하고 있었다.) 자기가 읽을 수 있는 부분을 찾으려고 책장을 넘겼다.

<span class="spoken">"&mdash;온통 내가 모르는 언어잖아,"</span> 앨리스는 혼잣말로 중얼거렸다.</p> <p>책에는 이렇게 적혀 있었다</p> <div class="poem"> <h3 class="poem-title">YKCOWREBBAJ</h3> <div class="poem-stanza"> <div>sevot yhtils eht dna ,gillirb sawT'</div> <div>;ebaw eht ni elbmig dna eryg diD</div> <div>,sevogorob eht erew ysmim llA</div> <div>.ebargtuo shtar emom eht dnA</div> </div> </div> <p>이것을 보고 앨리스는 한참동안 어리둥절했지만, 마침내 똑똑한 생각이 번득였다. <span class="spoken"> "이건 거울 책이잖아. 그러니까 거울에 비추어 보면, 낱말들이 다시 똑바로

보일거야."</span></p> <p>앨리스가 읽은 시는 다음과 같았다.</p> <div class="poem"> <h3 class="poem-title">JABBERWOCKY</h3> <div class="poem-stanza"> <div>'Twas brillig, and the slithy toves</div> <div>Did gyre and gimble in the wabe;</div> <div>All mimsy were the borogoves,</div> <div>And the mome raths outgrabe.</div> </div> </div> </div> </body></html>

Page 34: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

8 l Learning jQuery 1.3

note! 실제 서버상의 파일 위치는 신경 쓸 필요가 없다. 다른 파일에 대한 참조는 상황에 맞게

조정해 주면 된다. 이 책의 대부분의 예제에서는 절대 경로(/images/foo.png)보다는

상대 경로(../images/foo.png)를 사용할 것이다. 웹 서버 없이 로컬에서 손쉽게 수행

해 볼 수 있다.

HTML의 처음 헤더 부분에서 바로 스타일시트(alice.css)를 로드한다. 예제를 위해 간략하게

작성하였다.

body { font: 62.5% Arial, Verdana, sans-serif;}h1 { font-size: 2.5em; margin-bottom: 0;}h2 { font-size: 1.3em; margin-bottom: .5em;}h3 { font-size: 1.1em; margin-bottom: 0;}.poem { margin: 0 2em;}.highlight {font-style: italic;border: 1px solid #888;padding: 0.5em;margin: 0.5em 0;background-color: #ffc;}

스타일시트를 읽어들이고 난 다음 자바스크립트 파일을 읽어들인다. 다른 스크립트들을 로드

하기 전에 jQuery 라이브러리(jquery.js)를 로드해야 한다는 점을 명심하자. 그렇지 않으면,

다른 스크립트에서 jQuery 프레임워크를 참조할 수 없게 된다.

note! 이 책의 나머지 부분에서는 관련된 HTML과 CSS 파일의 일부분만 표시한다. 파일의 전

체 내용은 이 책의 웹 사이트인 http://book.learningjquery.com이나 혹은 출판사의

웹사이트인 http://www.packtpub.com/에서 구할 수 있다(한글화한 소스는 http://

jquery.collably.com/ 과 http://www.wikibook.co.kr에 정리돼 있다).

Page 35: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

1장 jQuery 시작하기 l 9

페이지는 다음과 같은 모습으로 보일 것이다.

이제 jQuery를 사용하여 시의 구절에 새로운 스타일을 적용해 볼 것이다.

note! 이 예제는 jQuery의 사용 예를 보여주기 위해 간략하게 만든것이다. 실제 개발 시의 스

타일 적용은 jQuery를 사용하기보다는 순수하게 CSS만을 사용할 수도 있다.

jQuery 코드 작성

우리는 새로 ‘alice.js’ 자바스크립트 파일을 작성할 것이며, 이 파일은 <script src="alice.

js" type="text/javascript"></script>를 통해 HTML에 포함된다. 이 예제는 단지 3줄의

코드로 이루어져 있다.

$(document).ready(function() { $('.poem-stanza').addClass('highlight');});

시 구절 찾기

jQuery의 가장 기본적인 조작은 도큐먼트의 일부를 선택하는 것이다. $() 생성자로 선택을 수

행한다. 일반적으로 이 함수의 인자는 문자열이며, CSS 선택자 표현을 포함할 수 있다. 앞에서

Page 36: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

10 l Learning jQuery 1.3

본 예제는 도큐먼트에서 poem-stanza 클래스가 적용된 텍스트를 찾는 내용이다. 이 예제의 경

우에는 무척 단순하지만 앞으로 보다 다양하고 정교한 사용 방법들을 소개할 것이다. 도큐먼

트의 일부를 찾아내는 다른 방법들은 2장에서 살펴본다.

$() 함수는 우리가 작업하는 대상 객체를 만들어내는, jQuery의 객체 생성 공장 같은 역할을

한다. jQuery 객체는 여러 개의 DOM 요소를 캡슐화할 수 있으며, 이것을 다양한 방식으로 다

룰 수 있게 해준다. 이 예제에서 우리는 텍스트의 클래스를 바꿈으로써 페이지 모습의 일부를

변경할 것이다.

새로운 클래스 주입하기

글자 그대로, .addClass() 메서드는 선택한 페이지의 일부분에 CSS 클래스를 적용하는 기능

을 수행한다. 이 메서드의 인자는 추가할 클래스의 이름이다. 이 메서드와 반대 기능을 수행하

는 .removeClass() 메서드는 다양한 선택자 표현식과 함께 상당히 자주 사용하게 된다. 이 예

제에서는 간단하게 시 구절에 테두리를 추가하고 기울임 글꼴(이탤릭체)로 텍스트를 강조하는

highlight 클래스를 추가하고 있다.

시의 구절마다 클래스를 추가하기 위해 반복문을 사용하지 않는다는 점을 눈여겨보자. 앞서

이야기한 대로, jQuery는 .addClass() 메서드 내에서 묵시적인 반복을 수행하기 때문에, 단 한

번의 함수 호출로, 도큐먼트에서 선택된 모든 부분들을 한 번에 변경할 수 있다.

코드 수행하기

$()와 .addClass()를 사용하는 것만으로 시 구절의 외관을 바꾸는 데는 부족함이 없다. 하

지만, 만일 이 코드가 HTML 도큐먼트의 헤더 부분에 추가되어 있다면, 텍스트에 아무런 영

향을 주지 못한다. 자바스크립트 코드는 브라우저가 읽어들이는 시점에서 수행되기 때문에,

브라우저가 헤더 부분을 읽을 때 스타일이 적용될 HTML은 아직 존재하지 않은 상태이다.

DOM이 완전히 적재된 다음에 스크립트 코드를 수행하려면, 스크립트의 수행 시점을 늦출

필요가 있다.

수행 시점을 제어하는 가장 일반적인 방법은 자바스크립트 코드를 이벤트 핸들러에서 호출하

는 것이다. 우리는 마우스 클릭이나 키보드 눌림과 같이 사용자가 발생시키는 다양한 이벤트

들에 대해 핸들러를 만들 수 있다. 만일, jQuery를 사용할 수 있는 상황이 아니라면, 페이지(페

Page 37: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

1장 jQuery 시작하기 l 11

이지가 포함하고 있는 모든 이미지)가 렌더링된 다음 발생하는 이벤트인 onload 핸들러를 사

용해야 한다. onload 이벤트에서 코드를 수행하기 위해 코드를 함수 안으로 옮긴다.

function emphasizePoemStanzas() { $('.poem-stanza').addClass('highlight');}

그다음 HTML의 <body> 태그를 수정하여, 이 함수를 호출하도록 이벤트에 할당한다.

<body onload="highlightPoemStanzas();">

이렇게 해서, 페이지가 완전히 로드된 다음 코드가 수행된다.

하지만, 이런 접근 방식에는 단점이 있다. 우리는 변경을 위해 HTML 자체를 수정하였다. 이

방식은 구조와 코드를 강하게 묶어버리기 때문에, 마우스 이벤트와 연결하는 경우와 마찬가지

로 모든 페이지의 해당 요소에 대해 작업을 해주어야 한다. 새로운 행위를 추가하려면 모든 페

이지에 걸쳐 코드와 HTML 둘 다 변경해야 하며, 이 작업은 더 많은 오류를 가져올 가능성이

있으며, 디자이너와 프로그래머 간의 병행 작업을 더욱 어렵게 만든다.

이런 함정을 피하기 위해, jQuery는 $(document).ready() 메서드를 제공하는데, 이 메서드를

사용하면 DOM이 로드되고 이미지가 로드되기 직전에 특정한 작업을 수행할 수 있다. 이 기

능을 다음과 활용할 수 있다.

$(document).ready(highlightPoemStanzas);

이 기법을 사용하면 HTML을 전혀 수정하지 않고, 자바스크립트 파일만 수정하면 된다. 3장에

서 HTML의 구조를 전혀 건드리지 않고 다양한 종류의 사용자 액션에 반응하는 코드를 작성

하는 방법을 살펴볼 것이다.

highlightPoemStanzas() 함수가 단 한 번만 사용되었는데, 좀 더 최적화할 수 있는 여지가

남아있다. 다시 말해, 전역 함수로 사용하는 식별자가 재사용되지 않고 있으므로, 전역 함수로

만들 이유가 별로 없다. 이런 비효율성을 극복하기 위해, 다른 프로그래밍 언어들과 마찬가지

로 자바스크립트도 익명함수 호출(종종 람다함수lambda function라고도 한다) 기능을 제공하고

있다. 원래 코드를 다시 살펴보자.

$(document).ready(function() { $('.poem-stanza').addClass('highlight');});

Page 38: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

12 l Learning jQuery 1.3

함수의 이름을 사용하지 않고 function 키워드만 사용하여, 한정된 영역에서만 코드가 사용

되도록 함수를 정의하고 있다. 이렇게 해서 간결하게 단 3라인으로만 구성된 자바스크립트 코

드를 작성하였다. jQuery는 함수를 인자로 받는 메서드들이 많기 때문에 이러한 표현 방식이

상당히 많이 사용된다.

이렇게 함수 내에서 익명 함수(anonymous function)를 정의하는 문법을 사용할 때, 클로저(closure)

가 생성된다. 이것은 강력한 고급 기능이지만, 중첩 함수를 확장해서 사용하려는 경우 의도하

지 않은 순서로 호출되거나 메모리 사용 문제가 발생할 수 있기 때문에 정확히 이해해 두는 것

이 좋다. 자바스크립트의 클로저에 대한 전반적인 설명은 부록 C를 참조하자.

완성된 산출물

자바스크립트 코드를 적용하면, 다음과 같은 결과를 볼 수 있다.

이제, 시의 구절은 자바스크립트 코드를 통해 alice.css에 정의된 highlight 클래스를 적용

함으로써 이탤릭체로 바뀌었고, 테두리가 만들어졌다.

Page 39: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

1장 jQuery 시작하기 l 13

요약

이제 우리는 개발자가 왜 기초적인 작업이라도 직접 모든 코드를 작성하는 대신 자바스크립트

프레임워크를 사용해야 하는지 알아 보았다. jQuery가 프레임워크로서 뛰어난 장점은 무엇인

지 살펴보았고, 따라서 jQuery를 선택해야 하는 이유에 대해서도 살펴보았다. 또, jQuery를 손

쉽게 사용하는 일반적인 방법들도 알아보았다.

1장에서는 자바스크립트 코드에서 jQuery를 사용하기 위해 어떻게 해야 하는지 공부했고, $()

함수를 사용하여 페이지의 일부분을 검색하고, .addClass() 함수를 사용하여 페이지의 일부

분에 스타일을 추가하였으며, $(document).ready() 함수를 사용하여 페이지가 로딩되는 시점

에 코드가 수행되도록 하였다.

이 간단한 예제는 jQuery가 어떻게 동작하는지 보여주지만, 실전 상황에서 아주 유용하지는 않

다. 2장에서는 이전 코드를 더욱 확장하여 jQuery의 정교한 선택자 언어를 살펴보고, 이 기법

들을 실제로 어떻게 활용하는지 구체적인 사례들을 통해 살펴보자.

Page 40: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리
Page 41: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

15

jQuery 라이브러리는 문서 객체 모델(DOM, Document Object Model)의 요소나 혹은 요소들의

집합에 빠르고 쉽게 접근하는 캐스케이딩 스타일시트(CSS) 선택자 기능을 가지고 있다.1 2장

에서는 선택자들을 어떻게 사용할 수 있는지 알아보고, jQuery 자체적으로 제공하는 사용자정

의 선택자들에 대해서 간단히 살펴본다. 이 외에도 우리가 HTML 요소를 검색하는 데 많은 융

통성을 제공하는 jQuery의 DOM 순회 메서드(DOM traversal methods)에 대해서도 살펴본다.

DOM

jQuery의 가장 강력한 기능 중에 하나는 DOM을 쉽게 순회할 수 있도록 만들어 주는 능력이다.

DOM은 일종의 가계도와 같은 계층적 구조를 가지고 있는데, HTML도 다른 마크업 언어들처

럼 페이지 내에 존재하는 객체들의 관계를 기술할 때 이 모델을 사용한다. 객체들 간의 관계를

언급할 때, 우리가 가족관계를 표현할 때 사용하는 부모, 자식과 같은 용어들을 동일하게 사용

한다. 다음의 간단한 예는 가계도의 은유가 어떻게 도큐먼트에 적용되는지를 보여준다.

<html> <head> <title>the title</title> </head> <body> <div> <p>This is a paragraph.</p> <p>This is another paragraph.</p> <p>This is yet another paragraph.</p> </div> </body></html>

1  (옮긴이) jQuery 1.2 이후에서는 XPath 선택자를 기본을 제공하지 않는다.

02선택자

Page 42: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

16 l Learning jQuery 1.3

여기서, <html>은 다른 모든 요소들의 최상위 조상이다. 거꾸로 말하면, 다른 모든 요소들

은 <html>의 자손들이 된다. 따라서, <html>은 <head>와 <body>의 조상이기도 하면서 또한

<html>은 그들의 부모이기도 하다. <p> 요소들은 <div>의 자식들(동시에 자손들)이고, <body>

와 <html>의 자손들이며, 그들 서로는 형제들이다. 소프트웨어를 사용하여 DOM의 가계도 구

조를 시각화하는 방법에 대한 정보를 원한다면 부록 B를 참고하자.

시작하기 전에 알아야 할 중요한 점 중에 하나는 여러 가지의 선택자들과 메서드들로부터 얻

는 결과 집합이 jQuery 객체라는 사실이다. 우리가 페이지에서 골라낸 요소들에 대해 특정 작

업을 하려고 할 때, jQuery 객체를 사용하면 작업하기가 아주 수월하다. 대상이 되는 객체에 이

벤트를 쉽게 바인딩할 수 있을 뿐만 아니라, 효과를 매끄럽게 추가할 수 있으며, 여러 가지 변

경이나 효과들을 함께 연결할 수 있기 때문이다. 아무튼, jQuery 객체들은 일반적인 DOM 요소

들과 다르며, DOM 요소 혹은 노드 목록에 어떤 작업을 하려 할 때, DOM 요소 자체에서 제공

하는 동일한 메서드나 프로퍼티들을 사용할 필요가 없다는 점을 기억해두자. 2장의 마지막 부

분에서 jQuery 객체로 감싼 DOM 요소에 접근하는 방법들을 살펴볼 것이다.

$()팩터리함수

jQuery에서 사용하려는 선택자가 어떤 형태인지는 중요하지 않다. 어떤 경우이든 시작할 때는

언제나 $()처럼 달러 기호와 괄호를 사용하여 시작한다. 스타일시트에 사용할 수 있는 표현은

어떤 것이던 따옴표로 묶어 괄호 안에 넣으면, 이 표현에 해당되는 요소집합에 jQuery 메서드

를 적용할 수 있게 되는 것이다.

note! 다른 자바스크립트 라이브러리들과 jQuery가 서로 잘 동작하도록 만들기

jQuery에서 달러 표시($)는 jQuery를 줄여서 표현한 것이다. 그런데, $() 함수는 다른

여러 자바스크립트 라이브러리에서 가장 널리 사용되는 함수이기도 하기 때문에 충돌

이 발생할 수도 있다. 만일 하나 이상의 라이브러리들을 같은 페이지에서 사용해야 하

는 경우가 발생한다면, jQuery를 사용하여 개발자가 작성하는 jQuery 코드 내에서 모

든 $ 인스턴스를 다른 문자로 대체하는 방식으로 충돌을 피할 수 있다. 이러한 문제 해

결을 위한 추가적인 해결 방법을 10장에서 소개하고 있다.

선택자의 세 가지 구성요소는 태그명, ID 그리고 클래스이다. 이 요소들은 단독으로 쓰거나 혹

은 다른 선택자와 함께 사용할 수도 있다. 다음 예제는 세 개의 선택자가 각각 어떻게 사용될

Page 43: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2장 선택자 l 17

수 있는지 보여준다.

선택자 CSS jQuery 설명

태그명 p $('p')도큐먼트 내에서 모든 HTML 단락요소(p 요소)들

을 얻어낸다.

ID #some-id $('#some-id')도큐먼트 내에서 some-id라는 ID를 가지는 단일

요소를 가져온다.

클래스 .some-class $('.some-class')도큐먼트 내에서 some-class라는 클래스 이름을

가진 모든 요소를 가져온다.

1장에서 언급한 것처럼, 어떤 것이든 일단 괄호 안에 넣기만 하면 자동으로 반복 순회하여

jQuery 객체로 만들어진다. 따라서, $() 함수를 사용하면, 요소들의 집합에 접근하기 위해 명

시적으로 for 루프를 사용할 필요가 없다.

지금까지 우리는 가장 기본적인 것들에 대해서 다루어보았다. 이로써 좀 더 강력한 선택자들

의 사용방법을 살펴볼 수 있는 준비가 갖추어졌다.

CSS선택자들

jQuery에서는 월드 와이드 웹 컨소시엄 사이트 내의 http://www.w3.org/Style/CSS/#specs에

서 제시하는 CSS 명세서 1에서부터 3까지에 포함되어 있는 대부분의 선택자들을 지원한다. 이

것은 브라우저에서 자바스크립트를 지원하기만 한다면, 다양한 브라우저(특히 인터넷 익스플

로러 6 이하)에서 새로운 선택자들이 항상 지원될 수 있다는 것을 보장하므로, 개발자들로 하

여금 안심하고 웹 사이트를 향상시킬 수 있도록 해준다.

note! 책임감 있는 jQuery 개발자라면, 자바스크립트를 사용하지 못하는 상황에서-혹시 우아

하게 보이지 않는다 하더라도, 언제나 ‘단계적 기능향상(Progressive Enhancement)’2과 ‘단계

적 기능축소(Graceful Degradation)’3 개념을 적용하여 페이지가 정확하게 렌더링되는 것을

보장하여야 한다. 이 책 전반에 걸쳐서 이러한 개념들을 살펴보게 될 것이다.

2  (옮긴이) 항상 콘텐츠가 중심이 되어야 하며, 부차적인 기능이나 외관을 추가할 수 있도록 구조와 표현을 분리하는 것을 말한다. 대표적인 사례가 CSS를 활용하는 것이다. CSS를 적용해서 웹사이트를 만들게 되면 구조와 표현을 분리할 수 있게 되어 CSS를 통해서 어떻게 보여질지를 정할 수 있다. 이런 식으로 부가 기능을 계속 추가 적용하는 것을 단계적 기능향상(progressive enhancement)이라고 한다.

3  (옮긴이) 기능이 없는 환경에서도 동작하도록 만드는 것을 말한다. 자바스크립트가 동작하지 않는 브라우저에서도 최소한 콘텐츠가 보이고 동작하도록 만드는 것을 들 수 있다. 자바스크립트를 정확하게 사용하면, 자바스크립트 기능이 없는 브라우저 사용자들도 동일하게 이용할 수 있다. 이것을 자바스크립트의 단계적 기능축소(graceful degradation)라고 한다.

Page 44: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

18 l Learning jQuery 1.3

jQuery에서 CSS 선택자들을 사용하는 방법을 익히기 위해, 많은 웹 사이트들에서 흔히 볼 수

있는 (중첩되고 정렬되지 않은) 구조를 사용할 것이다.

<ul id="selected-plays" class="clear-after">

<li>희극

<ul> <li><a href="/asyoulikeit/">As You Like It</a></li> <li>All's Well That Ends Well</li> <li>A Midsummer Night's Dream</li> <li>Twelfth Night</li> </ul> </li> <li>비극

<ul> <li><a href="hamlet.pdf">Hamlet</a></li> <li>Macbeth</li> <li>Romeo and Juliet</li> </ul> </li> <li>사극

<ul> <li>Henry IV (<a href="mailto:[email protected]">email</a>) <ul> <li>Part I</li> <li>Part II</li> </ul> </li> <li><a href="http://www.shakespeare.co.uk/henryv.htm">Henry V</a></li> <li>Richard II</li> </ul> </li></ul>

첫 번째 <ul>은 selected-plays라는 ID를 가지는 반면에, <li> 태그에는 아무런 스타일이 적

용되지 않았다는 점을 눈여겨보자. 위의 리스트는 화면에 다음과 같이 표시될 것이다.

Page 45: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2장 선택자 l 19

예상했던 것처럼 중첩된 리스트는, 수직으로 정렬되어 있고, 레벨에 맞추어서 들여쓰기가 되

어 있으며, 글머리기호(bullet)가 적용된 항목들을 보여주고 있다.

리스트 항목 레벨 단위로 스타일 입히기

위의 예에서 최상위 레벨의 항목들을 수평 방향으로 정렬하고자 한다면, 우선 스타일시트에

horizontal 클래스를 정의한다.

.horizontal { float: left; list-style: none; margin: 10px;}

horizontal 클래스는 요소와 그 뒤를 잇는 요소들을 좌측 정렬하게 만들고, 목록 앞의 글머리

기호 표시를 제거하며, 요소의 모든 가장자리에 10 픽셀의 여백을 추가해 준다.

jQuery 선택자를 사용하는 예를 보여주기 위해서, 이 horizontal 클래스를 HTML에 직접 입

력하지 않고, 최상위 레벨의 리스트인 희극, 비극, 사극에 동적으로 설정한다.

$(document).ready(function() { $('#selected-plays > li').addClass('horizontal');});

1장에서 설명한 것처럼, jQuery 코드는 DOM이 로드되자마자 수행되는 래퍼(wrapper) 메서드

$(document).ready()로 시작한다.

Page 46: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

20 l Learning jQuery 1.3

두 번째 라인은 horizontal 클래스를 최상위 항목들에게만 추가할 수 있도록 자식 콤비네이

터(>)를 사용하고 있다. $() 함수 안에 있는 선택자가 의미하는 것은 selected-plays를 ID값

으로 가지는 요소(#selected-plays)의 자식(>) 중에서 리스트 항목(li)을 찾는다는 뜻이다.

이제 클래스를 적용하였으므로, 중첩된 리스트는 다음 그림처럼 보인다.

나머지 다른 모든 항목들(최상위 레벨이 아닌)에 매우 다양한 방법으로 스타일을 입힐 수 있

다. 이미 최상위 레벨 항목들에게 horizontal 클래스를 적용해 보았으므로, horizontal을 클

래스로 가지고 있지 않은 리스트 항목들을 찾는 방법, 즉 부정 의사 클래스(negation pseudo-class)

를 사용해보기로 하겠다. 추가된 세 번째 라인의 코드를 살펴보자.

$(document).ready(function() { $('#selected-plays > li').addClass('horizontal'); $('#selected-plays li:not(.horizontal)').addClass('sub-level');});

이 코드는 다음을 만족하는 리스트 항목들을 선택할 것이다.

selected-plays ID(#selected-plays)11 를 가지고 있는 요소의 자식이며,

horizontal21 클래스를 가지고 있지 않은 항목(:not(.horizontal)).

조건에 맞는 항목들을 찾아서 sub-level 클래스를 적용하면, 해당 항목들은 스타일시트에 정

의되어 있는 배경색을 갖게 된다. 리스트는 다음처럼 보일 것이다.

Page 47: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2장 선택자 l 21

속성선택자

속성 선택자(Attribute selector)는 CSS 선택자 기능의 일부이며 매우 유용하다. 속성 선택자는 링

크의 title 속성이나 이미지의 alt 속성과 같은 HTML 프로퍼티 요소를 지정할 수 있도록 해

준다. 예를 들어, alt 속성을 가지는 모든 이미지를 선택하고 싶다면 다음과 같이 쓸 수 있다.

$('img[alt]')

note! jQuery 1.2 이전 버전에서는 속성 선택자와 XPath의 기능을 제공하기 위해 XML Path

언어(XPath) 문법을 사용했었다. XPath 선택자 기능은 jQuery 핵심 라이브러리에서 제

외되었지만, 여전히 플러그인 형태로 사용이 가능하다.

http://plugins.jquery.com/project/xpath

링크에 스타일 입히기

속성 선택자들은 문자열의 시작부분( )̂ 또는 끝부분($)을 가리키는 정규 표현식 패턴(regular-

expression-like)을 지원한다. 또, 문자열 내의 임의의 위치를 가리키기 위해서 애스터리스크(*)문자

를 가질 수도 있있으며, 특정 문자를 포함하지 않도록 하기 위해 느낌표(!)를 사용할 수도 있다.

만일, 다른 형식을 갖는 링크들을 각각 다른 텍스트 색상으로 출력하고 싶다면, 먼저 스타일시

트에 다음과 같은 스타일들을 정의한다.

a { color: #00c;}a.mailto { background: url(images/mail.png) no-repeat right top; padding-right: 18px;}a.pdflink { background: url(images/pdf.png) no-repeat right top; padding-right: 18px;}a.henrylink { background-color: #fff; padding: 2px; border: 1px solid #000;}

Page 48: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

22 l Learning jQuery 1.3

그런 다음, jQuery를 사용하여 세 가지 클래스들(mailto, pdflink, mysite)을 각각 적절한

링크에 적용해보도록 하겠다.

먼저, href 속성([href]) 값이 mailto:로 시작(^="mailto:")하는 링크 요소들을 찾는 선택자

구문을 먼저 생성한다. 이 구문은 다음과 같다.

$(document).ready(function() { $('a[href^=mailto:]').addClass('mailto');});

PDF 파일 링크에 클래스를 추가하기 위해, 캐럿 표식( )̂이 아닌 달러 표식($)을 사용해야 한

다. 이렇게 하는 이유는 href의 값이 .pdf로 끝나는 문자열을 구하기 위해서다.

$(document).ready(function() { $('a[href^=mailto:]').addClass('mailto'); $('a[href$=.pdf]').addClass('pdflink');});

속성 선택자를 조합하여 사용할 수도 있다. 예를 들어, http로 시작하며 henry를 포함하는

href 값을 가진 모든 링크에 henrylink 클래스를 추가하려면 다음과 같이 할 수 있다.

$(document).ready(function() { $('a[href^=mailto:]').addClass('mailto'); $('a[href$=.pdf]').addClass('pdflink'); $('a[href^=http][href*=henry]') .addClass('henrylink');});

세 개의 클래스가 링크가 적용되면 다음과 같이 보일 것이다.

Hamlet 링크 오른쪽에 PDF 아이콘 표시, email 링크에 편지봉투 아이콘 그리고, Henry V 링

크의 주변에 흰색배경과 검정색 테두리를 확인하자.

Page 49: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2장 선택자 l 23

사용자정의선택자들

다양한 CSS와 XPath의 선택자들 외에도, jQuery는 고유한 사용자정의(Custom) 선택자들을 추가

로 가지고 있다. 사용자정의 선택자들의 대부분은 배열에서 임의의 요소를 추출하는 데 사용

하게 된다. CSS의 의사 클래스(pseudo-class) 구문과 동일하게, 선택자의 구문은 콜론(:)으로 시

작한다. 예를 들어, horizontal 클래스를 가지는 div 집합 중에서 두 번째 항목을 선택하려고

한다면, 다음처럼 작성할 수 있다.

$('div.horizontal:eq(1)')

eq(1)은 선택된 집합에서 두 번째 항목이라는 점을 기억하자. 자바스크립트 배열에서 인덱스

숫자는 0을 기반으로 한다. 이 말의 뜻은 jQuery 배열도 0을 시작으로 한다는 뜻이다. 이와는

다르게, CSS는 1을 기반으로 하기 때문에, $('div:nth-child(1)')와 같은 CSS 선택자는 부모

의 첫 번째 자식에 해당하는 div를 가져온다(이 경우, $('div:first-child') 를 사용할 수도 있다).

행에 징검다리 스타일 입히기

jQuery 라이브러리에서 두 가지의 아주 유용한 사용자정의 선택자로 :odd와 :even이 있다. 다

음과 같이 테이블에 간단하게 줄무늬를 입히면서, 우리가 이 선택자들을 어떻게 사용할 수 있

는지 살펴보도록 하자.

<table> <tr> <td>As You Like It</td> <td>희극</td> <td></td> </tr> <tr> <td>All's Well that Ends Well</td> <td>희극</td> <td>1601</td> </tr> <tr> <td>Hamlet</td> <td>비극</td> <td>1604</td> </tr> <tr> <td>Macbeth</td>

<다음 쪽에 예제 코드 계속>

Page 50: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

24 l Learning jQuery 1.3

<td>비극</td> <td>1606</td> </tr> <tr> <td>Romeo and Juliet</td> <td>비극</td> <td>1595</td> </tr> <tr> <td>Henry IV, Part I</td> <td>사극</td> <td>1596</td> </tr> <tr> <td>Henry V</td> <td>사극</td> <td>1599</td> </tr></table>

이제 테이블의 모든 행을 위한 스타일을 추가하고, 짝수 행을 위한 alt 클래스를 다음과 같이

추가한다.

tr { background-colgmlrmror: #fff;}.alt { background-color: #ccc;}

마지막으로, 짝수 테이블 행(<tr> tags)에 클래스들을 추가하는 jQuery 코드를 작성한다.

$(document).ready(function() { $('tr:odd').addClass('alt');});

잠깐! 왜 여기서 짝수 행들을 선택하기 위해 .odd 선택자를 사용했을까? :eq() 선택자를 사용

할 때처럼, :odd()와 :even() 선택자들은 0으로 시작하는 자바스크립트의 번호를 사용한다.

따라서, 첫 번째 행은 0(짝수)으로, 두 번째 행은 1(홀수)로 표현된다. 이 점을 염두에 두고, 테

이블이 다음과 같은 화면 출력을 확인해 보자.

Page 51: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2장 선택자 l 25

페이지에 테이블이 하나 이상 있다면 의도하지 않던 결과가 나타날 수 있음에 주의하자. 예를

들어, 이 테이블의 마지막 행이 흰색의 배경색을 가지고 있기 때문에, 다음 테이블의 첫 번째

행은 의도한 바와 다르게 회색을 배경으로 가지게 된다. 이 문제를 해결하는 방법 중의 하나는

:nth-child() 선택자를 사용하는 것이다. 이 선택자의 인자로 odd 혹은 even를 지정할 수 있

다. :nth-child()은 1부터 시작하는 jQuery 선택자라는 점에 주의하자. 하나의 도큐먼트에 존

재하는 여러 테이블에 일관성 있게 줄무늬를 넣으려면, 다음과 같이 작성하면 된다.

$(document).ready(function() { $('tr:nth-child(even)').addClass('alt');});

사용자정의 선택자의 마지막 부분을 살펴보기 위해서, 테이블에서 ‘Henry’라는 텍스트를 포함

한 셀만 강조하고자 한다고 가정하자. 이 경우 우리가 해야 할 일은 단지, 텍스트에 볼드와 이

탤릭 속성을 지정하는 클래스 ( .highlight {font-weight:bold; font-style: italics;} )

를 스타일시트에 추가하고, :contains() 선택자를 사용해서 jQuery 코드에 하나의 라인을 추가

하는 정도이다.

$(document).ready(function() {$('tr:nth-child(even)').addClass('alt'); $('td:contains(Henry)').addClass('highlight');});

이제, 우리는 이제 ‘Henry’라는 텍스트가 강조되고 줄무늬가 들어간 멋진 테이블을 볼 수 있다.

Page 52: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

26 l Learning jQuery 1.3

여기서 기억해야 할 중요한 점은 :contains() 선택자가 대소문자를 구분한다는 점이다. 대문

자 "H"를 사용하지 않도록 $('td:contains(henry)') 를 사용하면, 아무 셀도 선택되지 않을 것

이다.

물론, jQuery 또는 클라이언트 측 프로그래밍을 사용하지 않고도 강조할 수 있는 방법들은 많

다. 그렇지만 내용이 동적으로 생성될 때나, HTML이나 서버 측 코드에 접근할 수 없을 경우,

jQuery(CSS와 함께)를 사용하여 스타일을 입히는 것이 훌륭한 대안이 될 수 있다.

폼 선택자

폼을 가지고 작업할 때, jQuery의 커스텀 선택자를 사용하면 우리가 원하는 요소만을 간단하게

뽑아낼 수 있다. 다음 테이블은 선택자로 유용하게 사용할 수 있는 표현들이다.

선택자 매칭

:text, :checkbox, :radio, :image, :submit, :reset, :password, :file

속성이 선택자의 이름과 동일(콜론은 제외)한 입력요소. 예를 들어,

:text 선택자는 <input type="text">와 매치된다.

:input입력(Input), 텍스트영역(textarea), 셀렉트(select), 그리고 버튼

(button) 요소

:button 버튼 요소와 type 속성이 button인 입력(input) 요소

:enabled 활성화된 폼 요소

:disabled 비활성화된 폼 요소

:checked 체트된 라디오 버튼(radio button) 혹은 체크박스(checkbox)

:selected 선택된 옵션 요소

다른 선택자들과 마찬가지로 폼 선택자들 역시 조합하여 사용할 수 있다. 예를 들어,

$(':radio:checked')를 사용하여 선택된 모든 라디오 버튼(체크박스는 제외)을 선택하거나,

$(':password, :text:disabled')로 모든 패스워드 입력과 비 활성화된 텍스트 입력 요소들을

선택할 수 있다. 커스텀 선택자의 경우도 매치되는 요소를 찾기 위해 만드는 CSS의 원리를 동

일하게 적용할 수 있는 것이다.

Page 53: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2장 선택자 l 27

DOM순회메서드들

지금까지 살펴보았던 jQuery 선택자들은 DOM 트리를 참조하여 내려가면서 순회하고 그 결과

를 필터링하여 요소 집합을 얻을 수 있게 해준다. 만일 요소들을 순회하는 방법으로 앞 방향만

가능했다면, 우리의 선택은 상당히 제한적이었을 것이다(솔직히, 일반적인 DOM 스크립트와

비교해도, 선택자 표현식들이 그 자체만으로도 강력하다고 할 수 있다). 종종 부모나 조상 요

소를 얻어야 할 필요가 많이 생긴다. jQuery의 DOM 순회 메서드들을 이런 경우에 사용한다.

우리가 처리해야 할 곳에 순회 메서드들을 사용하면, 위로 혹은 아래로 그리고 모든 DOM 트

리 전체를 쉽게 검색할 수 있다.

메서드들 중에서 일부는 선택자 표현식과 거의 동일한 표현을 가지고 있다. 예를 들면, alt 클

래스를 추가하기 위해 사용했던 $('tr:odd').addClass('alt');은 다음 코드처럼 .filter() 메

서드로 대체할 수 있다.

$('tr').filter(':odd').addClass('alt');

하지만, 대부분의 경우 요소를 얻기 위한 두 가지 방법은 상호 보완관계에 있다. 또한, .filter()

메서드는 인자를 지정할 수 있기 때문에 매우 강력하다. 이 기능을 사용하면 요소들이 특정한

집합에 속하는지 아닌지를 확인할 수 있는 복잡한 테스트를 만들어 낼 수 있다. 예를 들어, 모

든 외부 링크에 클래스를 추가한다고 가정해 보자. jQuery는 이런 경우를 처리하는 선택자를

가지고 있지 않다. filter 기능이 없다면, 우리는 명시적으로 루프를 돌려가며 일일이 검사를 해

야 할 것이다. 다행이, 다음 코드와 같이 filter 기능을 사용하여 묵시적인 순환을 사용하여 코

드를 간결하게 유지할 수 있다.

$('a').filter(function() { return this.hostname && this.hostname != location.hostname;}).addClass('external');

두 번째 라인은 다음 조건으로 <a>요소를 필터링 하고 있다.

도메인 이름(11 this.hostname)을 가진 href 속성을 가진다. 우리는 이 검사를 통해

mailto 링크를 제외 시킬 수 있다.

링크된 도메인 이름(21 this.hostname)이 현재 페이지(location.hostname)의 도메인 이

름을 가지고 있지 않아야(!=) 한다.

Page 54: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

28 l Learning jQuery 1.3

좀 더 자세히 말해, .filter() 메서드는 매치된 요소의 집합을 순회하면서, 각각에 대해 실행

한 함수의 반환 값을 검사한다. 만일, 함수의 반환 값이 거짓(false) 이면, 요소는 매치된 집합

에서 제거되며, 참(true)이면 요소를 유지한다.

이 메서드들을 사용하여 무엇을 할 수 있는지를 알아보기 위해 줄무늬 테이블을 다시 살펴보자.

특정 셀에 스타일 입히기

앞서 우리는 Henry라는 텍스트를 포함하는 모든 셀에 highlight 클래스를 추가했었다.

Henry라는 텍스트를 포함하는 다음 셀에 스타일을 적용하는 대신, 다음과 같이 이미 작성했

던 선택자 앞에 간단히 next() 메서드만 추가해도 된다.

$(document).ready(function() { $('td:contains(Henry)').next().addClass('highlight');});

적용된 테이블은 다음 그림처럼 보일 것이다.

.next() 메서드는 오로지 바로 옆의 이웃 요소만을 반환해 준다. Henry를 포함하는 셀 다음

에 오는 모든 셀을 하이라이트하려면, nextAll() 메서드를 사용할 수도 있다.

$(document).ready(function() { $('td:contains(Henry)').nextAll().addClass('highlight');});

note! 여러분이 예상하는 대로, .next()와 .nextAll()는 .prev()와 .prevAll()의 반대이다.

덧붙여, .siblings()는 다음에 오거나 이전에 있거나 상관없이 동일한 DOM 레벨에 존

재하는 모든 요소를 골라낸다.

Page 55: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2장 선택자 l 29

다음에 오는 셀들과 함께 원래 셀(Henry를 포함하는 셀)을 포함시키려면 .andSelf() 메서드

를 사용한다.

$(document).ready(function() { $('td:contains(Henry)').nextAll().andSelf().addClass('highlight');});

확인을 위해, 동일한 요소 집합을 선택하는 다중 선택자와 조회 메서드를 조합해서 사용할 수

있다. 다음 예제는 Henry를 포함한 셀이 최소한 하나 이상 존재하는 행에 있는 모든 셀을 선

택하는 다른 방법을 보여준다.

$(document).ready(function() { $('td:contains(Henry)').parent().children().addClass('highlight');});

여기서는 형제 요소들을 모두 순회하는 대신, .parent()을 사용하여 DOM 레벨상에서 한 레

벨 위인 <tr>로 이동하고 .children() 메서드를 사용하여 모든 행의 모든 셀을 선택하고 있다.

체인

앞서 살펴본 순회 방법들은 모두 jQuery의 체인 능력을 보여주고 있다. jQuery를 사용해서 요

소의 다중 집합을 얻어 다양한 조작을 할 수 있는데, 그것을 하나의 코드 라인에 모두 표현하

는 것도 가능하다. 체인은 jQuery 코드를 간결하게 만드는 데 도움이 되지만, 선택자를 다시 기

술하여 스크립트의 성능을 향상하는 데도 도움이 된다.

코드의 가독성을 위해서 하나의 코드라인을 여러 라인으로 분리할 수도 있다. 예를 들어, 다음

과 같이 한 줄로 쓸 수도 있고,

$('td:contains(Henry)').parent().find('td:eq(1)') .addClass('highlight').end().find('td:eq(2)') .addClass('highlight');

일곱 라인으로 나눌 수도 있다.

$('td:contains("Henry")') // "Henry"를 포함하는 셀을 얻는다

.parent() // 부모를 얻는다

.find('td:eq(1)') // 부모셀 안에서 두 번째 셀을 찾는다.

.addClass(highlight') // "highlight" 클래스를 셀에 추가한다.

.end() // "Henry"를 포함한 셀의 부모로 되돌아 간다.

.find('td:eq(2)') // 부모셀 안에서 세 번째 셀을 찾는다

.addClass('highlight'); // "highlight" 클래스를 셀에 추가한다.

Page 56: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

30 l Learning jQuery 1.3

분명, 예제에서 살펴본 DOM 순회 방법들은 지나치게 불합리하며 우회적인 방법들을 취하고

있다. 분명 좀 더 간단하고 직접적인 방식들이 존재하며, 이런 사용 방법은 결코 추천하지는

않는다. 이 예제들은 체인이 제공하는 유연함의 극치를 보여주기 위한 예제일 뿐이다.

체인은 전체 문단을 한 번에 말하는 것과 같다. 단숨에 말할 수도 있지만, 그 코드를 이해해야

하는 다른 사람들에게는 이해하기 어려운 코드로 보일 수 있다. 긴 안목으로 보면, 여러 라인

으로 쪼개서 그에 알맞은 주석을 추가하는 것은, 어쩌면 더 많은 시간을 절약하는 데 도움이

될 수도 있다.

DOM요소접근하기

모든 선택자 표현식과 대부분의 jQuery 메서드들은 거의 대부분 jQuery 객체를 반환한다. 왜냐

하면, 묵시적인 반복이나 체인이 가능하기 때문이다.

하지만, 아직까지는 jQuery 객체가 감싸고 있는 DOM 요소를 직접 접근해야 할 필요가 있을 수

있다. 예를 들어, 다른 자바스크립트 라이브러리를 사용할 경우, 그 라이브러리가 사용하게 될

요소 집합을 DOM으로 제공해야 할 경우도 있다. 혹은, DOM 요소의 프로퍼티를 요소의 태그

이름으로 접근할 필요가 생길 수도 있다. 흔한 경우는 아니지만, 이런 경우를 위해 jQuery에서

는 .get() 메서드를 제공하고 있다. 만일 jQuery 객체가 참조하고 있는 첫 번째 DOM 엘리먼

트에 접근하고 싶다면 .get(0)과 같이 사용할 수 있으며, 만일 DOM 요소가 반복 루프에서 사

용된다면, .get(index)처럼 사용할 수 있을 것이다. 그 외에도, "my-element"를 아이디로 갖

는 요소의 태그 이름을 알고 싶다면, 다음처럼 코드를 작성할 수 있을 것이다.

var myTag = $('#my-element').get(0).tagName;

이보다 훨씬 간편한 방식을 원한다면, jQuery가 제공하는 .get()의 간편한 표현식을 활용할 수

있다. 예를 들어, $('#my-element').get(0) 대신, $('#my-element')[0] 처럼 대괄호를 사용할

수도 있다.

var myTag = $('#my-element')[0].tagName;

이 구문이 DOM 요소 배열처럼 보이는 것은 우연이 아니다. 첨자(이 경우는 0)를 포함하여 대

괄호를 사용하는 것은 jQuery 래퍼를 벗겨서 DOM 요소를 얻어내는 것과 동일한 역할을 한다.

Page 57: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

2장 선택자 l 31

요약

이제 우리는 2장에서 설명했던 기술들로 CSS 선택자들을 이용하여 중첩된 리스트의 상, 하위

레벨의 항목에 스타일을 입힐 수 있게 되었으며, 기본 속성 선택자들을 사용하여 링크에 각각

다른 스타일을 적용할 수 있게 되었고, 사용자정의 jQuery 선택자들인 :odd와 :even 혹은 고

급 CSS 선택자인 :nth-child()를 사용하여 테이블에 기본적인 줄무늬를 추가할 수 있게 되었

으며, jQuery 메서드들의 체인을 사용하여 임의의 테이블 셀들의 텍스트를 강조할 수 있게 되

었다.

지금까지 $(document).ready() 이벤트를 사용하여 요소의 집합에 클래스를 추가했었다. 다

음 3장에서는 다양한 사용자 이벤트에 응답하는 클래스를 추가하는 방법에 대해서 살펴볼 것

이다.

Page 58: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리
Page 59: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

33

자바스크립트는 사용자 상호작용과 여러 가지 이벤트들을 처리할 수 있는 다양한 방법을 제공

한다. 동적으로 변화하거나 사용자의 동작에 반응하는 페이지를 구성하려면, 지금까지 배웠던

그리고 앞으로 학습하게 될 jQuery 코드가 원하는 시점에서 수행되도록 해야 한다. 이것은 순

수 자바스크립트만으로도 충분히 가능한 일이다. 하지만, jQuery를 사용하여 자바스크립트가

가지고 있는 이벤트 처리 기능을 모두 사용하면서도 보다 강력하면서 멋진 구문으로 확장하고

개선할 수 있다.

페이지로드시점에작업수행하기

이전에 설명한 바와 같이, 페이지가 로드될 때 jQuery 코드가 동작하도록 하기 위해 $(document).

ready() 이벤트 핸들러에서 특정 함수를 수행하도록 하였다. 이 부분에 대해서 조금 상세히 살펴

보자.

코드 실행 시간

1장에서 우리는 $(document).ready()가 자바스크립트의 onload 이벤트의 기능을 대신하기

위한 jQuery의 기능이라는 점을 살펴보았다. 이 두 가지는 비슷한 결과를 가지지만, 함수를 호

출하는 시점에 다소 차이가 있다.

window.onload 이벤트는 관련된 모든 도큐먼트가 브라우저로 다운로드된 후에 발생한다. 이 이

야기는 자바스크립트에서 페이지의 모든 요소에 접근할 수 있다는 것을 의미하는 것으로써, 다시

말해, 요소들이 로드되는 순서를 고려할 필요가 없게 해 주는 매우 좋은 기능으로 볼 수 있다.

반면에, $(document).ready()를 사용하여 등록된 핸들러는 DOM이 로드되어 사용할 준비가

03이벤트

Page 60: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

34 l Learning jQuery 1.3

끝나는 시점에 바로 호출된다. 이것 역시, 스크립트에서 모든 요소들에 접근할 수 있다는 것을 의

미한다. 하지만 중요한 차이점이 있는데, 관련된 모든 파일들이 다운로드된 후를 의미하는 것은

아니라는 점이다. HTML이 다운로드되자마자 다른 관련 파일들(이미지 등)의 다운로드 완료 상

태와 상관없이 바로 DOM 트리로 파싱되고, 곧바로 우리가 작성한 코드가 실행되도록 되어 있다.

note! 자바스크립트 코드가 실행되기 전에 스타일이 완전히 적용되었다는 것을 보증하기 위

해, 도큐먼트의 <head> 요소 내에서, <link rel="stylesheet"> 태그를 <script> 앞

에 위치하도록 하는 것이 좋다.

이것에 대한 장점을 설명하기 위해, 이미지를 보여주는 갤러리 페이지를 생각해 보도록 하자.

이 페이지에는 jQuery를 사용해서 숨기기, 보여주기, 움직이기, 또는 그 외의 다양한 조작의 대

상이 되는 다수의 커다란 이미지들을 포함하고 있을 것이다. 만일 우리가 onload 이벤트를 사

용하여 사용자 인터페이스를 구현했다면, 사용자들은 페이지를 사용하기 전에 각각의 모든

이미지들이 완전히 다운로드되기만을 기다려야 한다. 더 안 좋은 점은, 링크처럼 기본 행위

(behaviors)가 특정 요소에 설정되기 전이라면, 사용자의 상호작용은 의도하지 않은 결과를 낳을

수도 있다. $(document).ready()를 사용하여 행위자를 지정하였다면, 훨씬 더 일찍 특정 동작으

로 연결되어, 사용자 인터페이스는 이미 사용할 수 있는 준비가 끝나고도 남았을 것이다.

note! 앞에서 설명한 것처럼, 대부분의 경우 onload 핸들러를 직접 사용하는 것보다

$(document).ready()를 사용하는 것이 바람직하다고 할 수 있다. 하지만, 관련 파일들

이 완전히 로드되지 않았을 수도 있기 때문에, 이미지 높이와 너비와 같은 속성들까지

항상 사용 가능한 것은 아니라는 점에 유념해야 한다. 만일 이러한 기능을 원하지 않는

다면, 필요에 따라서 onload 핸들러(또는 jQuery의 .load() 이벤트 핸들러 설정)를 사

용하여 구현할 수도 있다. 언제든지 이 두 가지 방법은 서로 충돌 없이 같이 사용할 수

있다.

하나의 페이지에 다중 스크립트 사용하기

(HTML 태그 속성으로 핸들러를 직접 추가하는 방법을 제외하고) 자바스크립트를 사용해서

이벤트 핸들러를 추가하는 일반적인 방법은, DOM 요소 객체 속성에 함수를 할당하는 것이다.

예를 들어, 다음과 같은 함수를 정의하였다고 가정하자.

function doStuff() { // 작업 수행...

}

Page 61: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 35

HTML 태그 안에 직접 함수를 할당할 수도 있다.

<body onload="doStuff();">

혹은, 다음과 같이 자바스크립트 코드 안에서 함수를 할당할 수도 있다.

window.onload = doStuff;

이 두 가지 모두 페이지가 로드될 때 특정 함수가 실행되도록 하고 있다. 이 중에 두 번째 방식

은 태그로부터 행위가 좀 더 분명하게 분리되는 장점을 가지고 있다.

note! 함수를 핸들러로 할당할 때 괄호는 제외하고 함수 이름만 사용해야 한다는 점에 주의하

자. 괄호까지 사용하게 되면, 함수가 즉각 호출된다. 괄호를 지정하지 않으면 단지 함수

의 이름만 인식되어 나중에 호출된다.

하나의 함수로는 잘 동작한다. 그러나, 다음과 같은 별도의 함수를 가지고 있다고 가정해 보자.

function doOtherStuff() { // 다른 작업 수행...

}

페이지가 로드될 때, doOtherStuff()도 함께 수행되어야 할 경우도 있다.

window.onload = doOtherStuff;

하지만, 이 코드는 처음 할당한 함수를 제거하게 된다. .onload 속성은 오로지 하나의 함수만

저장할 수 있기 때문에 이미 등록된 함수가 존재하는 경우, 여기에 다른 함수를 다시 할당하게

되면 잘못된 결과를 낳게 된다.

$(document).ready()를 사용하면, 이런 상황을 아주 훌륭하게 처리할 수 있다. .ready() 메서

드를 호출하여 추가된 함수들은 내부의 큐에 모두 로드되기 때문에, 페이지가 로드될 때 등록

된 모든 함수들이 순서대로 실행된다.

note! 다행히도 이런 문제를 회피하는 방법이 jQuery로만 가능한 것은 아니다. 여러 핸들러

들을 누적할 수 있고, onload 이벤트에서 누적된 함수를 호출해 줄 수 있는 함수를 직

접 만들어 사용할 수도 있다. 하지만, 이러한 접근 방식(심슨 윌슨의 addLoadEvent()

예에서 사용되었던1)은 $(document).ready()처럼 중복된 핸들러들의 충돌은 피할 수

1  (옮긴이) 심슨 윌슨의 블로그에서 이벤트를 중복해서 할당하는 방법에 대해 설명하고 있다. http://simonwillison.net/2004/May/26/addLoadEvent/  

Page 62: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

36 l Learning jQuery 1.3

있을지 모르지만, 앞서 설명했던 다른 장점들이 부족하다고 할 수 있다. document.

addEventListener()와 document.attachEvent() 같이 특정 브라우저에 종속적인

메서드들은 유사한 기능을 제공하지만, jQuery는 브라우저간의 차이에 신경 쓰지 않고

도 동일한 목적을 달성할 수 있다.

간결하게 단축된 코드

$(document).ready() 생성자는 실제로 DOM의 도큐먼트 요소들을 사용하여 jQuery 객체의

.ready() 메서드를 호출하고 있다. 이것은 아주 빈번하게 사용되는 작업이기 때문에, 더 짧고

쉽게 사용할 수 있는 방식으로 $() 팩토리 함수를 제공하고 있다. 인자 없이 함수를 호출하면,

이 함수는 도큐먼트 객체가 전달된 것으로 인식하고 동작한다. 즉 다음 코드를,

$(document).ready(function() { // 여기에 여러분의 코드를 작성한다…

});

아래와 같이 쓸 수 있다.

$().ready(function() { // 여기에 여러분의 코드를 작성한다…

});

이뿐만 아니라, 팩터리 함수는 함수를 인자로 넘겨 받을 수도 있다. 만일 함수를 넘기면 jQuery

는 묵시적으로 .ready() 함수를 호출하여 수행한다. 따라서, 다음과 같은 코드로 동일한 결과

를 얻을 수 있다.

$(function() { // 여기에 여러분의 코드를 작성한다…

});

비록 이 코드가 다른 구문들보다 짧기는 하지만 저자는 코드의 동작을 분명하게 보여주는 긴

구문을 더 추천한다.

다른 라이브러리와 공존

가끔, 하나의 페이지에 두 개 이상의 자바스크립트 라이브러리를 사용해야 할 경우가 생길 수

있다. 많은 라이브러리들이 $ 식별자를 (짧고 간결하기 때문에)사용하고 있기 때문에, 이런 이

Page 63: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 37

름들이 충돌하는 것을 막을 방법이 필요하다.

다행히도, jQuery는 다른 라이브러리에 $ 식별자에 대한 제어를 넘겨주는 .noConflict()라는

메서드를 제공한다. 일반적으로 .noConflict()는 다음과 같은 형식으로 사용한다.

<script src="prototype.js" type="text/javascript"></script><script src="jquery.js" type="text/javascript"></script><script type="text/javascript"> jQuery.noConflict();</script><script src="myscript.js" type="text/javascript"></script>

우선, 다른 라이브러리(예를 들어, Prototype)을 포함시키고, 그 다음 jQuery를 포함시켜 $를 점

유한다. 그러고 나서, .noConflict()를 호출하여 $에 대한 제어권을 놓아주어, 이전에 로드한

라이브러리(Prototype)에서 $를 사용할 수 있도록 한다. 이렇게 하면, 우리가 만드는 스크립트

에서는 두 라이브러리 모두를 사용할 수 있게 된다. 하지만, jQuery 메서드를 사용하려면 $ 대

신 jQuery라는 식별자를 사용해야 한다.

이 상황에 도움이 될만한 .ready() 메서드 관련 기법이 있다. 콜백함수는 jQuery 객체 자체를

인자로 받는데, 이것은 충돌을 피하기 위해 이름들을 변경할 때 내부에서는 $를 그대로 사용할

수 있으므로 매우 효과적이다.

jQuery(document).ready(function($) { // 여기에는, $를 그대로 사용할 수 있다.

});

혹은, 앞서 배운 방법을 사용하여 보다 짧게 기술할 수도 있다:

jQuery(function($) {

// $를 사용하는 코드

});

기본이벤트들

페이지를 로딩하는 시간 외에도 특정 작업 처리를 필요로 하는 시점은 매우 많다. 자바스크립

트에서 페이지 로드 이벤트를 가로채기 위해 <body onload=""> 또는 window.onload을 사

용하도록 하는 것처럼, 마우스가 클릭될 때(onclick)나 폼의 입력 필드의 값이 변경될 때

(onchange), 또는 윈도우의 크기가 달라질 때(onresize)에 사용자가 특정 작업을 할 수 있도록

Page 64: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

38 l Learning jQuery 1.3

이벤트들을 제공한다. DOM 요소들을 직접 사용하여 이벤트들을 할당하는 방법은 onload에서

설명했던 것과 유사한 단점들을 가지게 된다. jQuery는 이벤트들을 처리하는 더 나은 방법들을

제공하고 있다.

간단한 스타일 변환기

이벤트 처리를 위한 기법들을 설명하기 위해, 사용자의 선택에 따라서 각각 다른 스타일로 보

여주는 페이지를 만들고 싶다고 가정하자. 사용자가 버튼을 클릭하면 일반 화면, 칼럼이 좁아

서 텍스트의 너비가 제약된 화면, 또는 콘텐트 내용을 확대해서 보여주는 화면들을 선택적으

로 보여주는 페이지를 만들어 보자.

현실적으로, 훌륭한 웹 개발자라면 여기에 ‘단계적 기능향상(progressive enhancement)’을 적용할

것이다. 스타일 변환기(style switcher)에 자바스크립트가 사용될 수 있으면 좋겠지만, 그렇지 않

은 경우에는 버튼을 숨기고 페이지를 선택하기 위한 링크를 대신 사용할 것이다. 이 예제에서

는 모든 사용자들이 자바스크립트를 활성화시킨 상태라고 가정하겠다.

스타일 변환기를 위한 HTML 태그는 다음과 같다.

<div id="switcher"> <h3>스타일 변환기</h3> <div class="button selected" id="switcher-default"> Default </div> <div class="button" id="switcher-narrow"> Narrow Column </div> <div class="button" id="switcher-large"> Large Print </div></div>

위의 코드가 포함된 HTML 태그와 약간의 기본적인 CSS를 사용해서 페이지의 나머지를 구성

하여, 다음 그림과 같은 페이지를 만들었다.

Page 65: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 39

Large Print 버튼에 사용될 함수를 만드는 것부터 시작하기로 하자. 우선 페이지의 외형을 지정

하기 위한 CSS부터 준비하도록 하겠다.

body.large .chapter { font-size: 1.5em;}

가장 먼저 해야 할 일은 <body> 태그에 large 클래스를 적용하는 것이다. 이렇게 하면 페이지

가 주어진 스타일로 재구성될 것이다. 2장에서 배운 내용을 적용하여, 다음과 같이 코드를 작

성할 수 있다.

'body').addClass('large');

그런데, 앞의 코드를 페이지가 로드되는 시점이 아니라, 버튼이 클릭되는 시점에서 수행하도

록 하고 싶다. 그렇게 하려면 먼저 .bind() 메서드부터 알아보아야 할 것이다. 이 메서드는 자

바스크립트가 제공하는 이벤트에, 행위자를 할당하는 역할을 담당하고 있다. 이 예제에서는

click 이벤트를 사용하며 한 개의 라인으로 구성된 함수를 이 이벤트에 추가할 것이다.

Page 66: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

40 l Learning jQuery 1.3

$(document).ready(function() { $('#switcher-large').bind('click', function() { $('body').addClass('large'); });});

이제 버튼이 클릭되면, 코드가 실행되어 다음 그림에서 보는 것과 같이 텍스트가 강조되는

모습을 볼 수 있다.

이것이 이벤트를 연결하기 위해 필요한 전부다. 앞에서 설명한 .ready() 메서드의 장점들이

적용되어 있다. 다수의 .bind() 메서드 호출을 사용하고 있는데, 동일한 이벤트에 여러 개의

행위들을 필요한 만큼 추가할 수 있다.

물론, 이 방법이 가장 훌륭하고 효율적인 방법이라고 할 수는 없지만, 3장의 나머지 부분을 통

해 훨씬 깔끔한 코드로 확장되고 개선될 것이다.

다른 버튼 활성화하기

이제, 앞서 이야기한 것처럼 Large Print 버튼을 동작하게 만들었다.

나머지 버튼들(Default와 Narrow Column)도 각 버튼의 기능을 수행할 수 있도록, 핸들러를

할당해 보자. 방법은 간단하다. .bind()를 사용하여 버튼 클래스를 제거하거나 혹은 추가하는

click 핸들러를 할당하면 된다. 새로운 코드는 다음과 같다.

Page 67: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 41

$(document).ready(function() { $('#switcher-default').bind('click', function() { $('body').removeClass('narrow'); $('body').removeClass('large'); }); $('#switcher-narrow').bind('click', function() { $('body').addClass('narrow'); $('body').removeClass('large'); }); $('#switcher-large').bind('click', function() { $('body').removeClass('narrow'); $('body').addClass('large'); });});

이 코드는 narrow 클래스의 CSS 규칙과 연결되어 있다.

body.narrow .chapter { width: 400px;}

이제, Narrow Column 버튼을 클릭하면 그와 연관된 CSS가 적용되어 다음 그림과 같이 텍스트

가 다르게 표시된다.

Default를 클릭하면 <body> 태그로부터 클래스가 제거되며, 페이지는 초기 렌더링 상태로 돌

아간다.

Page 68: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

42 l Learning jQuery 1.3

이벤트 핸들러 컨텍스트

스타일 변환기 버튼이 올바르게 작동하고 있지만, 한 가지 아쉬운 점은, 현재 어느 버튼이 활

성 상태인지 알려주는 피드백이 없다는 것이다. 이 문제를 해결하기 위해서, 버튼을 클릭할 때

해당 버튼에 selected 클래스를 적용하여 표시하고, 다른 버튼들이 클릭되면 그 클래스를 제

거하는 방법을 사용할 것이다. selected 클래스는 버튼의 텍스트를 굵은 텍스트(bold)로 바꿔

준다.

.selected { font-weight: bold;}

필요에 따라 각 버튼의 ID를 참조하여 클래스를 적용하거나 제거하는 방법으로 클래스를 변경

할 수 있다. 하지만 이번에는 이 방법 대신, 실행 중인 이벤트 핸들러의 컨텍스트를 이용하는

보다 멋지고 안전한 방식을 살펴보고자 한다.

이벤트 핸들러가 실행되는 동안 사용할 수 있는 키워드인 this는 핸들러가 추가된 DOM 요소

를 가리킨다. 앞서 $() 팩토리 함수를 사용해서 행위자를 추가하기 위해 DOM 요소를 넘긴 적

이 있었다. 이 때 넘겨진 DOM 요소가 this이며, 코드작성에 유용하게 사용할 수 있는 편리한

키워드이다. 이벤트 핸들러 안에서 $(this)를 사용하면 DOM 요소와 연관된 jQuery 객체를 쉽

게 생성할 수 있으며, 마치 CSS 선택자를 사용하여 직접 선택한 요소처럼 사용할 수 있다.

this를 사용하여 다음코드를 작성할 수 있다.

$(this).addClass('selected');

세 개의 각 핸들러에 이 라인을 추가하면, 버튼이 클릭될 때마다 클래스가 추가된다. 반대로, 다른

버튼으로부터 클래스를 제거할 때는, 다음과 같이 jQuery의 묵시적인 반복 기능을 사용할 수 있다.

$('#switcher .button').removeClass('selected');

이 한 줄의 코드는 스타일 변환기 안의 모든 버튼으로부터 클래스를 제거하는 코드이다. 이 코

드를 사용할 때는 순서에 신경을 써야 한다.

$(document).ready(function() { $('#switcher-default').bind('click', function() { $('body').removeClass('narrow'); $('body').removeClass('large'); $('#switcher .button').removeClass('selected'); $(this).addClass('selected');

Page 69: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 43

}); $('#switcher-narrow').bind('click', function() { $('body').addClass('narrow'); $('body').removeClass('large'); $('#switcher .button').removeClass('selected'); $(this).addClass('selected'); }); $('#switcher-large').bind('click', function() { $('body').removeClass('narrow'); $('body').addClass('large'); $('#switcher .button').removeClass('selected'); $(this).addClass('selected'); });});

이제 다음 그림처럼, 버튼의 상태가 적절하게 표시되는 스타일 변환기를 볼 수 있을 것이다.

이렇게 핸들러 컨텍스트를 사용하여 코드를 일반화함으로써, 더 효율적인 코드를 만들 수 있

다. 버튼을 강조하는 코드는 모두 동일한 내용을 가지고 있기 때문에, 이것을 다음과 같이 별

도로 나누어진 핸들러로 분리할 수 있다.

$(document).ready(function() { $('#switcher-default').bind('click', function() { $('body').removeClass('narrow').removeClass('large'); });

<다음 쪽에 예제 코드 계속>

Page 70: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

44 l Learning jQuery 1.3

$('#switcher-narrow').bind('click', function() { $('body').addClass('narrow').removeClass('large'); }); $('#switcher-large').bind('click', function() { $('body').removeClass('narrow').addClass('large'); }); $('#switcher .button').bind('click', function() { $('#switcher .button').removeClass('selected'); $(this).addClass('selected'); });});

이번 최적화에서는 앞에서 언급한 jQuery의 세 가지의 장점들을 모두 사용하고 있다. 첫 번째

로, 한 번의 .bind() 호출로 동일한 핸들러를 여러 버튼과 연결하기 위해서 묵시적인 반복을

사용하였고, 두 번째로, 추가로 핸들러 대입을 할 때 기존에 할당된 핸들러가 덮어 써지지 않

도록 하면서도 click 이벤트에 할당된 두 개의 함수가 차례로 수행되도록 하기 위해 행위자

대기열을 사용하였으며, 마지막으로 클래스를 추가하고 제거할 때 사용되는 여러 라인의 코드

를 한 라인으로 표현하기 위해 jQuery의 체인 기능을 사용하고 있다.

좀 더 간소하게 만들기

우리는 리팩토링(refactoring)하여, 다시 말해, 기존 코드와 동일한 작업을 수행하면서도 좀 더 효

과적인 방식으로 수행되도록 개선하여 코드를 최적화 하였다. 좀 더 리팩토링할 내용이 있는

지 검토해 보자. 다시 한 번 각 버튼에 연결했던 행위자들의 코드를 살펴보도록 하자. 코드에

서 사용했던 .removeClass() 메서드의 인자는 선택 사항이다. 만약에 이것을 생략하게 되면

요소에 설정된 모든 클래스를 제거하겠다는 것을 의미한다. 이런 특징을 이용한다면 다음처럼

코드를 간소화할 수 있다.

$(document).ready(function() { $('#switcher-default').bind('click', function() { $('body').removeClass(); }); $('#switcher-narrow').bind('click', function() { $('body').removeClass().addClass('narrow'); }); $('#switcher-large').bind('click', function() { $('body').removeClass().addClass('large'); });

$('#switcher .button').bind('click', function() {

Page 71: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 45

$('#switcher .button').removeClass('selected'); $(this).addClass('selected'); });});

실행 순서가 약간 바뀌었음에 주의하자. .removeClass()를 먼저 수행하여, .addClass()한 내

용이 취소되지 않도록 하였다.

note! removeClass()는 모든 클래스를 제거할 수 있기 때문에 사용상의 주의가 필요하다. 다

행히, 이 코드에서는 HTML부터 모든 것을 우리가 직접 작성하고 있기 때문에 모든 클

래스들을 마음대로 제거해도 상관없지만, 재사용되는 코드(플러그인과 같은)를 작성하

는 경우라면, 요소에 추가된 다른 클래스에 손상을 주면 안되므로 클래스를 지우는 작업

에 세심한 주의가 필요하다.

각 버튼의 핸들러의 코드 중 일부가 완전히 동일하다는 것을 발견할 수 있다. 이 부분은 버튼

클릭 핸들러를 따로 만들어 정리할 수 있다.

$(document).ready(function() { $('#switcher .button').bind('click', function() { $('body').removeClass(); $('#switcher .button').removeClass('selected'); $(this).addClass('selected'); }); $('#switcher-narrow').bind('click', function() { $('body').addClass('narrow'); }); $('#switcher-large').bind('click', function() { $('body').addClass('large'); });});

여기서 일반화된 핸들러를 다른 핸들러들보다 위에 두어야 한다는 점을 기억해두자. jQuery는

항상 등록된 순서대로 이벤트 핸들러를 수행하기 때문에, 이 코드에서는 .removeClass()가

.addClass()보다 먼저 나타나야 한다.

마지막으로, .bind() 메서드를 사용하고 있는 여러 개의 코드 블록을 하나의 블록으로 줄이기

위해서 다시 한 번 이벤트 컨텍스트를 이용할 것이다. 컨텍스트 키워드 this는 jQuery 객체가

아닌 DOM 요소 객체이기 때문에, 클릭된 요소를 구별해내기 위해 순수 DOM 프로퍼티인 ID

를 사용할 수 있다. 이것을 이용해서 모든 버튼에 동일한 핸들러를 적용하고, 핸들러 내부에서

Page 72: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

46 l Learning jQuery 1.3

각 버튼에 대해 다른 동작을 수행하도록 할 수 있다.

$(document).ready(function() { $('#switcher .button').bind('click', function() { $('body').removeClass(); if (this.id == 'switcher-narrow') { $('body').addClass('narrow'); } else if (this.id == 'switcher-large') { $('body').addClass('large'); } $('#switcher .button').removeClass('selected'); $(this).addClass('selected'); });});

간소화된 이벤트

핸들러를 이벤트(간단한 click 이벤트 같은)에 연결하는 것은 흔한 작업이기 때문에, jQuery

는 보다 더 간단하고 명료한 방식의 간소화된 이벤트 메서드를 제공하고 있다. 이 메서드는

.bind()와 동일한 기능을 하면서도 짧게 기술할 수 있어서 사용이 편리하다.

예를 들어, 스타일 변환기에서 .bind() 메서드 대신 간소화된 .click() 메서드를 사용하여 다

음과 같이 작성할 수 있다.

$(document).ready(function() { $('#switcher .button').click(function() { $('body').removeClass(); if (this.id == 'switcher-narrow') { $('body').addClass('narrow'); } else if (this.id == 'switcher-large') { $('body').addClass('large'); }

$('#switcher .button').removeClass('selected'); $(this).addClass('selected'); });});

다음 간소화된 이벤트 메서드는 모두 표준 DOM 이벤트에서 온 것이다:

Page 73: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 47

blur•

change•

click•

dblclick•

error•

focus•

keydown•

keypress•

keyup•

load•

mousedown•

mousemove•

mouseout•

mouseover•

mouseup•

resize•

scroll•

select•

submit•

unload•

각각의 간소화 메서드는 대응되는 이름의 이벤트에 바인드된다.

합성이벤트

jQuery의 이벤트 처리 메서드들은 대부분 자바스크립트의 이벤트에 직접 응답할 수 있다.

jQuery에는 편의성과 브라우저 호환성을 지원하기 위해 사용자정의 핸들러들이 추가되어 있

다. 이런 메서드 중에 하나가 바로 .ready()이다. .ready()에 대해서는 앞서 자세히 설명하였

다. 그 외에 사용자정의 핸들러로 .toggle()과 .hover() 메서드가 존재하며, 이 두 메서드를

합성 이벤트 핸들러라고 하는데, 이 핸들러들이 사용자 행위 조합을 가로채어, 하나 이상의 함

수에 대해 응답하는 기능을 제공하고 있기 때문이다.

Page 74: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

48 l Learning jQuery 1.3

개선된 보이기와 숨기기 특징

합성 이벤트를 어떻게 사용하는지 알아보기 위해, 필요하지 않을 때 스타일 변환기가 보이지

않도록 숨기는 기능을 구현해보자. 숨기기 기능을 구현하는 가장 간단한 방법은 해당 요소에

접고 펼치는 기능(toggle)을 추가하는 것이다. 그럼 이제부터 레이블을 클릭하면 그 레이블만 남

기고 버튼들을 숨기며, 레이블을 다시 한 번 더 클릭하면 버튼들이 원래대로 복원되는 기능을

구현해 보자. 우선 숨김 버튼을 처리하기 위해 클래스를 하나 더 준비하자.

.hidden { display: none;}

이 기능을 구현하기 위해 현재 버튼의 상태를 변수에 저장하고, 매번 레이블이 클릭될 때마다

버튼에 hidden 클래스가 추가되었는지 또는 제거되었는지를 검사하는 방법을 사용할 수 있을

것이다. 또는 레이블이 클릭될 때마다 버튼에 클래스가 있는지 없는지 직접 검사하여 무엇을

할지 결정하게 할 수도 있을 것이다. jQuery에서는 그것을 대신 처리해 줄 수 있는 .toggle()

메서드를 제공하고 있다.

note! jQuery에 두 개의 .toggle() 메서드가 정의되어 있다. 같은 이름의 효과 관련 메서드

(이 두 메서드는 서로 다른 인자 타입으로 구분)에 대해서는 http://docs.jquery.com/

Effects/toggle을 참조하라

.toggle() 메서드는 두 개의 인자를 갖는다. 이 두 인자들은 모두 함수다. .toggle()이 적용된

요소를 처음 클릭하면 첫 번째 함수가 실행되고, 두 번째 클릭하면 두 번째 함수가 실행되도록

되어 있다. 그 후에도 이 두 함수들은 클릭에 의해서 교대로 계속 실행된다. .toggle()을 사용

하면, 접기/펼치기 기능을 가진 스타일 변환기를 손쉽게 구현할 수 있다.

$(document).ready(function() { $('#switcher h3').toggle(function() { $('#switcher .button').addClass('hidden'); }, function() { $('#switcher .button').removeClass('hidden'); });});

다음 화면에서 보는 것처럼 첫 번째 클릭 이후에 모든 버튼이 숨겨진 것을 알 수 있다.

Page 75: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 49

그리고 다음 클릭에서는 다음 화면에서 보는 것처럼 버튼들이 다시 모습을 보여주고 있다.

이번에도 다시 한 번 묵시적인 반복을 사용하여 코드를 작성한다. 모든 버튼들을 한 번에 숨기

기 위해, 이 버튼들을 둘러싸는 요소를 새로 만들지는 않는다.

이런 경우를 위해, jQuery는 우리가 작성해야 할 코드를 줄여줄 수 있는 방법을 제공하고 있다.

클래스를 추가하거나 제거하기 전에 클래스의 존재 유무를 자동으로 검사해야 할 경우에는

.toggleClass() 메서드를 활용할 수 있다.

$(document).ready(function() { $('#switcher h3').click(function() { $('#switcher .button').toggleClass('hidden'); });});

이 예제에서 볼 수 있듯이 .toggleClass()를 사용하는 것은 클래스를 추가/제거하는 방법보

다도 더 멋진 해결 방법이 될 수 있다. 또 번갈아 수행될 수 있는 다른 작업에서도 다양하게

.toggle()을 활용할 수 있을 것이다.

클릭 가능한 아이템들 강조하기

페이지 내에서 클릭이 가능한 요소를 구별하여 보여주기 위해, 버튼이 동작 가능함을 표현하

는 인터페이스를 만들었다. 이와 마찬가지로, 마우스로 상호작용이 가능함을 분명하게 보여주

기 위해 버튼에(실제로는 단지 <div> 요소) 롤오버 상태2를 부여할 수 있다.

2  (옮긴이) 마우스가 특정 요소 위에 위치했을 때, 요소의 변화를 주어 선택 가능한 항목을 강조하는 기법을 말한다. 마우스오버라고도 하며, 흔히 자바스크립트를 사용하여 스타일이나 이미지를 대체하는 방법으로 구현한다.

Page 76: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

50 l Learning jQuery 1.3

#switcher .hover { cursor: pointer; background-color: #afa;}

CSS 명세는 의사 클래스(pseudo-class)로 :hover를 포함하고 있는데, 이것은 사용자의 마우스 커

서가 요소의 영역 안에 들어왔을 때, 해당 요소의 모양을 변경할 수 있게 해준다. 인터넷 익스

플로러 6에서는 이러한 기능을 link 요소에만 적용할 수 있다. 이 때문에, 브라우저 호환성을

고려하여 작성해야 하는 경우, 다른 요소에는 이러한 기능을 사용할 수 없다. jQuery에서는 이

런 문제를 해결하기 위해서 요소에 마우스 커서가 들어갈 때나 나올 때를 모두 표현할 수 있는

독자적인 방식을 제공하고 있다.

.toggle() 메서드와 마찬가지로 .hover() 메서드 역시 두 개의 함수를 인자로 가질 수 있다.

.hover()의 경우, 선택된 요소에 마우스 커서가 들어가면 첫 번째 함수가 실행되고, 커서가 떠

날 때 두 번째 함수가 실행된다. 이 기능을 활용하면, 롤오버 효과를 주기 위해 버튼에 적용된

클래스를 다음과 같이 간단히 수정할 수 있다.

$(document).ready(function() { $('#switcher .button').hover(function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); });});

코드를 줄이고 간결하게 만들기 위해 다시 한 번 묵시적인 반복과 이벤트 컨텍스트를 사용하

고 있다. 이제 마우스 커서가 버튼 위로 이동할 때, 클래스가 적용된 모습을 다음 그림에서 볼

수 있을 것이다.

Page 77: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 51

.hover() 메서드를 사용하면 자바스크립트에서 이벤트 전파(event propagation)때문에 발생하는

골치 아픈 문제들도 피할 수 있다. 이해를 돕기 위해, 자바스크립트가 주어진 이벤트를 처리할

요소를 어떻게 결정하는지 살펴볼 필요가 있다.

이벤트의여행

페이지에서 이벤트가 발생하면, DOM 전체 계층에 있는 모든 요소들이 이벤트를 처리할 수 있

는 기회를 갖게 된다. 만일 페이지가 다음과 같다고 가정하자.

<div class="foo"> <span class="bar"> <a href="http://www.example.com/"> The quick brown fox jumps over the lazy dog. </a> </span> <p> How razorback-jumping frogs can level six piqued gymnasts! </p></div>

다음 그림은 코드에서 중첩된 요소들의 집합을 시각적으로 나타내고 있다.

<div>

<span>

<a> <p>

어떠한 이벤트에 대해서건, 논리적으로 여러 요소들이 반응에 대한 책임을 가질 수 있다.이 페

이지에서 앵커(<a>)가 클릭되면, <div>, <span>, <a>는 모두 클릭 이벤트에 응답할 수 있는 기

회를 가지게 된다. 그 이유는, 세 개가 모두 동일한 마우스 좌표상에 있기 때문이다. 반면에

<p> 요소는 전혀 이러한 상호작용의 대상이 되지 않는다.

여러 요소가 한 번의 클릭에 모두 반응하도록 하는 전략을 이벤트 캡처링(event capturing)이라고

한다. 이벤트 캡처링에서, 모든 것을 감싸고 있는 최상위의 요소에게 이벤트가 처음으로 주어

지고, 그 후에 연속해서 하위 요소로 전달된다. 이 예제에서는 가장 먼저 <div>가 이벤트를 받

Page 78: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

52 l Learning jQuery 1.3

게 되고, <span>이 그 뒤를 이어서 받고, 마지막으로 <a>가 받게 된다.

<div>

<span>

<a> <p>

Capturing

note! 기술적으로 봤을 때, 브라우저 자체의 이벤트 캡처링 기능은 자손 요소들에서 발생하는

이벤트들을 감지하기 위해 리스너를 등록하는 방식으로 구현되었을 것이다. 우리가 브

라우저 구현 자체에 관심을 가지고 있는 것은 아니므로, 브라우저 구현에 대한 설명은

이 정도로 충분하다.

반대 방향으로 이벤트가 전파되는 것을 이벤트 버블링(event bubbling)이라고 한다. 이벤트는 가

장 낮은 자식 요소에 처음으로 전달되고, 해당 요소가 반응한 후에, 그 이벤트는 그 부모 요소

로 전파된다. 이 예제에서는 <a> 요소가 이벤트를 첫 번째로 처리하고, <span>과 <div>가 차례

대로 처리하게 된다.

<div>

<span>

<a> <p>

Bubbling

당연한 이야기이지만, 브라우저 개발자들은 브라우저를 개발하면서 서로 다른 이벤트 전파 모

델을 구현하였다. 그런데, 나중에 만들어진 DOM 표준은 결국 이 두 가지 전략이 모두 사용되

어야 한다고 지정하고 있다. 캡처되는 이벤트는 부모에서 특정 자식 요소로 이동하고, 버블되

는 이벤트는 DOM 계층의 최상위로 거슬러 올라간다. 이벤트 핸들러는 두 가지 과정 모두에

등록할 수 있다.

아직까지 모든 브라우저들이 이 새로운 표준을 따르도록 업데이트되지는 않은 상태이며,일반

적으로 캡처링을 사용하려면 반드시 명시적으로 지정해 주어야 한다. jQuery는 브라우저 호환

Page 79: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 53

의 일관성을 제공하기 위해 버블링 모델을 지원하는 이벤트 핸들러들을 항상 사용하고 있다.

그 결과, 이벤트에 첫 번째로 응답하는 것이 항상 선택된 최하위 특정 자식 요소라는 것을 보

장받을 수 있게 된다.

이벤트 버블링의 부작용

이벤트 버블링은 기대하지 않은 결과를 낳을 수 있는데, 특히 mouseover나 mouseout에 대해

엉뚱한 요소가 응답을 하는 경우 더욱 그렇다. 예제에서 mouseout 이벤트 핸들러가 <div> 태

그에 연결되었다고 가정해보자. 사용자의 마우스 커서가 <div> 위에 존재한다면 mouseout 핸

들러가 예상한 대로 잘 실행될 것이다. 왜냐하면 <div>는 계층 구조상 가장 높은 위치에 있기

때문이며 다른 요소들에게 이 이벤트가 전달되지 않을 것이기 때문이다. 이와 반대로, 커서가

<a> 요소에 존재하게 된다면 mouseout 이벤트는 <a> 태그로 보내진다. 이 이벤트는 버블업

(bubble up) 되어 상위에 있는 <span> 태그로도 전달될 것이고, 그 후에 <div> 태그로도 전달되

어 <div>가 가지고 있는 핸들러가 실행될 것이다. 이러한 버블링은 원했던 것이 아니다. 스타

일 변환기 예제에서 버튼의 경우, 이러한 버블링으로 인해 롤오버를 강조했던 스타일이 조기

에 해제될 수 있기 때문이다.

.hover() 메서드는 이러한 버블링 문제를 고려하고 있으며, 이벤트들을 추가할 때 이 메서드

를 사용하면 mouseover나 mouseout 이벤트가 엉뚱한 요소에 전달돼서 발생하는 문제들을 없

앨 수 있다. 따라서, 개별적으로 마우스 이벤트들을 직접 연결해서 사용하는 것보다 .hover()

를 사용하는 것이 더욱 좋다고 할 수 있다.

note! 만일 마우스가 요소에 들어오거나 나갈 때, 혹은 두 경우 모두 jQuery의 mouseenter와

mouseleave 이벤트를 바인드할 수 있다. 이 메서드 들은 모두 버블링 문제를 해결하고 있

다. 이 이벤트들은 보통 쌍으로 사용되므로 일반적으로 .hover()를 쓰는 것이 더 낫다.

mouseout을 사용한 시나리오는 이벤트의 전파 범위를 제한해야 할 필요성을 보여주고 있다.

이런 특수한 상황을 .hover()가 해결해 줄 수 있지만, 그런 상황 이외에도 이벤트를 공간적으

로 제한(다른 요소로 전달되는 것을 막는 것)하거나 혹은 시간적으로 제한(특정 시점에서 이벤

트를 막는 것)해야 할 경우도 생길 수 있다.

Page 80: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

54 l Learning jQuery 1.3

진행경로수정하기:이벤트객체

앞에서 이벤트 버블링이 문제를 발생시킬 수 있다는 것을 알게 되었다. .hover()로 해결 할 수

없는 상황을 연출하기 위해 접기 기능과 관련한 코드를 수정할 것이다.

그리고 스타일 변환기의 접기/펼치기 기능을 수행하기 위해 클릭 영역을 확장하는 경우를 생

각해 본다. 이것을 구현하는 방법 중의 하나는 이벤트 핸들러를 레이블 <h3>로부터 <div> 요소

로 옮기는 것이다.

$(document).ready(function() { $('#switcher').click(function() { $('#switcher .button').toggleClass('hidden'); });});

이벤트 핸들러를 옮기고 나면, <div> 영역 전체가 스타일 변환기의 토글 영역이 되어버린다.

이럴 경우, 스타일 변환기를 사용하여 도큐먼트 스타일을 변경하기 위해서 버튼을 클릭하게

되면 도큐먼트 스타일이 변경되자마자 버튼들이 사라져버린다. 이것 또한 이벤트 버블링 때문

에 발생하는 문제다. 이벤트는 버튼 핸들러에 의해 올바르게 처리되지만, 이벤트 버블링에 의

해서 버튼들을 숨기는 핸들러를 가진 <div id="switcher">를 만날 때까지 DOM 트리를 거

슬러 올라가며, 새로운 핸들러가 활성화 되고 버튼은 감추어 진다.

이 문제를 해결하려면 이벤트 객체(event object)에 접근할 수 있어야 한다. 자바스크립트의 이벤

트 객체는 이벤트가 발생한 위치의 요소 객체를 포함하고 있다. 이 요소 객체를 활용하면, 이

벤트가 발생한 마우스 위치와 같은 이벤트 정보를 얻을 수 있을 뿐만 아니라, DOM을 통해 전

달되는 이벤트 진행에 영향을 줄 수 있는 메서드들도 이용할 수 있다.

핸들러에서 이벤트 객체를 사용하려면, 기존 함수에 매개 변수 하나만 추가하면 된다.

$(document).ready(function() { $('#switcher').click(function(event) { $('#switcher .button').toggleClass('hidden'); });});

이벤트 대상

이제 event 변수 하나를 추가함으로써 핸들러에서 이벤트 객체를 사용할 수 있게 되었다.

Page 81: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 55

event.target 프로퍼티를 사용하여 이벤트의 영향을 제어하는 데 도움을 받을 수 있다. 이 프

로퍼티는 DOM API의 한 부분이지만, 모든 브라우저에서 구현하고 있지는 않다. jQuery는 모

든 브라우저에서 이 프로퍼티를 사용할 수 있도록 이벤트 객체를 확장하고 있다. .target을 사

용함으로써 DOM에서는 어느 요소가 이벤트를 처음으로 받은 요소인지를(이 click 이벤트 경

우 클릭된 실제 아이템) 알 수 있다. 이벤트를 처리하고 있는 DOM 요소를 this라는 키워드로

도 사용할 수 있다는 것을 기억하고 있다면, 이제 다음과 같은 코드를 작성할 수 있을 것이다.

$(document).ready(function() { $('#switcher').click(function(event) { if (event.target == this) { $('#switcher .button').toggleClass('hidden'); } });});

이 코드는 클릭된 아이템이 하위 요소 중에 하나가 아니라 <div id="switcher">라는 것을 보

장받을 수 있도록 작성되어 있다. 이제 버튼을 클릭해도 스타일 변환기가 이벤트를 처리한 후

바로 사라지는 일은 없을 것이다. 하지만, 레이블 <h3>을 클릭하면 아무런 동작도 하지 않는

다. 왜냐하면, 이것 역시 하위 요소이므로, 조건문으로 인한 영향을 받았기 때문이다. 이런 확

인을 수행하는 대신 버튼의 행위 코드를 수정해서 동일한 기능을 구현할 수도 있다.

이벤트 전파 멈추게 하기

이벤트 객체는 버블링 과정을 중단할 수 있도록 하는 .stopPropagation() 메서드를 제공한다.

.target 속성처럼, 이 메서드 또한 순수 자바스크립트의 기능이긴 하지만 모든 브라우저에서

사용할 수 있는 것은 아니다. 하지만, jQuery를 사용해서 이벤트 핸들러들을 등록하여 사용하기

만 하면 모든 브라우저에서 완전한 호환성을 갖도록 할 수 있다.

바로 위에서 사용했던 조건 검사 event.target == this를 제거하고, 버튼의 클릭 핸들러에 몇

가지 코드를 추가할 것이다.

$(document).ready(function() { $('#switcher .button').click(function(event) { $('body').removeClass(); if (this.id == 'switcher-narrow') { $('body').addClass('narrow'); } else if (this.id == 'switcher-large') {

<다음 쪽에 예제 코드 계속>

Page 82: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

56 l Learning jQuery 1.3

$('body').addClass('large'); } $('#switcher .button').removeClass('selected'); $(this).addClass('selected'); event.stopPropagation(); });});

이벤트 객체에 접근하기 위해, 이전 코드와 마찬가지로 클릭 핸들러 함수에 인자를 포함시켜

이벤트 객체에 접근할 수 있도록 한다. 그런 다음, 다른 DOM 요소가 이벤트에 응답하지 못하

도록 event.stopPropagation() 메서드만 호출하면 된다. 이제부터 클릭 이벤트는 버튼에 의

해서 처리되며, 버튼 외에 그 어떤 다른 요소로도 전파되지 않게 된다. 이제 스타일 변환기의

다른 곳을 클릭하여 버튼들이 올바르게 접히고 펼쳐지는 것을 확인할 수 있을 것이다.

기본 동작들

만일 스타일 변환기를 구현할 때 일반 <div>가 아닌 링크 요소 <a>를 사용하여 click 이벤트

핸들러를 등록하였다면, 또 다른 문제를 만날 수도 있다. 사용자가 링크를 클릭했을 때, 브라

우저가 새로운 페이지를 로드하게 만드는 것이 링크가 가지고 있는 기본 동작(default action)이

다. 하지만 이러한 행위는 우리가 지금까지 이야기해왔던 버튼이 가지고 있어야 할 행위는 아

니다. 이와 유사하게, 사용자가 폼에 데이터를 입력을 하다가 엔터키를 누르면, Submit 이벤

트가 발생하여 폼 데이터가 전송이 되는데, 이러한 문제도 기본 동작으로 인해 생기는 문제라고

할 수 있다.

만일, 기본 동작이 원치 않는 것일 경우, 이벤트에 대해 .stopPropagation()를 호출하는 것은

별 소용이 없다. 기본 동작들은 일반적인 이벤트 전파 단계에서 발생하지 않는다.

.stopPropagation() 대신에 .preventDefault() 메서드를 호출하여 기본 동작이 시작되기 전

에 이벤트를 중단할 수 있다.

note! 이벤트를 사용하는 환경에서 몇 가지 조건을 검사한 후에 .preventDefault() 메서드

를 호출하는 것이 유용한 경우가 종종 있다. 예를 들어, 폼 전송을 할 때 필수 입력 필드

에 필드의 값이 입력되었는지를 검사하고 나서 입력되지 않은 경우 기본 동작을 막고 싶

을 때가 있다. 8장에서 이것에 대한 내용을 좀 더 상세하게 살펴볼 것이다.

Page 83: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 57

이벤트가 전파되는 것과 기본 동작이 실행되는 것은 서로 독립적인 메커니즘이다. 즉, 한쪽이

동작하는 동안, 다른 한쪽의 동작을 멈출게 할 수 있다. 만일 둘 모두를 중지시키고 싶다면, 우

리가 작성하는 이벤트 핸들러에서 false를 반환하면 된다. 이 방법은 .stopPropagation()과

.preventDefault() 모두를 호출하는 것과 동일한 효과를 갖는다.

이벤트 위임

이벤트 버블링이 항상 장애가 되는 것은 아니며, 이 기능을 활용하여 상당한 이득을 얻을 수

있다. 가장 큰 이점은 바로 이벤트 위임(event delegation)이라 불리는 기법이다. 이벤트 위임을 활

용하여, 하나의 요소가 여러 가지 다른 작업을 수행하도록 이벤트 핸들러를 추가할 수 있다.

note! jQuery 1.3에 두 개의 메서드 .live()와 .die()가 새롭게 소개되었다. 이 메서드들은

.bind() 와 .unbind()와 동일한 기능을 수행하지만, 이벤트 위임을 함으로써, 3장

에서 설명하는 장점들을 누릴 수 있도록 해준다. 이 두 메서드에 대한 자세한 내용은

http://docs.jquery.com/Events/live 에서 찾아 볼 수 있다.

예제에서 우리는 세 개의 <div class="button"> 요소에 click 핸들러를 추가하였다. 하지

만, 여러 개라면 어떻게 해야 할까? 이런 필요는 생각보다 많이 발생한다. 예를 들어, 정보를

담은 커다란 테이블이 있고, 각각의 행이 click 핸들러를 필요로 하는 항목을 포함하고 있다

고 가정해 보자. 묵시적인 순환을 통해 click 핸들러를 손쉽게 할당할 수 있을 것이다. 하지만,

jQuery에 의해 내부적으로 루프를 돌게 되므로 성능이 매우 나빠지게 되며, 모든 핸들러를 관

리하기 위해 메모리를 많이 사용하게 된다.

이렇게 하는 대신, DOM의 조상 요소에 단 한 개의 click 핸들러만 할당할 수 있다. 이벤트 버

블링이 일어나므로, 이벤트는 중단 없이 조상 요소로 전달되며, 여기서 우리가 하고자 하는 작

업을 수행하도록 할 수 있다.

예제를 통해, 우리의 스타일 변환기(항목의 개수를 상관없다)에 적용해 보자. 앞서 살펴본 것

처럼,어느 요소에 마우스 클릭이 발생했는지 알아내기 위해 event.target 프로퍼티를 사용할

수 있다.

$(document).ready(function() { $('#switcher').click(function(event) { if ($(event.target).is('.button')) { $('body').removeClass(); if (event.target.id == 'switcher-narrow') {

<다음 쪽에 예제 코드 계속>

Page 84: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

58 l Learning jQuery 1.3

$('body').addClass('narrow'); } else if (event.target.id == 'switcher-large') { $('body').addClass('large'); } $('#switcher .button').removeClass('selected'); $(event.target).addClass('selected'); event.stopPropagation(); } });});

여기서 새로운 메서드 .is()를 사용하고 있다. 이 메서드는 지정한 선택자 표현식(selector

expression)에 대응하는 jQuery 객체가 있는지를 검사한다. 만일 선택자에 해당하는 요소가 하나

라도 있으면, .is()는 참(true)를 반환할 것이다. 예제에서, $(event.target).is('.button')는

클릭된 요소에 button 클래스가 할당되어 있는지 여부를 검사한다. 만일 이 검사가 참이라면,

더 진행하기 전에 한가지 중요한 작업을 수행한다. 현재, this 키워드는 <div id="switcher">

를 가리킨다. 따라서, 클릭된 버튼을 찾으려 할 때 마다, event.target를 가지고 this를 참조

하기만 하면 된다.

note! 요소에 클래스가 할당되어 있는지를 검사하기 위해, 간편하게 .hasClass() 메서드를

사용할 수 있다. 하지만, .is() 메서드가 좀 더 유연하며, 선택자 표현식을 사용하여 검

사할 수 있다는 장점이 있다 .

그러나, 이 코드에는 의도하지 않은 부작용이 숨어 있다. 버튼을 클릭하면, .stopPropagation()를

호출하기 전에 스타일 변환기가 접힌다. 스타일 변환기는 보이게 하는 토글 기능을 수행하는 핸들러

가 버튼에도 똑같이 바인딩 되어 있기 때문에, 이벤트 버블링 중단해도 토글이 중단되지 않는

다. 이 문제를 해결하기 위해, .stopPropagation() 호출을 제거하고 .is() 검사를 추가한다.

$(document).ready(function() { $('#switcher').click(function(event) { if (!$(event.target).is('.button')) { $('#switcher .button').toggleClass('hidden'); } });});

$(document).ready(function() { $('#switcher').click(function(event) { if ($(event.target).is('.button')) {

Page 85: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 59

$('body').removeClass(); if (event.target.id == 'switcher-narrow') { $('body').addClass('narrow'); } else if (event.target.id == 'switcher-large') { $('body').addClass('large'); } $('#switcher .button').removeClass('selected'); $(event.target).addClass('selected'); } });});

이 예제는 규모에 비해 매우 복잡해 보이지만, 요소들에 할당되는 이벤트 핸들러가 증가하는

경우, 이벤트 위임은 매우 적절한 기법이다.

note! 나중에 상세하게 살펴보겠지만, 이벤트 위임은 DOM을 조작 메서드(5장)나 AJAX 루틴

(6장)을 통해 새로운 요소를 동적으로 추가하는 경우에도 매우 유용하게 사용된다.

이벤트핸들러제거하기

등록했던 이벤트 핸들러의 작업이 완료되면 더 이상 완료된 동작을 실행할 필요가 없게 되는

경우가 있다. 일반적으로 이런 상황에서는 제어문을 사용하여 핸들러가 더 이상 실행되지 않

도록 제어할 수도 있지만, 핸들러를 완전히 제거(unbind)하는 것이 더 바람직하다.

간단한 예로써, 페이지가 평상시 스타일이 아닌 경우, 버튼을 클릭해도 스타일 변환기가 접히

지 않고 펼쳐진 상태 그대로 남아있기를 원한다고 가정하자. 즉, Narrow Column 혹은 Large

Print 버튼이 선택된 상태에서, 스타일 변환기의 배경을 클릭하면 아무것도 하지 않는다. 이 문

제에 대한 해결 방법은 스타일 변환기 버튼이 클릭될 때 핸들러를 제거하는 .unbind() 메서

드를 사용하면 간단하게 해결할 수 있다. 기본 스타일 변환기 버튼이 아닌 버튼이 클릭되면,

.unbind() 메서드를 사용하여 접기를 수행하는 핸들러를 제거한다.

$(document).ready(function() { $('#switcher').click(function(event) { if (!$(event.target).is('.button')) { $('#switcher .button').toggleClass('hidden'); } });

<다음 쪽에 예제 코드 계속>

Page 86: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

60 l Learning jQuery 1.3

$('#switcher-narrow, #switcher-large').click(function() { $('#switcher').unbind('click'); });});

이제, Narrow Column 버튼 등을 클릭하면, <div>의 click 핸들러가 제거되고, 박스의 배경을

클릭했을 때 접히지 않는다. 하지만, 버튼은 더 이상 작동하지 않는다! 우리가 이벤트 위임을

사용하여 버튼 처리 코드를 다시 작성했기 때문에, 스타일 변환기 <div>의 click 이벤트가 할

당되어있기 때문이다. 이것은 우리가 $('#switcher').unbind('click')를 호출했을 때, 행위가

모두 제거되었음을 의미한다.

이벤트 네임스페이스

이미 등록한 click 핸들러를 제거하지 않도록 하기 위해, .unbind() 호출을 좀 더 상세하게 살

펴볼 필요가 있다. 이 문제를 해결하는 방법 중의 하나는 이벤트 네임스페이스(event namespace)

를 사용하는 것이다. 이벤트를 바인딩할 때, 추가적인 정보를 주어 나중에 식별할 수 이도록

하는 것이다. 네임스페이스를 사용하려면 단축 메서드를 사용하지 말고 .bind()를 사용해야

한다.

.bind()에 지정하는 첫번째 인자는 우리가 식별하고자 하는 자바스크립트 이벤트의 이름이다.

우리는 여기서 이벤트를 세분하여 구분하기 위한 특별한 문법을 사용해 볼 것이다.

$(document).ready(function() { $('#switcher').bind('click.collapse', function(event) { if (!$(event.target).is('.button')) { $('#switcher .button').toggleClass('hidden'); } }); $('#switcher-narrow, #switcher-large').click(function() { $('#switcher').unbind('click.collapse'); });});

.collapse 접미사는 이벤트 처리 시스템과는 무관하다: 코드에 쓰여진 대로 click 이벤트는

.bind('click')에 의해 처리된다. 그러나, 네임스페이스 추가가 의미하는 것은, 버튼에 할당된

click 핸들러에 영향을 주지 않고도 특정 핸들러만 해지할 수 있다는 것이다.

Page 87: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 61

note! 잠시 살펴본 바와 같이 .unbind()을 좀 더 상세하게 지정할 수 있는 방법들이 더 많이

있다. 이벤트 네임스페이스는 매우 유용한 도구이며, 11장에서 보다 편리하게 사용할 수

있도록 만들어진 플러그인에 대해 살펴볼 것이다.

이벤트 다시 바인딩하기

이제, Narrow Column 혹은 Large Print 버튼을 클릭하면 스타일 변환기가 접히는 기능이 비

활성화 된다. 하지만, Default 버튼을 누르면 이 기능을 복구하고 싶다. 이렇게 하기 위해,

Default 버튼이 눌렸을 때 핸들러를 다시 바인드할 필요가 생긴다.

우선, 핸들러를 나중에 다시 사용할 수 있도록 핸들러 함수에 이름을 부여한다.

$(document).ready(function() { var toggleStyleSwitcher = function(event) { if (!$(event.target).is('.button')) { $('#switcher .button').toggleClass('hidden'); } };

$('#switcher').bind('click.collapse', toggleStyleSwitcher);});

사뭇 다른 문법을 사용하여 함수를 정의하고 있다는 점을 눈여겨보자. function 키워드를 사

용하여 함수를 정의하지 않고, 지역변수에 익명함수 정의를 할당하고 있다. 이런 스타일로 코

드를 제작하면, 이벤트 핸들러와 다른 함수의 정의가 서로 거의 유사한 형태를 가지게 되며,

두 문법 표현은 기능적으로 동일하다.

또한, 함수 참조를 두 번째 인자로 하여 .bind()를 호출한다. 명명된 함수를 사용할 때 매우 중

요한 사항으로 함수 뒤에 오는 괄호를 빼야 한다는 점을 기억해 두자. 괄호를 쓰면 함수를 참

조하는 것이 아니라 호출하게 된다.

이제 함수에 이름을 부여했기 때문에, 함수를 반복하여 정의하지 않고도, 필요한 때에 언제든

지 바인딩할 수 있게 되었다.

$(document).ready(function() { var toggleStyleSwitcher = function(event) { if (!$(event.target).is('.button')) { $('#switcher .button').toggleClass('hidden'); } };

<다음 쪽에 예제 코드 계속>

Page 88: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

62 l Learning jQuery 1.3

$('#switcher').bind('click.collapse', toggleStyleSwitcher); $('#switcher-narrow, #switcher-large').click(function() { $('#switcher').unbind('click.collapse'); }); $('#switcher-default').click(function() { $('#switcher') .bind('click.collapse', toggleStyleSwitcher); });});

이제, 토글 행위자는 도큐먼트가 로드될 때 연결되었다가, Narrow Column 또는 Large Print

버튼이 클릭되면 연결이 해제되고, Normal 버튼이 다시 클릭되면 행위를 다시 연결한다.

아직 코드의 잠재적인 문제점은 언급하지 않았다. 이전 jQuery 코드에서 핸들러가 이벤트와 연

결될 때를 돌이켜 생각해 보면, 이전의 핸들러들이 결국에는 그대로 남아있다는 것을 알 수 있

다. Normal을 여러 번 연속으로 클릭했을 때 여러 개의 toggleStyleSwitcher 핸들러 사본이

바인드되어 <div>를 클릭했을 때 이상하게 동작하는 것처럼 보일 수 있다. 실제로, 우리가 예제

에서 익명 함수를 사용했다면, 바로 그런 경우가 되었을 것이다. 하지만 이 코드에서는 함수에 이

름을 부여하고 같은 함수를 다시 사용하고 있기 때문에 행위자는 단 한 번만 연결될 수 있었다.

명명된 함수를 사용하는 또 다른 이득은 바로 더 이상 네임스페이스를 사용할 필요가 없다는

점이다. .unbind() 메서드에 두 번째 인자를 지정할 수 있는데, 이 경우 지정한 핸들러의 바인

드를 해지한다.

$(document).ready(function() { var toggleStyleSwitcher = function(event) { if (!$(event.target).is('.button')) { $('#switcher .button').toggleClass('hidden'); } };

$('#switcher').click(toggleStyleSwitcher); $('#switcher-narrow, #switcher-large').click(function() { $('#switcher').unbind('click', toggleStyleSwitcher); }); $('#switcher-default').click(function() { $('#switcher').click(toggleStyleSwitcher); });});

Page 89: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 63

이벤트 핸들러가 한 번만 호출된 후에 바로 해제되기를 원하는 상황에서 사용할 수 있는 간소

화된 메서드가 있다. 이 메서드는 .one()이며, 다음 코드처럼 사용할 수 있다.

$(document).ready(function() { $('#switcher').one('click', toggleStyleSwitcher);});

이것은 토글 동작이 단 한 번만 실행되고 다시는 실행되지 않도록 만든다.

사용자상호작용흉내내기

때때로, 실제 이벤트가 발생하지 않았지만 이벤트에 연결했던 코드를 실행하도록 하는 것

이 훨씬 편할 때가 있다. 예를 들어, 페이지가 로드될 때 스타일 변환기가 접힌 상태에서 시

작되기를 원한다고 가정하자. 이것을 처리하기 위한 방법으로는, 페이지가 로드될 때 스타

일 변환기 안에 있는 버튼을 숨기는 코드를 따로 작성하여 실행하도록 할 수도 있고, 혹은

$(document).ready() 핸들러로부터 .hide() 메서드를 호출하게 할 수도 있다. 그 외에 다른

방법은 앞서 토글을 위해서 사용해왔던 스타일 변환기의 click을 그대로 흉내 내는 것이다.

.trigger() 메서드가 바로 이런 처리를 가능하게 만들어준다.

$(document).ready(function() { $('#switcher').trigger('click');});

이제는 페이지가 로드될 때 선택기는 접혀 있는 상태로 표시되며, 다음 그림과 같이 마치 클릭

된 적이 있었던 것처럼 보여진다. 사용자가 자바스크립트를 활성화 하지 않아도 되므로, 이 기

능은 단계적 기능축소(graceful degradation)를 구현하는 합리적인 방법이 될 수 있다.

Page 90: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

64 l Learning jQuery 1.3

.bind()처럼 .trigger() 메서드도 .click() 메서드를 사용하여 간소화된 방법을 제공한다.

.click() 메서드에 인자를 지정하지 않는 경우, 이벤트와 행위를 연결하는 것이 아니라, 이벤

트에 해당하는 행위를 발생시키게 된다.

$(document).ready(function() { $('#switcher').click();});

키보드 이벤트

다른 예제로, 스타일 변환기에 바로가기 키보드 기능을 구현한다. 화면에 표시된 스타일의 첫

번째 글자를 누르면, 해당 버튼이 눌린 것처럼 동작하게 만들 것이다. 이 기능을 구현하기 위

해, 마우스 이벤트와는 조금 다른 키보드 이벤트에 대해 살펴보자.

키보드 이벤트에는 두 가지 종류가 있다. 키보드에 직접 반응하는 것(keyup와 keydown)과 텍

스트 입력에 반응하는 것(keypress)이 있다. 한 개의 문자 입력은 몇 개의 키 입력에 대응되기

도 한다. 예를 들어, Shift 키와 X 키를 함께 눌러 대문자 X가 입력된다. 브라우저 마다 차이가

존재하지만, 확실하고 안전한 규칙은 - 사용자가 어떤 키를 눌렀는지 알고 싶다면 keyup 혹은

keydown 이벤트를 사용하고, 어떤 글자가 입력되었는지 알고 싶다면 keypress 이벤트를 사용

하라는 것이다. 앞서 언급한 기능을 구현하기 위해, 우리는 D, N, L 문자 입력과 keyup을 사용

할 것이다.

그런 다음, 이 이벤트를 어느 요소에서 감시해야 할지를 결정한다. 이것은 마우스 이벤트의 경

우보다 덜 명확하다. 마우스는 마우스 커서가 있는 위치가 명확하게 보이기 때문이다. 키보드

이벤트의 대상은 포커스(focus)를 가진 요소가 된다. 마우스를 클릭하거나 탭 키를 누르는 등의

방법으로 다른 요소로 포커스를 이동할 수 있다. 모든 요소가 포커스를 가질 수 있는 것은 아

니며, 폼 필드, 링크 그리고, .tabIndex 프로퍼티를 가진 요소들이 포커스을 가지는 유력한 후

보들이 된다.

사실 이 예제에서 어떤 요소가 포커스를 가지는지 크게 신경 쓸 필요는 없다. 사용자가 키 중

의 하나를 눌렀을 때 스타일 변환기가 잘 동작하면 된다. 이벤트 버블링은 매우 유용하다. 우

리는 단지 document 요소에 keyup 이벤트를 바인드 하기만 하면, 모든 키 이벤트들이 버블업

되어 전달될 것이기 때문이다.

마지막으로, keyup 핸들러가 불렸을 때 어떤 키가 눌렸는지 알아야 할 필요가 있다. 이벤트 객

Page 91: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 65

체를 조사하면 된다. 이벤트 객체의 .keyCode 프로퍼티는 눌려진 키에 대한 식별 값과 알파벳

키 값을 가지고 있으며, 이 값은 대문자 ASCII 값이다. 따라서, 우리는 이 값에 따라 버튼 클릭

을 발생하도록 분기하도록 하면 된다.

$(document).ready(function() { $(document).keyup(function(event) { switch (String.fromCharCode(event.keyCode)) { case 'D': $('#switcher-default').click(); break; case 'N': $('#switcher-narrow').click(); break; case 'L': $('#switcher-large').click(); break; } });});

키가 눌려지면, 마우스로 버튼을 클릭한 것과 동일하게 동작한다. 파이어폭스의 다음 찾기와

같은 기능에 의해 방해를 받지 않고 수행 된다.

클릭을 흉내내는 다른 방법으로 .trigger()를 사용할 수 있다. 코드를 다듬어 여러 개의 핸들

러(여기서는 click 와 keyup)에서 호출되는 하나의 함수를 어떻게 만드는지 살펴보자. 여기서 이

런 작업이 크게 필요한 것은 아니지만, 코드의 중복을 없애는 기법으로 유용하게 사용할 수 있다.

$(document).ready(function() { // Enable hover effect on the style switcher buttons. $('#switcher .button').hover(function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); });

// Allow the style switcher to expand and collapse. var toggleStyleSwitcher = function(event) { if (!$(event.target).is('.button')) { $('#switcher .button').toggleClass('hidden'); } }; $('#switcher').click(toggleStyleSwitcher); // Simulate a click so we start in a collaped state. $('#switcher').click();

<다음 쪽에 예제 코드 계속>

Page 92: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

66 l Learning jQuery 1.3

// The setBodyClass() function changes the page style. // The style switcher state is also updated. var setBodyClass = function(className) { $('body').removeClass(); $('body').addClass(className); $('#switcher .button').removeClass('selected'); $('#switcher-' + className).addClass('selected'); if (className == 'default') { $('#switcher').click(toggleStyleSwitcher); } else { $('#switcher').unbind('click', toggleStyleSwitcher); $('#switcher .button').removeClass('hidden'); } };

// Invoke setBodyClass() when a button is clicked. $('#switcher').click(function(event) { if ($(event.target).is('.button')) { if (event.target.id == 'switcher-default') { setBodyClass('default'); } if (event.target.id == 'switcher-narrow') { setBodyClass('narrow'); } else if (event.target.id == 'switcher-large') { setBodyClass('large'); } } });

// Invoke setBodyClass() when a key is pressed. $(document).keyup(function(event) { switch (String.fromCharCode(event.keyCode)) { case 'D': setBodyClass('default'); break; case 'N': setBodyClass('narrow'); break; case 'L': setBodyClass('large'); break; } });});

Page 93: jQuery 1.3 : 작고 강력한 자바스크립트 라이브러리

3장 이벤트 l 67

요약

3장의 설명을 통해 우리는 다음과 같은 내용들을 살펴보았다.

.noConflict()• 를 사용하여 하나의 페이지내에 다수의 자바스크립트 라이브러리를 동

시에 사용할 수 있다.

.bind()• 나 .click()을 사용해서 사용자의 클릭에 반응하는 마우스 이벤트 핸들러를

작성할 수 있게 되었다.

클릭되는 요소가 무엇이냐에 따라서, 서로 다른 동작들을 수행하기 위해 • 이벤트 컨텍스

트를 사용할 수 있게 되었다. 거기에다가 하나의 핸들러가 여러 요소에 연결되는 경우도

알아보았다.

• .toggle()을 사용하여 페이지의 요소를 펼치거나 접을 수 있게 되었다.

.hover()• 를 사용하여 마우스 커서 위치에 있는 요소를 강조할 수 있게 되었다.

• .stopPropagation()과 .preventDefault()를 이용하여 이벤트에 응답해야 하는 요

소를 결정하기 위해 이벤트 전달 과정을 제어할 수 있게 되었다.

이벤트 위임• 을 구현하여 페이지에서 바인드를 필요로하는 핸들러의 수를 줄였다.

이벤트 핸들러를 제거하기 위해 • .unbind()를 호출할 수 있게 되었다.

이벤트 네임스페이스• 를 사용하여 연관된 이벤트 핸들러들을 분리하여 하나의 그룹 처

럼 동작하도록 한다.

.trigger()• 를 사용하여 실행하고 싶은 이벤트 핸들러와 연결할 수 있게 되었다.

keyup()• 을 사용하여 사용자의 키 입력에 반응하는 키보드 이벤트 핸들러를 사용할 수

있다.

지금까지 사용한 모든 능력을 사용한다면 훌륭하게 상호작용하는 페이지를 만들 수 있을 것이

다. 다음 4장에서는 상호작용을 하는 과정에서 사용자에게 보다 시각적인 피드백을 제공하는

방법에 대해서 배울 것이다.