개발자입니다
[비트캠프] 28일차(6주차3일) - Javascript(이벤트: 등록, 정보 다루기, 전파, 기본 동작 중지) 본문
[비트캠프] 28일차(6주차3일) - Javascript(이벤트: 등록, 정보 다루기, 전파, 기본 동작 중지)
끈기JK 2022. 12. 14. 11:39
이벤트 - 리스너 등록하기
이벤트(event)
=> 사용자나 시스템에 의해 태그의 상태가 바뀌는 것을 가리킨다.
=> 각 태그 별로 발생하는 이벤트가 정해져 있다.
=> 물론 개발자가 임의의 이벤트를 발생시킬 수 있다.
리스너(listener) = 이벤트 핸들러(event handler)
=> 이벤트가 발생할 때 호출되는 메서드이다.
=> HTML 태그나 자바스크립트 코드에서 이벤트에 대해 함수를 등록해야 한다.
click 이벤트
=> 사용자가 태그를 클릭할 때 발생한다.
click 이벤트에 대해 리스너를 등록하는 방법
1) HTML 태그의 onclick 속성에 자바스크립트 코드를 넣는다.
=> 사용자가 태그를 클릭하면 이 속성에 등록된 자바스크립트 코드가 실행된다.
=> 이 방식은 태그 안에 자바스크립트 코드가 섞여 있기 때문에 유지보수할 때 힘들다.
=> HTML 태그는 태그대로, 자바스크립트 코드는 코드대로 분리되어 있어야 유지보수가 쉽다.
=> 태그 안에 자바스크립트 코드를 넣어야 하기 때문에 긴 코드를 넣기가 불편한다.
2) 태그 객체의 onclick 프로퍼티에 함수를 등록한다.
=> 사용자가 태그를 클릭하면 onclick이라는 이름으로 등록된 함수를 호출한다.
=> HTML 태그와 자바스크립트 코드가 분리되어 있어서 유지보수하기 쉽다.
=> 이 방식은 이벤트에 대해 한 개의 리스너만 등록할 수 있다.
3) 태그 객체의 addEventListener()를 이용하여 호출될 함수를 등록한다.
=> 사용자가 태그를 클릭하면 해당 이벤트에 등록된 함수가 호출된다.
=> 이 또한 HTML 태그와 자바스크립트 코드가 분리되어 있어서 유지보수에 좋다.
=> 특히 여러 개의 리스너를 등록할 수 있다.
// ex06\exam01-1.html
<h1>이벤트 - 리스너 등록하기</h1>
<button id="btn1-1" onclick="var str='Hello'; window.alert(str);">버튼1-1</button><br>
<input id="input1" type="text">
<button id="btn1-2" onclick="btn1Click()">버튼1-2</button><br>
<button id="btn2">버튼2</button><br>
<button id="btn3">버튼3</button><br>
<script>
// 방법1:
function btn1Click() {
var msg = document.getElementById('input1');
if (msg.value == 'ok') {
console.log('하하하');
} else {
console.log('-.-');
}
}
// 방법2:
//var btn2 = document.getElementById("btn2");
var btn2 = document.querySelector("#btn2"); // 둘 중 아무거나 사용하면 된다.
//var btn2 = $("#btn2");
/*
function f1() {
var str = "Hello2a!";
window.alert(str);
console.log(this); // this는 이 함수가 소속된 객체를 통해 호출될 때 그 객체를 가리킨다.
}
btn2.onclick = f1; // 함수의 주소를 객체 프로퍼티로 저장하는 순간 그 객체에 소속된다.
*/
/*
btn2.onclick = function () {
var str = "Hello2b!";
window.alert(str);
console.log(this); // 일반 함수에서 this는 그 함수가 소속된 객체이다.
};
*/
btn2.onclick = () => {
var str = "Hello2c!";
window.alert(str);
console.log(this); // arrow function에서 this는 window 객체이다.
};
// 방법3:
// => addEventListener(이벤트명, 리스너);
// => 주의!
// 클릭 이벤트의 이름은 "onclick"이 아니라, "click"이다.
//
var btn3 = document.querySelector("#btn3");
btn3.addEventListener("click", btn3Click);
function btn3Click() {
var str = "Hi1!!";
window.alert(str);
console.log(this); // this는 btn3 객체이다.
}
btn3.addEventListener("click", function () {
var str = "Hi2!!";
window.alert(str);
console.log(this); // this는 btn3 객체이다.
});
btn3.addEventListener("click", () => {
var str = "Hi3!!";
window.alert(str);
console.log(this); // this는 window 객체이다.
});
이벤트 - 리스너 실행 순서
한 태그에 세가지 방법으로 등록된 리스너가 있을 때 호출되는 순서는?
=> 만약 태그 객체에 대해 onclick 프로퍼티로 리스너를 등록했다면, 태그의 onclick 속성에 등록된 자바스크립트 코드는 실행되지 않는다.
=> 태그 객체에 대해 onclick 프로퍼티로 등록한 리스너가 먼저 실행된다. 그런 후에 addEventListener()로 등록한 리스너를 호출한다.
=> 주의!
이 호출 순서에 의존하여 코드를 작성하지 말라! 또한 세가지 방법 중에 한 가지 방법으로 리스너를 등록하라! 그렇게 일관성이 있어야 유지보수가 쉬워진다.
<h1>이벤트 - 리스너 실행 순서</h1>
<button id="btn1" onclick="var str='Hello1'; window.alert(str);">버튼1</button><br>
<script>
var btn1 = document.querySelector("#btn1");
// 태그의 onclick 속성에 자바스크립트가 있든
// 태그 객체의 onclick 프로퍼티에 리스너를 등록하였든 상관없이
// 리스너를 추가한다.
btn1.addEventListener("click", () => {
var str = "Hello3";
window.alert(str);
});
// 태그의 onclick 속성 값을 설정했다면 그 값을 대체한다.
//
btn1.onclick = () => {
var str = "Hello2";
window.alert(str);
};
이벤트 - 각 태그 객체에 따로따로 이벤트 리스너를 등록해야 한다.
<button class="btn1">btn1-버튼1</button>
<button class="btn1">btn1-버튼2</button>
<button class="btn1">btn1-버튼3</button><br>
<button class="btn2">btn2-버튼1</button>
<button class="btn2">btn2-버튼2</button>
<button class="btn2">btn2-버튼3</button><br>
<script>
"use strict"
var el = document.querySelectorAll(".btn1");
// querySelectorAll()의 리턴 값은 NodeList 이다.
// 태그 객체가 아니다.
// 따라서 addEventListener() 함수가 없다.
/*
el.addEventListener("click", () => {
console.log(this);
});
*/
// 또한 onclick 프로퍼티도 없다.
// 따라서 다음 코드는 의미 없다.
/*
el.onclick = () => {
console.log(this);
};
*/
// 다음과 같이 각 태그 객체에 리스너를 추가하던가!
/*
for (var e of el) {
e.onclick = function () {
console.log(this);
}
}
*/
// 다음처럼 한 개의 함수를 정의한 후에
// 각 태그에 리스너로 등록하던가!
function f1() {
console.log(this);
}
for (var e of el) {
e.onclick = f1
}
// JQuery
//$(".btn1").on('click', function() {
// console.log(this);
//});
//$(".btn1").click(function() {
// console.log(this);
//});
이벤트 - 이벤트 정보 다루기 I
이벤트가 발생하면 웹브라우저는 이벤트 정보를 객체에 담아서 리스너를 호출할 때 파라미터로 전달한다.
이벤트 객체는 이벤트 종류에 따라 미리 정의된 생성자에 의해서 초기화된다. 즉 이벤트 종류에 따라 특정 생성자가 이벤트 객체를 준비한다.
예)
=> 마우스 클릭, 더블클릭, 누를 때, 뗄 때 - PointerEvent() 생성자가 초기화시킨다.
=> 키보드에서 키를 누를 때, 뗄 때, 눌렀다 땔 때 - KeyboardEvent() 생성자가 초기화시킨다.
=> 콘텐트를 편집할 때 - InputEvent() 생성자가 초기화시킨다.
=> UI 객체가 포커스를 얻었을 때, 잃었을 때 - FocusEvent() 생성자가 초기화시킨다.
태그의 onclick 속성에 자바스크립트 코드를 둘 때 이벤트 정보를 사용하는 방법?
=> "event" 라는 이름으로 정의된 객체가 있다. 그 객체를 사용하면 된다.
=> 이 event 객체는 PointerEvent()가 초기화시킨 객체이다.
=> 즉 PointerEvent() 생성자가 추가한 속성을 사용할 수 있다.
PointerEvent 주요 속성
=> altKey : Alt 키 누름 여부
=> ctrlKey : Ctrl 키 누름 여부
=> button : 누른 버튼 번호
=> offsetX/Y : 버튼 영역을 기준으로 X/Y 좌표
=> clientX/Y : 웹브라우저 내용창을 기준으로 X/Y 좌표
=> screenX/Y : 바탕화면 영역을 기준으로 X/Y 좌표
<button id="btn1" onclick="console.log(event)">버튼1</button><br>
이벤트 - 이벤트 정보 다루기 II
HTML 태그의 onclick 속성에 많은 자바스크립트 코드를 넣을 수 없을 때, 함수를 만들고 호출하라!
=> 물론 event 객체를 함수를 호출할 때 넘겨줘야 한다.
당연히 함수에서는 event 객체를 받는 파라미터가 있어야 한다.
<button id="btn1" onclick="btn1Click(event)">버튼1</button><br>
<script>
function btn1Click(e) {
console.log(e);
console.log(e.constructor.name);
console.log(e instanceof MouseEvent);
console.log(
e.altKey, e.ctrlKey, e.button,
e.offsetX, e.offsetY,
e.clientX, e.clientY,
e.screenX, e.screenY)
}
이벤트 - 이벤트 정보 다루기 III
<div>
테스트!
<button id="btn1">버튼1</button><br>
</div>
<script>
"use strict"
// 태그 객체의 onclick 프로퍼티에 리스너 등록하고 이벤트 정보 추출
document.getElementById("btn1").onclick = function(e) {
console.log(
e.altKey, e.ctrlKey, e.button,
e.offsetX, e.offsetY,
e.clientX, e.clientY,
e.screenX, e.screenY)
};
/*
$("#btn1").click(function(e) {
console.log(
e.altKey, e.ctrlKey, e.button,
e.offsetX, e.offsetY,
e.clientX, e.clientY,
e.screenX, e.screenY)
});
*/
// id가 부여된 태그는 window 객체를 통해 바로 접근할 수 있다.
/*
window.btn1.onclick = function() {
console.log("test..ok!");
};
*/
이벤트 - 이벤트 정보 다루기 IV
<button id="btn1">버튼1</button><br>
<script>
"use strict"
// addEventListener() 사용
document.getElementById("btn1").addEventListener("click", function(e) {
console.log(
e.altKey, e.ctrlKey, e.button,
e.offsetX, e.offsetY,
e.clientX, e.clientY,
e.screenX, e.screenY)
});
이벤트 - 이벤트가 발생된 태그 알아내기
리스너가 일반 함수나 익명 함수일 경우, this가 가리키는 객체가 이벤트가 발생된 객체이다.
<button id="btn1" data-no="100">버튼1</button><br>
<script>
document.getElementById("btn1").addEventListener("click", function (e) {
console.log(this);
// 이벤트가 발생한 객체의 속성 값 알아내기
// => 개발자가 임의로 추가한 속성인 경우 반드시 getAttribute()를 사용해야 한다.
console.log(this.getAttribute("data-no"));
// 개발자가 태그에 임의로 추가한 속성은 다음과 같이 일반적인 방법으로 꺼낼 수 없다.
console.log(this["data-no"]); // undefined
// 태그에 원래 있던 속성이라면 일반적인 문법으로 접근할 수 있다.
console.log(this.id);
});
이벤트 - 이벤트가 발생된 태그 알아내기 II
arrow function인 경우 this는 window 객체를 가리킨다.
<button id="btn1" data-no="100">버튼1</button><br>
<script>
document.getElementById("btn1").addEventListener("click", (e) => {
console.log(this); // window 객체이다.
// 그럼 arrow function(자바에서는 Lambda라 부른다)에서는
// 이벤트가 발생된 객체를 알 수 없는가?
// => 있다!
// 이벤트 객체에 이벤트가 발생된 태그의 주소가 들어 있다.
console.log(e.target);
// 이벤트가 발생한 객체의 속성 값 알아내기
console.log(e.target.getAttribute("data-no"));
});
이벤트 - 이벤트가 발생된 태그 알아내기 III
여러 개의 태그에 같은 리스너를 등록했을 경우 리스너가 호출될 때 어떤 태그인지 알아내는 방법!
<button id="btn1" class="b1" data-no="100">버튼1</button><br>
<button id="btn2" class="b1" data-no="200">버튼2</button><br>
<button id="btn3" class="b2" data-no="300">버튼3</button><br>
<button id="btn4" class="b2" data-no="400">버튼4</button><br>
<p id="message"></p>
<script>
"use strict"
var el = document.querySelectorAll(".b1");
var p = document.querySelector("#message");
p.style.width = "200px";
p.style.height = "100px";
// 스타일 이름에 공백이나 특수 문자가 포함된 경우
// 자바스크립트에서 프로퍼티 이름을 사용할 수 없다.
//p.style.background-color = "gray"; // 프로퍼티 이름 중간에 - 문자가 있으면 안된다.
// 그래서 다음과 같이 대괄로 문법으로 스타일을 설정해야 한다.
p.style["background-color"] = "yellow";
// 웹브라우저 API는
// 개발자들이 스타일 이름을 프로퍼티 이름 규칙에 따라 사용할 수 있도록
// 스타일 이름을 변경한 프로퍼티를 제공한다.
// 예) background-color ===> backgroundColor
// 예) border-top-width ===> borderTopWidth
// 따라서 다음과 같이 배경색을 지정할 수 있다.
// p.style.backgroundColor = "yellow";
p.style.color = "green";
p.style.border = "5px dashed red";
var btnClick = function (event) {
p.innerHTML = this.getAttribute("data-no");
};
for (var e of el) {
e.addEventListener("click", btnClick);
}
이벤트 - 이벤트 단계
이벤트가 발생하면 다음 3단계로 전달 된다.
1) capture phase
=> 부모 태그에서 자식 태그로 내려가는 단계
2) target phase
=> 이벤트가 발생된 목적지에 도달한 단계
3) bubble phase
=> 다시 목적지에서 부모 태그로 올라가는 단계
다음과 같은 방법으로 이벤트 리스너를 등록하면,
이벤트가 발생했을 때
capture phase 단계는 건너뛰고
target과 bubble 단계에서 호출된다.
=> <태그 onclick="자바스크립트 코드"></태그>
=> <태그객체.onclick = function() {}
=> <태그객체.addEventListener("click", function() {});
#btn1이나 #btn2를 클릭하면,
=> 버튼에 등록된 click 리스너가 호출된다.
=> 부모들에 등록된 click 리스너도 위로 올라가면서 순차적으로 호출된다.
<body onclick="console.log('body')">
<div id="d1" onclick="console.log('#d1')">d1
<div id="d2" onclick="console.log('#d2')">d2
<button id=" btn1" onclick="console.log('#btn1')">버튼1</button>
<button id="btn2" onclick="console.log('#btn2')">버튼2</button>
</div>
</div>
이벤트 단계
event 발생 → ① capture phase로 전달 → ② target phase로 전달 → ③ bubble phase로 전달
button#btn2 를 click하면 event가 html로 전달된다.
① capture phase에 html → body → div#d1 → div#d2 로 전달된다.
② target phase에 div#d2 → button#btn2 로 전달된다.
③ bubble phase에 button#btn2 → div#d2 → div#d1 → body → html → ~ 로 전달된다.
이벤트 단계와 리스너 호출
이벤트 등록은 3개 방법이 있다.
태그객체.onclick = function() {-}
태그객체.addEventListener(
"click",
function() { - });
태그객체.addEventListener(
"click"
function() { - },
false);
→ event 발생 → 캡쳐 단계 무시 → 타겟 단계에서 리스너 호출 → 버블 단계에서 리스너 호출
이벤트 발생시 html ~ div#d2 건너뛰고 바로 ① target phase 가서 button#btn2 리스너 호출한다.
script에 document.getElementById(" - ").onclick 으로 클릭이벤트 등록하는 방법
<h1>이벤트 - 이벤트 단계</h1>
<div id="d1">d1
<div id="d2">d2
<button id="btn1">버튼1</button>
<button id="btn2">버튼2</button>
</div>
</div>
<script>
"use strict"
document.getElementById("btn1").onclick = function (e) {
console.log("버튼1...");
};
document.getElementById("btn2").onclick = function (e) {
console.log("버튼2...");
};
document.getElementById("d2").onclick = function (e) {
console.log("d2...");
};
document.getElementById("d1").onclick = function (e) {
console.log("d1...");
};
document.body.onclick = function (e) {
console.log("body...");
};
addEventListener(
이벤트명,
리스너,
캡쳐단계에서 실행 할지 여부 <== 캡쳐 단계에서 실행 여부
);
document.getElementById("btn1").addEventListener("click", function (e) {
console.log("버튼1...");
});
document.getElementById("btn2").addEventListener("click", function (e) {
console.log("버튼2...");
});
document.getElementById("d2").addEventListener("click", function (e) {
console.log("d2...");
});
document.getElementById("d1").addEventListener("click", function (e) {
console.log("d1...");
});
document.body.addEventListener("click", function (e) {
console.log("body...");
});
addEventListener 의 3번째 argument에 false는 기본이며 캡쳐 단계 실행 여부를 설정한다.
document.getElementById("btn1").addEventListener("click", function (e) {
console.log("버튼1...");
}, false);
document.getElementById("btn2").addEventListener("click", function (e) {
console.log("버튼2...");
}, false);
document.getElementById("d2").addEventListener("click", function (e) {
console.log("d2...");
}, false);
document.getElementById("d1").addEventListener("click", function (e) {
console.log("d1...");
}, false);
document.body.addEventListener("click", function (e) {
console.log("body...");
}, false);
이벤트 - bubble 대신 capture와 target 단계에서 호출되는 리스너 등록하기
세번째 파라미터를 true로 설정하면, capture 단계와 target 단계에서만 호출된다.
<div id="d1">d1
<div id="d2">d2
<button id="btn1">버튼1</button>
<button id="btn2">버튼2</button>
</div>
</div>
<script>
"use strict"
document.getElementById("btn1").addEventListener("click", function (e) {
console.log("버튼1...");
}, true);
// target, bubble 단계에서 호출되도록 설정한다.
document.getElementById("btn2").addEventListener("click", function (e) {
console.log("버튼2...");
});
// capture, target 단계에서 호출되도록 설정한다.
document.getElementById("d2").addEventListener("click", function (e) {
console.log("d2...");
}, true);
// capture, target 단계에서 호출되도록 설정한다.
document.getElementById("d1").addEventListener("click", function (e) {
console.log("d1...");
}, true);
// capture, target 단계에서 호출되도록 설정한다.
document.body.addEventListener("click", function (e) {
console.log("body...");
}, true);
정리!
=> addEventListener(이벤트, 리스너, false) : target, bubble 단계일 때 리스너가 호출된다.
- 세 번째 파라미터가 없으면 기본이 false이다.
=> addEventListener(이벤트, 리스너, true) : capture, target 단계일 때 리스너가 호출된다.
이벤트 - 이벤트 전파 막기
이벤트가 발생하면 capture-target-bubble 단계로 진행한다.
target 단계에서 bubble 단계로 진행하는 것을 막지 않으면 부모 태그에 등록된 리스너까지 호출되는 문제가 발생한다.
<div id="d1">d1
<div id="d2">d2
<button id="btn1">버튼1</button>
<button id="btn2">버튼2</button>
</div>
</div>
<script>
"use strict"
// 방법1: Event.stopPropagation()을 호출하라!
// => 이벤트 bubbling을 막는다.
// => 단 target에 등록된 함수는 모두 호출된다.
//
document.getElementById("btn1").addEventListener("click", function (e) {
console.log("버튼1...1");
e.stopPropagation(); // 버블링을 하지 않도록 설정한다.
});
document.getElementById("btn1").addEventListener("click", function (e) {
console.log("버튼1...2");
});
document.getElementById("btn1").addEventListener("click", function (e) {
console.log("버튼1...3");
});
//방법2: Event.stopImmediatePropagation()을 호출하라!
//=> 이벤트 bubbling을 막는다.
//=> target에 등록된 함수라도 즉시 현 함수에서 실행을 마감한다.
//
document.getElementById("btn2").addEventListener("click", function (e) {
console.log("버튼2...1");
e.stopImmediatePropagation(); // 이 리스너까지만 실행한다.
});
document.getElementById("btn2").addEventListener("click", function (e) {
console.log("버튼2...2");
});
document.getElementById("btn2").addEventListener("click", function (e) {
console.log("버튼2...3");
});
document.getElementById("d2").addEventListener("click", function (e) {
console.log("d2...");
});
document.getElementById("d1").addEventListener("click", function (e) {
console.log("d1...");
});
document.body.addEventListener("click", function (e) {
console.log("body...");
});
이벤트 - 이벤트 전파 기능을 이용하지 않는 경우
자식 태그에 대해 이벤트 리스너를 등록할 때 그 자식 태그를 클릭했을 때만 호출된다.
예) 제목을 출력하는 a 태그에 click 리스너를 등록하면 정확하게 제목을 클릭해야만 동작한다.
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>등록일</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><a href="https://www.daum.net" data-no="1">제목</a></td>
<td>홍길동</td>
<td>2019-4-29</td>
<td>100</td>
</tr>
<tr>
<td>2</td>
<td><a href="https://www.daum.net" data-no="2">제목</a></td>
<td>임꺽정</td>
<td>2019-4-29</td>
<td>800</td>
</tr>
<tr>
<td>3</td>
<td><a href="https://www.daum.net" data-no="3">제목입니다.</a></td>
<td>유관순</td>
<td>2019-4-29</td>
<td>900</td>
</tr>
</tbody>
</table>
<script>
"use strict"
var el = document.querySelectorAll("tbody a");
for (var e of el) {
e.addEventListener("click", function (e) {
console.log(e.target);
console.log(e.target.getAttribute("data-no") + " 번 게시물의 제목을 눌렀음!");
});
}
이벤트 - 이벤트 전파 기능을 이용하기
부모 태그에 리스너를 등록하면 훨씬 더 광범위하게 클릭 이벤트를 처리할 수 있다.
즉 자식 태그의 이벤트를 부모 태그에서 처리할 수 있다. 어떻게? 부모로 이벤트가 전파되는 기능을 이용하는 것이다.
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>등록일</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
<tr data-no="1">
<td>1</td>
<td><a href="https://www.daum.net" onclick="return false;">제목</a></td>
<td>홍길동</td>
<td>2019-4-29</td>
<td>100</td>
</tr>
<tr data-no="2">
<td>2</td>
<td><a href="https://www.daum.net" onclick="return false;">제목</a></td>
<td>임꺽정</td>
<td>2019-4-29</td>
<td>800</td>
</tr>
<tr data-no="3">
<td>3</td>
<td><a href="https://www.daum.net" onclick="return false;">제목입니다.</a></td>
<td>유관순</td>
<td>2019-4-29</td>
<td>900</td>
</tr>
</tbody>
</table>
<script>
"use strict"
var el = document.querySelectorAll("tbody tr");
for (var e of el) {
e.addEventListener("click", function (e) {
// e.target 은 이벤트가 발생한 객체를 가리킨다.
// console.log(e.target);
// console.log(e.target.getAttribute("data-no") + " 번 게시물의 제목을 눌렀음!");
// 리스너가 등록된 태그를 가리키고 싶다면,
// e.currentTarget 프로퍼티의 값을 사용하라!
console.log(e.currentTarget);
console.log(e.currentTarget.getAttribute("data-no") + " 번 게시물의 제목을 눌렀음!");
console.log("-------------------------------");
// 자바스크립트에서 다른 페이지로 이동시킨다.
window.location.href = "https://www.daum.net/board?no=" + e.currentTarget.getAttribute("data-no");
});
}
이벤트 - 프로그래밍으로 이벤트 발생시키기
사용자의 행위가 아닌 프로그래밍으로 특정 이벤트를 발생시킬 수 있다.
<div id="d1">d1
<div id="d2">d2
<button id="btn1">버튼1</button>
<button id="btn2">버튼2</button>
</div>
</div>
<script>
"use strict"
document.getElementById("btn1").addEventListener("click", function(e) {
// #btn1을 눌렀을 때 #btn2에 click 이벤트 발생시키기
// 1) MouseEvent 만들기
var myEvent = new MouseEvent("click");
// 2) 위에서 생성한 이벤트 객체를 #btn2에 보낸다.
document.getElementById("btn2").dispatchEvent(myEvent);
});
document.getElementById("btn2").addEventListener("click", function(e) {
console.log("버튼2...");
});
객체와 인스턴스
var e = new MouseEvent() 명령어로 객체가 만들어 지는데 MouseEvent의 "인스턴스(instance)" 라 한다. 함수(생성자)를 통해서 초기화된 객체이다.
var f = function() { - } 는 객체이나 객체라 하지는 않는다.
다음은 객체이다.
"Hello" : 스트링 리터럴
100
true
new Object() : Object의 "인스턴스"
function() { - }
이벤트 - 커스텀 이벤트 발생시키기
javascript에 정의된 이벤트가 아닌 개발자가 임의의 이벤트를 만들어 발생시킬 수 있다.
=> Event() 생성자를 사용해서 이벤트 객체를 만들어야 한다.
<div id="d1">d1
<div id="d2">d2
<button id="btn1">버튼1</button>
<button id="btn2">버튼2</button>
</div>
</div>
<script>
"use strict"
document.getElementById("btn1").addEventListener("click", function (e) {
// #btn1을 눌렀을 때 #btn2에 "ohora" 이벤트를 발생시키기
// 1) Event 만들기
var myEvent = new Event("ohora");
// 2) 위에서 생성한 이벤트 객체를 #btn2에 보낸다.
document.getElementById("btn2").dispatchEvent(myEvent);
});
// "ohora" 이벤트를 처리하고 싶다면,
// 다음과 같이 이벤트 이름을 "ohora"로 지정하라!
document.getElementById("btn2").addEventListener("ohora", function (e) {
console.log("버튼2...");
});
이벤트 - 커스텀 이벤트 발생시키기 II
커스텀 이벤트에 데이터를 첨부해서 보내기
=> CustomEvent() 생성자를 사용해서 이벤트 객체를 만들어야 한다.
<div id="d1">d1
<div id="d2">d2
<button id="btn1">버튼1</button>
<button id="btn2">버튼2</button>
</div>
</div>
<script>
"use strict"
document.getElementById("btn1").addEventListener("click", function (e) {
// #btn1을 눌렀을 때 #btn2에 "ohora" 이벤트를 발생시키기
// 1) CustomEvent 만들기
// => 이벤트 객체에 데이터를 첨부할 때는 "detail"이라는 이름으로 데이터를 첨부하라!
var myEvent = new CustomEvent("ohora", {
detail: "hello!!"
});
// 2) 위에서 생성한 이벤트 객체를 #btn2에 보낸다.
document.getElementById("btn2").dispatchEvent(myEvent);
});
// "ohora" 이벤트를 처리하고 싶다면,
// 다음과 같이 이벤트 이름을 "ohora"로 지정하라!
document.getElementById("btn2").addEventListener("ohora", function (e) {
console.log("버튼2...", e.detail);
});
이벤트 - 커스텀 이벤트 발생시키기 III
커스텀 이벤트에 여러 개의 데이터를 첨부해서 보내기.
=> CustomEvent() 생성자를 사용해서 이벤트 객체를 만들어야 한다.
<div id="d1">d1
<div id="d2">d2
<button id="btn1">버튼1</button>
<button id="btn2">버튼2</button>
</div>
</div>
<script>
"use strict"
document.getElementById("btn1").addEventListener("click", function(e) {
// #btn1을 눌렀을 때 #btn2에 "ohora" 이벤트를 발생시키기
// 1) CustomEvent 만들기
// => 이벤트 객체에 데이터를 첨부할 때는 "detail"이라는 이름으로 데이터를 첨부하라!
var myEvent = new CustomEvent("ohora",
{detail: {
name:"홍길동",
age:20,
tel:"1111-2222"
}
});
// 2) 위에서 생성한 이벤트 객체를 #btn2에 보낸다.
document.getElementById("btn2").dispatchEvent(myEvent);
});
// "ohora" 이벤트를 처리하고 싶다면,
// 다음과 같이 이벤트 이름을 "ohora"로 지정하라!
document.getElementById("btn2").addEventListener("ohora", function(e) {
console.log("버튼2...");
console.log("name=", e.detail.name);
console.log("age=", e.detail.age);
console.log("tel=", e.detail.tel);
});
이벤트 - a 태그의 기본 동작을 중단시키기
- onclick 내용에 return false 입력하기
- 함수를 리턴하고 함수 내에 return false 입력하기
- preventDefault() 로 기본동작 중단하기. addEventListener 사용시 이 방법만으로 중단된다. - 가급적 이 방법 사용
<p>a 태그의 링크를 클릭하면 href 에 등록한 URL을 요청하는 것이
a 태그의 기본 동작이다.</p>
<a href="http://www.daum.net" onclick="alert('OK!')">a 태그의 기본 동작 계속</a><br>
<!-- 기본 동작을 막고 싶다면 onclick 속성에 작성하는 스크립트의 리턴 값을 false로 지정하라! -->
<a href="http://www.daum.net" onclick="alert('OK!'); return false">a 태그의 기본 동작 취소 1</a><br>
<!-- a 태그의 onclick에 작성할 스크립트가 많다면 별도의 함수에 작성하고 호출한다.
이때 함수의 리턴 값에 따라 a 태그의 기본 동작을 제어하는 기법이
다음 예이다. -->
<a href="http://www.daum.net" onclick="return f1()">a 태그의 기본 동작 취소 2</a><br>
<!-- 태그.onclick = 함수() {} -->
<a id="link3" href="http://www.daum.net">a 태그의 기본 동작 취소 3</a><br>
<!-- 태그.onclick = 함수() {} : preventDefault() -->
<a id="link4" href="http://www.daum.net">a 태그의 기본 동작 취소 4</a><br>
<!-- 태그.addEventListener("click", 함수() {}) -->
<a id="link5" href="http://www.daum.net">a 태그의 기본 동작 취소 5</a><br>
<!-- 태그.addEventListener("click", 함수() {}) : preventDefault() -->
<a id="link6" href="http://www.daum.net">a 태그의 기본 동작 취소 6</a><br>
<script>
"use strict"
function f1() {
alert("OK!");
return false
}
document.querySelector("#link3").onclick = function () {
alert("OK!");
return false; // false를 리턴하면 a 태그의 기본 동작을 취소한다.
};
document.querySelector("#link4").onclick = function (e) {
e.preventDefault(); // a 태그의 기본 동작을 비활성화시킨다. 리스너 호출이 끝난 후 서버에 요청하지 않는다.
alert("OK!");
};
document.querySelector("#link5").addEventListener("click", function () {
alert("OK!");
return false; // addEventListener()로 함수를 등록하면
// return 값으로 a 태그의 기본 동작을 취소할 수 없다.
});
document.querySelector("#link6").addEventListener("click", function (e) {
// addEventListener()로 함수를 등록한다면
// Event.preventDefault()를 사용하여 a 태그의 기본 동작을 취소해야 한다.
e.preventDefault();
alert("OK!");
});
이벤트 - form의 submit 버튼 만들기
button에 type 지정하지 않으면 기본은 submit 이다.
<form action="https://www.daum.net">
<input type="text" name="title">
<button>전송1</button>
</form>
<form action="https://www.daum.net">
<input type="text" name="title">
<button type="submit">전송2</button>
</form>
<form action="https://www.daum.net">
<input type="text" name="title">
<input type="submit" value="전송3">
</form>
이벤트 - form의 submit 동작을 중단시키기
- form 태그에 onsubmit="return false" 옵션을 추가한다.
- js에서 해당 객체 submit시 실행되는 함수에 return false 입력하기
- js에서 해당 객체 submit시 실행되는 함수에 preventDefault() 입력하기. addEventListener 사용시 이 방법만이 중지시킬수 있다. - 가급적 이 방법 사용
<p>form의 submit 버튼을 클릭하면 서버에 요청을 한다.</p>
<form action="https://www.daum.net" onsubmit="return false">
<input type="text" name="title">
<button>전송 막기1</button>
</form>
<form action="https://www.daum.net" id="form2">
<input type="text" name="title">
<button>전송 막기2</button>
</form>
<form action="https://www.daum.net" id="form3">
<input type="text" name="title">
<button>전송 막기3</button>
</form>
<form action="https://www.daum.net" id="form4">
<input type="text" name="title">
<button>전송 막기4</button>
</form>
<form action="https://www.daum.net" id="form5">
<input type="text" name="title">
<button>전송 막기5</button>
</form>
<form action="https://www.daum.net" id="form6">
<input type="text" name="title">
<!-- 일반 버튼은 서버에 전송을 수행하지 않는다. -->
<button type="button">전송 막기6</button>
<input type="button" value="전송 막기6">
</form>
<script>
"use strict"
// "submit" 이벤트가 발생했을 때 호출될 리스너를 등록한다.
// "submit" 이벤트는 언제 발생하는가?
// - submit 버튼을 클릭할 때 발생한다!
//
document.querySelector("#form2").onsubmit = () => {
return false;
};
document.querySelector("#form3").onsubmit = (e) => {
e.preventDefault();
};
document.querySelector("#form4").addEventListener("submit", (e) => {
e.preventDefault();
});
document.querySelector("#form5").addEventListener("submit", (e) => {
return false; // addEventListener()로 이벤트 핸들러를 등록할 때는
// return false 가 의미없다. 동작되지 않는다.
// 반드시 e.preventDefault()를 호출하라!
});
이벤트 - form 데이터 검증
1. return false로 서버에 제출 막기
<form id="form1" action="http://www.daum.net">
이름(*): <input type="text" id="name1" name="username"><br>
<button>전송</button>
</form>
<script>
"use strict"
document.querySelector("#form1").onsubmit = () => {
// submit 타입의 버튼을 클릭하면 onsubmit 으로 등록한 함수가 호출된다.
// 여기에서 입력 폼 값을 검증하는 일을 한다.
//
var name = document.querySelector("#name1");
if (name.value == "") {
alert("필수 입력 항목이 비어 있습니다.");
return false; // false를 리턴하면 입력 폼의 값을 서버에 제출하지 않는다.
// 즉 HTTP 요청을 수행하지 않는다.
}
// true를 리턴하거나 아무것도 리턴하지 않으면 원래대로
// 입력 폼의 값을 서버에 제출한다. 즉 HTTP 요청을 수행한다.
};
2. 일반 버튼에 onclick 사용. return ; 로 서버에 제출 막기
<form id="form2" action="http://www.daum.net">
이름(*): <input type="text" id="name2"><br>
<button id="btn2" type="button" name="username">전송</button>
</form>
<script>
"use strict"
document.querySelector("#btn2").onclick = () => {
var name = document.querySelector("#name2");
if (name.value == "") {
alert("필수 입력 항목이 비어 있습니다.");
return; // submit 버튼이 아니라 일반 버튼이기 때문에 false를 리턴할 필요가 없다.
}
// 일반 버튼을 클릭했을 때 입력 폼의 값을 서버에 제출하려면
// form 태그 객체에 대해 submit() 함수를 호출하라!
//
document.querySelector("#form2").submit();
}
3. preventDefault() 로 서버에 제출 막기 - 가급적 이 방법 사용
<form id="form3" action="http://www.daum.net">
이름(*): <input type="text" id="name3"><br>
<button id="btn3">전송</button>
</form>
<script>
"use strict"
document.querySelector("#form3").addEventListener("submit", (e) => {
console.log("okok!");
var name = document.querySelector("#name3");
if (name.value.length < 2) {
alert("2자 이상을 입력하세요.");
//return false; // addEventListener()로 등록한 경우 return false는 안 먹힌다.
e.preventDefault();
return;
}
});
조언
*알고리즘 책 사서 얆은 거 스터디 한 다음에 백준 사이트 가서 문제 풀면서 '2년 후 네카라쿠배 가겠다' 생각하라. 문제 풀면서 소회를 깃에 남겨라.
과제
/
'네이버클라우드 AIaaS 개발자 양성과정 1기 > Javascript' 카테고리의 다른 글
[Javascript] getElement 메서드 비교 (0) | 2022.12.15 |
---|---|
[비트캠프] 29일차(6주차4일) - AJAX 개요 (0) | 2022.12.15 |
[비트캠프] 27일차(6주차2일) - Javascript(캡슐화, DOM API: 태그 찾기, 알아내기, 속성 변경, 추가, 변경, 삭제) (0) | 2022.12.13 |
[비트캠프] 26일차(6주차1일) - Javascript(객체, 프로퍼티, 생성자) (0) | 2022.12.12 |
[비트캠프] 25일차(5주차5일) - Javascript(함수, 비동기, 주요함수, JSON) (0) | 2022.12.09 |