1. 이벤트 흐름 중단 — stopPropagation()
- 이벤트가 DOM 트리를 따라 내려갔다 올라가는 흐름을 강제로 멈추는 메서드
- 자주 쓸 일은 많지 않음 — 있다는 것만 알고 지나가면 됨
e.stopPropagation();
2. 마우스 핸들링
마우스 버튼 번호 (event.button)
값 의미
| 0 | 아무 버튼도 안 눌림 |
| 1 | 왼쪽 버튼 |
| 2 | 오른쪽 버튼 |
| 3 | 왼쪽 + 오른쪽 동시 |
| 4 | 가운데(휠) 버튼 |
휠 델타 (event.wheelDelta)
- 휠을 위로 굴리면 → 양수
- 휠을 아래로 굴리면 → 음수
- 지도 확대/축소, 테두리 두께 조절 등에 활용
// 휠로 테두리 두께 조절 예시
element.onwheel = function(event) {
if (event.wheelDelta < 0) {
w--;
if (w < 0) w = 0; // 0 이하로 안 내려가게 보호
} else {
w++;
}
obj.style.borderWidth = w + "px";
}
마우스 좌표계 3가지
모니터 전체
┌─────────────────────────────┐
│ screenX/Y │
│ ┌──────────────────────┐ │
│ │ 브라우저 │ │
│ │ ┌────────────────┐ │ │
│ │ │ HTML 영역 │ │ │
│ │ │ clientX/Y │ │ │
│ │ │ ┌──────────┐ │ │ │
│ │ │ │ 객체 │ │ │ │
│ │ │ │ offsetX/Y│ │ │ │
│ │ │ └──────────┘ │ │ │
│ │ └────────────────┘ │ │
│ └──────────────────────┘ │
└─────────────────────────────┘
프로퍼티 기준점
| screenX/Y | 모니터 화면의 맨 왼쪽 위 |
| clientX/Y | 브라우저 HTML 출력 영역의 맨 왼쪽 위 |
| offsetX/Y | 마우스가 올라가 있는 DOM 객체의 맨 왼쪽 위 |
- e.x / e.y 만 쓰면 → clientX/Y와 동일
주요 마우스 이벤트 (암기)
이벤트 발생 시점
| onmousedown | 마우스 버튼 누를 때 |
| onmouseup | 누른 버튼을 놓을 때 |
| onmouseover | 마우스가 영역 위로 올라올 때 |
| onmouseout | 마우스가 영역 밖으로 나갈 때 |
| onmousemove | 마우스가 이동할 때 |
| onwheel | 마우스 휠을 굴릴 때 |
| ondblclick | 더블클릭 시 |
onwheel 이벤트에서 wheelDelta를 읽으려면 반드시 event 객체를 함수에 넘겨야 한다.
예제 — 마우스 이벤트로 스타일 제어
<div onmousedown="down(this)" onmouseup="up(this)"
onmouseover="over(this)" onmouseout="out(this)"
onwheel="wheel(this, event)">
마우스 이벤트 영역
</div>
<script>
function down(obj) { obj.style.fontStyle = "italic"; }
function up(obj) { obj.style.fontStyle = "normal"; }
function over(obj) { obj.style.borderColor = "violet"; }
function out(obj) { obj.style.borderColor = "lightgray"; }
var w = 1;
function wheel(obj, e) {
if (e.wheelDelta < 0) { w--; if (w < 0) w = 0; }
else w++;
obj.style.borderStyle = "ridge";
obj.style.borderWidth = w + "px";
}
</script>
3. oncontextmenu — 불펌 방지
- 마우스 오른쪽 버튼 클릭 시 발생하는 이벤트
- 기본 동작: 소스 보기, 이미지 저장 등 컨텍스트 메뉴가 뜸
- return false로 메뉴 자체를 차단 → 불펌 방지
document.oncontextmenu = function() {
alert("오른쪽 클릭 금지! 불법 다운로드는 법적 처벌을 받습니다.");
return false; // 이게 핵심 — 컨텍스트 메뉴 안 뜸
}
4. onload 정리
두 가지 작성 방법이 있지만 2번 방법만 쓸 것:
// 방법① — 쓰지 말 것 (최근 브라우저에서 작동 안 할 수 있음)
window.onload = function() { ... }
// 방법② — 이 방법만 사용
<body onload="init()">
활용 예: 페이지 뜨자마자 공지 알림창 띄우기
<body onload="alert('이 사이트는 2027년 9월 1일부터 이전됩니다.')">
5. 이미지 onload — 이미지 로딩 완료 이벤트
body onload와 완전히 다른 것. 이미지 파일이 서버에서 내 브라우저로 다 도착했을 때 발생.
왜 필요한가: 이미지가 크면 img.src에 값을 넣은 직후 img.width를 읽으면 아직 로딩 안 됐을 수 있음.
// 잘못된 방법 — 이미지가 아직 안 왔을 수 있음
var img = document.getElementById("myImg");
img.src = "banana.png";
alert(img.width); // 0 또는 이상한 값 나올 수 있음
// 올바른 방법 — onload 이벤트 안에서 읽기
img.onload = function() {
alert(img.width + " x " + img.height); // 로딩 완료 후 정확한 값
}
img.src = "banana.png";
6. select + 이미지 교체 예제 (예제 9-4)
셀렉트 박스에서 항목 선택 시 해당 이미지로 교체.
<select id="sel" onchange="changeImage()">
<option value="images/apple.png">사과</option>
<option value="images/banana.png">바나나</option>
<option value="images/mango.png">망고</option>
</select>
<span id="mySpan">이미지 크기</span>
<img id="myImg" src="images/apple.png" width="200" height="200">
<script>
function changeImage() {
var sel = document.getElementById("sel");
var img = document.getElementById("myImg");
img.onload = function() {
document.getElementById("mySpan").innerHTML =
"이미지 크기 " + img.width + "x" + img.height;
}
var index = sel.selectedIndex; // 선택된 항목 순서 (0부터)
img.src = sel.options[index].value; // 해당 option의 value 값
}
</script>
- selectedIndex: 현재 선택된 항목의 인덱스 (0, 1, 2...)
- options[index].value: 해당 인덱스 option의 value 속성값
7. new Image() & 슬라이드쇼 (예제 9-5)
이미지 여러 장을 배열로 미리 준비해두고, 클릭 시 다음 이미지로 넘어가는 슬라이드쇼.
// 이미지 파일명 배열
var pics = ["penguin.jpg", "lighthouse.jpg", "bird.jpg", ...]; // 8개
// 이미지 객체 배열 — 미리 로딩
var imgs = new Array(pics.length);
for (var i = 0; i < pics.length; i++) {
imgs[i] = new Image();
imgs[i].src = "images/" + pics[i];
}
var next = 1;
function change(img) {
img.src = imgs[next].src; // 다음 이미지로 교체
next = (next + 1) % pics.length; // 나머지 연산으로 순환 (0~7 반복)
}
<img src="images/penguin.jpg" onclick="change(this)" width="200" height="200">
- new Image(): 화면에 안 보이는 이미지 객체 생성 — 미리 로딩 용도
- % pics.length: 마지막 인덱스를 넘으면 다시 0으로 순환
8. onFocus / onBlur
이벤트 발생 시점
| onfocus | 포커스가 들어올 때 (클릭해서 커서가 들어올 때) |
| onblur | 포커스가 빠져나갈 때 (다른 곳을 클릭할 때) |
- 포커스: 키보드 입력이 들어가는 지점 (마우스 커서 위치 아님)
- 블러: 초점이 흐려지는 것 = 포커스 없어짐
활용 — 입력 유효성 검사 (onblur)
<body onload="document.getElementById('name').focus()">
<!-- 화면 뜨자마자 이름 입력창에 자동 포커스 -->
<input type="text" id="name" onblur="checkField(this)">
<script>
function checkField(obj) {
if (obj.value == "") {
alert("이름을 입력하세요.");
obj.focus(); // 강제로 포커스 다시 돌려보냄
}
}
</script>
- obj.focus(): 강제로 해당 태그에 포커스 부여
9. 라디오버튼 / 체크박스
라디오버튼 작성
<form>
<input type="radio" name="city" value="서울" checked> 서울
<input type="radio" name="city" value="부산"> 부산
<input type="radio" name="city" value="춘천"> 춘천
<input type="button" value="선택 확인" onclick="findChecked()">
</form>
- 같은 그룹이면 name을 동일하게 줘야 함 (여기선 "city")
- checked: 처음 화면에서 기본 선택 상태
- value: 선택 시 저장되는 값 (사용자에게 안 보이는 내부 값)
- 체크박스는 type="radio" → type="checkbox"로만 바꾸면 됨
선택된 라디오버튼 찾기
function findChecked() {
var found = null;
var kct = document.getElementsByName("city"); // name으로 찾기 → 배열 반환
for (var i = 0; i < kct.length; i++) {
if (kct[i].checked) { // checked = true면 선택된 것
found = kct[i];
break;
}
}
if (found != null)
alert(found.value); // 선택된 항목의 value 출력
else
alert("선택된 것이 없음");
}
- getElementsByName(): name 속성으로 찾기 → 배열(컬렉션) 반환
- getElementById()는 id로 1개만 반환 — 라디오버튼에는 못 씀
주요 개념
- 좌표계 3가지: screenX/Y(모니터 기준), clientX/Y(HTML 영역 기준), offsetX/Y(객체 기준)
- onwheel + wheelDelta: 위로 굴리면 양수, 아래로 굴리면 음수
- oncontextmenu + return false: 불펌 방지 패턴
- 이미지 onload: img.src 바꾼 후 크기 읽으려면 onload 안에서 읽어야 정확
- selectedIndex / options[].value: select 태그에서 선택 항목 처리
- new Image(): 화면에 안 보이지만 이미지 미리 로딩하는 객체
- % (나머지 연산): 배열 순환 패턴 (next = (next + 1) % 전체개수)
- onfocus / onblur: 포커스 이동 감지 → 입력 유효성 검사에 활용
- getElementsByName(): name 속성으로 배열 반환 — 라디오버튼 그룹 처리에 필수
다시 보기
Q. screenX/Y, clientX/Y, offsetX/Y 각각 언제 쓰나?
- screenX/Y: 모니터 전체 기준 — 팝업 창 위치 결정 등
- clientX/Y: 브라우저 HTML 영역 기준 — 일반적인 웹 내 클릭 위치
- offsetX/Y: 클릭한 DOM 객체 내에서의 상대 좌표 — 객체 안에서 어디를 눌렀는지 알 때
- e.x / e.y 만 쓰면 clientX/Y와 동일
Q. 이미지 onload와 body onload를 왜 구분해야 하나?
- body onload: HTML 문서가 메모리에 로드됐을 때 → 초기화 루틴 심는 용도
- 이미지 onload: 이미지 파일이 서버에서 브라우저로 다 전송됐을 때 → 이미지 크기 읽기 가능한 시점
- 둘 다 "onload"지만 발생 주체가 window(문서)냐 img(이미지 파일)냐로 완전히 다름
Q. onwheel 이벤트에서만 event 객체를 명시해서 넘기는 이유는?
- wheelDelta가 이벤트 객체에 담겨 있기 때문
- this는 DOM 객체 자체, event는 이벤트 관련 정보 → 둘 다 넘겨야 함
- onmouseover="over(this)"는 DOM 객체만 필요해서 this만 넘기지만, 휠은 event도 필요
Q. getElementsByName과 getElementById의 차이는?
- getElementById: id로 1개 반환
- getElementsByName: name으로 여러 개(배열) 반환
- 라디오버튼은 같은 name을 여러 태그가 공유하므로 반드시 getElementsByName 사용
Q. 슬라이드쇼에서 new Image()로 미리 로딩하는 이유는?
- 클릭할 때마다 img.src만 바꾸면 그때마다 서버에서 이미지를 새로 받아와야 함
- new Image()로 미리 다 받아두면 클릭 시 즉시 표시 — 로딩 지연 없음
'웹프로그래밍' 카테고리의 다른 글
| [웹프로그래밍] BOM 마무리와 HTML5 Canvas — navigator·screen·history·드래그 그림판 (0) | 2026.06.08 |
|---|---|
| [웹프로그래밍] BOM과 타이머 — window.open·setTimeout·setInterval·location (0) | 2026.06.01 |
| [웹프로그래밍] DOM 조작과 이벤트 — 리스너 등록·이벤트 객체·익명 함수 (1) | 2026.06.01 |
| [웹프로그래밍] 코어 객체·배열·DOM 기초 — Array·Date·String·getElementById (0) | 2026.06.01 |
| [웹프로그래밍] JavaScript 연산자와 조건문 — 형변환과 if-else (0) | 2026.06.01 |