DOMContentLoaded 이벤트
로딩 이후에 자바스크립트 동작이 이뤄지는것이 일반적입니다. 자바스크립트가 실행되어야 할 가장 적절한 타이밍은 언제인지 아래의 표를 보겠습니다.
load 와 DOMContentLoaded의 차이 확인
화면 로딩 시점 | 이벤트 발생 시점 |
DOM Tree 분석 종료시 | DOMContentLoaded 이벤트 발생 |
그외 모든 자원(image, script, css)이 다 받아져서 브라우저에 렌더링(화면 출력) 완료시 | load 이벤트 발생 |
보통 DOM tree가 다 만들어지면 DOM APIs를 통해서 DOM에 접근할 수 있기때문에 실무에서는 대부분의 자바스크립트코드는 DOMContentLoaded 이후에 동작하도록 구현합니다. 이 방법이 로딩속도 성능에 유리하다고 생각하기 때문입니다.
Event delegation
delegation은 위임 이라는 뜻을 가지고 있습니다.
하위 요소에 각각 이벤트를 붙이지 않고 상위요소에서 하위요소의 이벤트를 제어하는 방식 입니다.
이것은 곧 Event Bubling 과 Event Capturing 과 연관된 개념입니다.
이벤트 버블링 (Bubbling) :이벤트 버블링은 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성을 의미합니다.
이벤트 캡쳐링 (Capturing) : 이벤트 캡쳐링은 버블링과 반대 방향으로 진행되는 이벤트를 의미합니다.
<ul>
<li>
<img src="https://images-na.ssl-images-amazon.com/images/I/513hgSybYgL._AC_SY400_.jpg" class="product-image" >
</li>
<li>
<img src="https://images-na.ssl-images-amazon.com/images/I/41HoczBHr2L._AC_SY400_.jpg" class="product-image" >
</li>
<li>
<img src="https://images-na.ssl-images-amazon.com/images/I/51AEI3isFiL._AC_SY400_.jpg" class="product-image" >
</li>
<li>
<img src="https://images-na.ssl-images-amazon.com/images/I/51JVp8YV3ZL._AC_SY400_.jpg" class="product-image" >
</li>
</ul>
ul.addEventListener("click",function(evt) {
console.log((evt.target.src);
});
ul 태그에만 이벤트를 등록했습니다. 이럴경우 li 를 클릭하거나 이미지를 클릭하더라도 모두 동일하게 동작합니다. li 나 img 태그 모두 ul 태그에 속하며 하위엘리먼트 입니다. 클릭한 지점이 하위 엘리먼트라고 하여도 그것을 감싸고 있는 상위 엘리먼트까지 올라가면서 이벤트리스너가 있는지 찾는 과정이 Bubbling 입니다. 기본적으로 버블링 순서로 이벤트가 발생합니다.
이와 반대로 Capturing 순서로 이벤트가 발생하기도 하는데, addEventListener메서드의 3번째 인자에 값을 true 로 주면 됩니다.
img 태그와 li 태그 사이에 공백을 클릭하면? undefinde 가 출력됩니다. 공백을 클릭하더라도 img src값이 출력되게 하려면 어떻게 해야할까?
var ul = document.querySelector("ul");
ul.addEventListener("click",function(evt) {
if(evt.target.tagName === "IMG") {
console.log("clicked" + evt.target.src);
} else if (evt.target.tagName === "LI") {
console.log("clicked" + evt.target.firstChild.src);
}
});
공백 클릭시 반응하지 않고, img 태그나 li 태그 클릭시 src 값을 출력할 수 있도록 조건을 위와같이 제한해주면 됩니다.
HTML templating
Ajax를 통해 서버로부터 JSON 데이터를 받아 화면에 출력해야 되는 경우, 반복적인 HTML부분을 template로 만들어두고, 서버에서 온 데이터를 결합해 화면에 추가하는것이 HTML templating 이라고 합니다.
JSON 과 HTML template 결합하기
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<ul class="box">
<li>제목: 기묘한 이야기</li>
<li>제작: 더퍼 형제</li>
<li>장르: SF</li>
</ul>
<button class="btn">버튼</button>
</body>
</html>
<script type="rv-template" id="itemList">
<ul class="box">
<li>제목: {title}</li>
<li>제작: {producer}</li>
<li>장르: {genre}</li>
</ul>
</script>
//JSON 데이터
var data = { title : "워킹데드",
producer : "AMC 스튜디오",
genre : "좀비 아포칼립스"
};
var btn = document.querySelector(".btn");
btn.addEventListener("click", function (evt) {
var html = document.getElementById("itemList").innerHTML;
var resultHTML = "";
resultHTML = html.replace("{title}", data.title)
.replace("{producer}", data.producer)
.replace("{genre}", data.genre);
document.querySelector(".box").innerHTML = resultHTML;
});
See the Pen HTML templating by So-Jeong (@sojeong1010) on CodePen.
https://www.edwith.org/boostcourse-web/lecture/16752/
https://www.edwith.org/boostcourse-web/lecture/16753/