
이벤트는 왜 필요한가
JavaScript는 화면 안에서 일어나는 변화에 반응하면서 동작한다.
버튼을 눌렀을 때, 마우스를 올렸을 때, 문서가 모두 준비되었을 때처럼 어떤 순간이 생기면 그에 맞는 코드를 실행한다.
이때 그 순간을이벤트라고 한다.
웹 페이지를 움직이게 만들려면 결국이벤트를 다룰 줄 알아야 한다.
화면 요소를 그냥 보여주는 것에서 끝나는 것이 아니라, 사용자의 행동에 따라 내용이 바뀌고 색이 바뀌고 화면 일부가 바뀌게 하려면이벤트가 필요하다.
즉, 이번 범위는 웹 페이지를 “반응하게 만드는 시작점”을 배우는 구간이라고 보면 된다.
이벤트를 이루는 기본 요소
event는 실제로 발생한 사건이다.
event target은 그 사건이 일어난 대상이다.
event type은click,load,mouseover,submit처럼 사건의 종류이다.
event handler는 그 사건이 발생했을 때 실행되는 함수이다.
이 네 가지를 같이 보면 흐름이 보인다.
어디에서 일이 일어났는지 확인한다.
무슨 종류의 일인지 확인한다.
그다음 그때 어떤 함수를 실행할지를 정한다.
가장 먼저
load를 이해해야 하는 이유초보자가 자주 헷갈리는 부분은 코드가 언제 실행되는가이다.
문서가 아직 다 만들어지지 않았는데DOM객체를 찾으려고 하면 원하는 요소를 찾지 못할 수 있다.
그래서 문서가 모두 준비된 뒤 실행해야 하는 코드는load이벤트에 연결하는 경우가 많다.
즉,load는 화면이 준비된 뒤 시작점을 만들어 주는 이벤트라고 이해하면 된다.
이 흐름을 알아야 왜 뒤에서window.onload나addEventListener("load", ...)를 쓰는지도 자연스럽게 이어진다.
예를 들어 아래 코드는 문서가 모두 로드된 뒤 오늘 요일을 계산해서 알림창을 띄운다.// exam4.html <body onload="window.alert('반갑습니다!! 오늘은 즐거운 ' + getKorDay() + '욜입니다.')"> <h1>로드 이벤트를 테스트 합니다.</h1> <script> function getKorDay() { // 요일 이름을 배열로 준비 let kordayname = ["일", "월", "화", "수", "목", "금", "토"]; // 오늘 요일 번호에 맞는 값을 꺼내서 반환 return kordayname[new Date().getDay()]; } </script> </body>// 출력결과 // 페이지가 모두 준비된 뒤 // "반갑습니다!! 오늘은 즐거운 O욜입니다." 형태의 알림창이 뜬다이 예제의 핵심은 문서가 다 준비된 뒤에 코드가 실행된다는 점이다.
즉,load이벤트는 실행 시점을 안전하게 맞춰 주는 역할을 한다.
이제 여기서 중요한 점은, 같은이벤트라도 연결하는 방식이 여러 가지라는 것이다.
이 차이를 알아야 이후 예제들이 왜 따로 나뉘어 있는지 이해할 수 있다.
이벤트 모델 3가지는 어떻게 다른가
이벤트를 연결하는 방법은 하나가 아니다.
이번 범위에서는인라인 이벤트 모델,고전 이벤트 모델,표준 이벤트 모델세 가지를 구분해서 봐야 한다.
겉으로는 비슷해 보여도 실제 동작 방식과 관리 방식이 다르다.
인라인 이벤트 모델
인라인 이벤트 모델은 태그 안에 바로onclick,onload,onmouseover같은 속성을 적는 방식이다.
태그를 보는 순간 어떤 함수가 실행되는지 바로 보인다는 점에서는 단순하다.
하지만 구조와 동작이 한 줄에 섞인다.
그래서 코드가 길어질수록 읽기 불편해진다.
고전 이벤트 모델
고전 이벤트 모델은 먼저DOM객체를 찾고, 그 객체의onclick,onmouseover같은 속성에 함수를 대입하는 방식이다.
이 방식은 태그 안에 직접 코드를 쓰지 않아도 된다.
그래서인라인보다 화면 구조와 동작을 조금 더 분리해서 볼 수 있다.
하지만 같은 이벤트 속성에는 함수 하나만 들어간다.
즉, 같은 요소의 같은 이벤트에 다른 함수를 다시 넣으면 이전 함수는 사라진다.
이 점이 뒤에서표준 이벤트 모델과 비교할 때 가장 중요하다.
표준 이벤트 모델
표준 이벤트 모델은addEventListener()를 사용해서 이벤트를 등록하는 방식이다.
이 방식은 같은 요소에 같은 종류의 핸들러를 여러 개 붙일 수 있다.
또 해제할 때도removeEventListener()를 사용해서 따로 관리할 수 있다.
그래서 기능을 분리해서 다루기 쉽고, 확장하기도 더 좋다.
같은 버튼에 핸들러를 두 번 연결하면 차이가 더 잘 보인다
아래 예제는
고전 이벤트 모델과표준 이벤트 모델의 차이를 가장 분명하게 보여준다.
첫 번째 버튼은onclick에 함수를 두 번 대입한다.
두 번째 버튼은addEventListener()로 함수를 두 번 등록한다.// exam5.html var doms = document.querySelectorAll("button"); var dom1 = doms[0]; var dom2 = doms[1]; // 첫 번째 버튼: 고전 이벤트 모델 dom1.onclick = function () { // 첫 번째 핸들러 alert("첫 번째 핸들러 수행(고전)"); }; dom1.onclick = function () { // 같은 속성에 다시 넣어서 이전 핸들러를 덮어씀 alert("두 번째 핸들러 수행(고전)"); }; // 두 번째 버튼: 표준 이벤트 모델 dom2.addEventListener("click", function () { // 첫 번째 핸들러 등록 alert("첫 번째 핸들러 수행(표준)"); }); dom2.addEventListener("click", function () { // 두 번째 핸들러도 함께 등록 alert("두 번째 핸들러 수행(표준)"); });// 출력결과 // 첫 번째 버튼 클릭 시 // 두 번째 핸들러 수행(고전) // // 두 번째 버튼 클릭 시 // 첫 번째 핸들러 수행(표준) // 두 번째 핸들러 수행(표준)
고전 이벤트 모델은 다시 대입하면 이전 핸들러가 덮어써지고,표준 이벤트 모델은 여러 핸들러를 함께 유지할 수 있다.
처음 보면 비슷해 보여도 실제 동작은 다르다.
이 차이는 꼭 구분해서 봐야 한다.
해제 방식도 다르다
이 차이는 이벤트를 없앨 때 더 분명하게 보인다.
고전 이벤트 모델은btn1.onmouseover = null;처럼 속성값을 비워서 해제한다.
반면표준 이벤트 모델은removeEventListener()로 등록했던 함수를 지정해서 해제한다.
즉, 등록 방식이 다른 만큼 해제 방식도 다르다.
정리하면인라인은 태그 안에 직접 연결하는 방식이다.
고전은 이벤트 속성 하나에 함수 하나를 넣는 방식이다.
표준은 여러 핸들러를 독립적으로 등록하고 해제할 수 있는 방식이다.
이벤트 객체와 this는 어떻게 봐야 하는가
이벤트가 발생하면 함수만 실행되는 것이 아니다.
그 사건이 어디서 일어났는지, 어떤 대상에서 일어났는지에 대한 정보도 함께 전달된다.
그래서이벤트 객체를 이해하면 단순한 클릭 처리에서 끝나지 않고, 클릭한 대상의 정보에 맞춰 화면을 바꾸는 코드까지 만들 수 있다.
this와e.target은 완전히 같은 것이 아니다처음 보면
this와e.target은 비슷해 보인다.
둘 다 지금 클릭한 대상처럼 느껴지기 때문이다.
하지만 정확히는 다르다.
this는 핸들러가 연결된 객체를 기준으로 본다.
e.target은 실제로 이벤트가 발생한 대상을 기준으로 본다.
둘이 같은 경우도 많다.
하지만 이벤트가 퍼지는 상황에서는 달라질 수 있다.
그래서 두 값을 구분해서 보는 습관이 중요하다.
클릭한 버튼의 정보를 읽어서 화면을 바꾸는 흐름
아래 예제는 버튼을 누를 때
this와e.target의 정보를 각각 확인하고, 버튼의 글자와 사용자 정의 속성값을 읽어서 제목 내용을 바꾸는 흐름을 보여 준다.// exam6_1.html function click_processing(e) { // 핸들러가 연결된 객체 정보 확인 window.alert(this.id); window.alert(this.textContent); // 실제 이벤트가 발생한 객체 정보 확인 window.alert(e.target.id); window.alert(e.target.textContent); // 첫 번째 h1 요소 찾기 let h1dom = document.getElementsByTagName("h1")[0]; // 클릭한 버튼의 글자를 제목으로 반영 h1dom.textContent = e.target.textContent; // 버튼의 data-mycolor 값을 읽어서 제목 색상 변경 h1dom.style.color = e.target.getAttribute("data-mycolor"); } var btn1 = document.querySelector("#b1"); var btn2 = document.getElementById("b2"); // 고전 이벤트 모델로 연결 btn1.onclick = click_processing; // 표준 이벤트 모델로 연결 btn2.addEventListener("click", click_processing);// 출력결과 // 버튼 클릭 시 // 연결된 버튼 정보와 실제 클릭된 버튼 정보를 확인할 수 있다 // h1 제목이 버튼의 글자로 바뀌고 // 제목 색도 data-mycolor 값에 맞게 바뀐다이 예제의 핵심은
이벤트가 단순히 함수를 실행만 시키는 것이 아니라, 어디서 일이 일어났는지에 대한 정보도 함께 준다는 점이다.
그래서 버튼의 글자,id, 속성값을 읽어서 화면을 바꿀 수 있다.
기본 동작을 막는 것도 중요한 이벤트 처리이다
링크를 클릭하면 페이지가 이동하는 것은
a태그의 기본 동작이다.
하지만 어떤 경우에는 이동하지 않고 내가 만든 코드만 실행하고 싶을 수 있다.
이럴 때 기본 동작을 막는다.
인라인과고전에서는return false를 사용할 수 있다.
표준 이벤트 모델에서는e.preventDefault()를 사용한다.
둘 다 목적은 같다.
원래 하던 동작을 멈추는 것이다.// exam7.html function test1() { // 인라인 방식에서 실행할 함수 alert("인라인이벤트모델 버튼 클릭"); } function test2() { // 고전 방식에서 실행할 함수 alert("고전이벤트모델 버튼 클릭"); // 기본 이동 막기 return false; } function test3(e) { // 표준 방식에서 기본 이동 막기 e.preventDefault(); alert("표준이벤트모델 버튼 클릭"); }// 출력결과 // 링크 클릭 시 알림창이 뜬다 // 그리고 페이지는 이동하지 않는다즉,
이벤트처리에는 실행뿐 아니라 제어도 들어 있다.
무언가 일어났을 때 어떤 코드를 실행할지 정할 뿐 아니라, 원래 브라우저가 하려고 하던 동작을 계속할지 멈출지도 결정할 수 있다.
DOM은 무엇이고 어떻게 찾는가
DOM은 화면에 있는HTML요소를JavaScript가 객체처럼 다룰 수 있게 만든 구조이다.
그래서 제목 글자를 바꾸고, 색을 바꾸고, 이미지를 교체하는 작업이 가능해진다.
쉽게 말하면, 화면 요소를 자바스크립트에서 만질 수 있도록 바꿔 둔 구조라고 보면 된다.
DOM객체를 찾는 대표 방법이번 범위에서 자주 나온 방법은 네 가지이다.
getElementById()는id하나를 기준으로 찾는다.
getElementsByTagName()은 태그 이름으로 여러 개를 찾는다.
querySelector()는CSS선택자 방식으로 하나를 찾는다.
querySelectorAll()은 선택자에 맞는 여러 개를 찾는다.
찾는 방식은 다르지만 목적은 같다.
내가 바꾸고 싶은 화면 요소를 정확히 찾는 것이다.
찾은 뒤에는 읽고, 그다음 수정한다
아래 예제는
h1태그들을 찾아서 내용을 읽고, 나중에는id로 다시 찾아서 5초 뒤 글자와 스타일을 바꾸는 흐름을 보여 준다.// exam8_1.html let dom = document.getElementsByTagName("h1"); // h1 태그 목록 확인 writeNewLine(dom); // h1 태그 개수 확인 writeNewLine(dom.length); // 첫 번째 h1의 글자 내용 확인 writeNewLine(dom[0].textContent); // 첫 번째 h1의 내부 구조 확인 writeNewLine(dom[0].innerHTML); dom = document.getElementById("test"); // id가 test인 요소의 현재 글자 확인 writeNewLine(dom.textContent); window.setTimeout(function() { // 5초 뒤 글자 내용 변경 dom.textContent = "오늘은 월요일"; // 글자색 변경 dom.style.color = "red"; // 배경색 변경 dom.style["background-color"] = "yellow"; }, 5000);// 출력결과 // h1 태그 목록과 개수가 출력된다 // 첫 번째 h1의 텍스트와 내부 내용이 출력된다 // 5초 뒤 id가 test인 h1의 글자와 색상이 바뀐다이 흐름은 아주 중요하다.
먼저 찾는다.
그다음 읽는다.
마지막으로 수정한다.
이 순서를 잡고 보면 이후 예제들도 훨씬 쉽게 읽힌다.
같은 기능도 찾는 방식은 달라질 수 있다
제목 바꾸기, 제목 색 바꾸기, 이미지 바꾸기처럼 보이는 결과는 같아도 내부 구현 방식은 다를 수 있다.
어떤 예제는id로 찾고, 어떤 예제는 태그 이름으로 찾고, 어떤 예제는 선택자로 찾는다.
하지만 찾은 뒤에는 결국textContent,style,src를 바꾼다.
아래 예제는querySelector()를 사용해서 제목과 이미지를 찾고, 버튼 클릭에 따라 제목, 색상, 이미지를 바꾸는 흐름을 보여 준다.// exam12_3.html function updateTitle() { // 첫 번째 h1 선택 const dom = document.querySelector("h1"); // 사용자에게 새 제목 입력받기 const msg = window.prompt("제목을 입력하세요"); // 제목 내용 변경 dom.textContent = msg; } function updateColor() { // 첫 번째 h1 선택 const dom = document.querySelector("h1"); // 무작위 색상 코드 만들기 const colorCode = "#" + Math.round(Math.random() * 0xffffff).toString(16); // 제목 색상 변경 dom.style.color = colorCode; } function updateImage() { // src 속성이 있는 이미지 선택 const dom = document.querySelector("[src]"); // 1~10 사이 이미지 번호 만들기 const imageName = Math.floor(Math.random() * 10) + 1; // 이미지 파일 경로 변경 dom.src = "../../images/" + imageName + ".jpg"; } const doms = document.getElementsByTagName("button"); // 첫 번째 버튼 클릭 시 제목 변경 doms[0].addEventListener("click", updateTitle); // 두 번째 버튼 클릭 시 제목 색 변경 doms[1].addEventListener("click", updateColor); // 세 번째 버튼 클릭 시 이미지 변경 doms[2].addEventListener("click", updateImage);// 출력결과 // 첫 번째 버튼 클릭 시 제목이 입력값으로 바뀐다 // 두 번째 버튼 클릭 시 제목 색이 무작위로 바뀐다 // 세 번째 버튼 클릭 시 이미지가 다른 파일로 바뀐다
DOM을 찾는 방법은 여러 가지지만, 찾은 뒤에는 결국 내용, 스타일, 속성을 바꾸는 흐름으로 이어진다.
그래서 선택 방법만 따로 외우는 것이 아니라, 찾고 바꾸는 전체 흐름으로 이해하는 것이 더 중요하다.
여러 요소를 한꺼번에 처리할 수도 있다
querySelectorAll()을 사용하면 여러 요소를 한 번에 가져올 수 있다.
그다음forEach()로 반복 처리하면 같은 동작을 여러 요소에 적용할 수 있다.
아래 예제는.target클래스를 가진 요소들을 모두 찾아서 2초마다 색을 함께 바꾸고,output태그에는 현재 요일을 넣는다.// exam10.html const doms = document.querySelectorAll(".target"); window.setInterval(function() { // 무작위 색상 코드 생성 var colorCode = "#" + Math.round(Math.random() * 0xffffff).toString(16); // 선택된 모든 요소의 글자색 변경 doms.forEach(function(elem) { elem.style.color = colorCode; }); }, 2000); const kordayname = ["일", "월", "화", "수", "목", "금", "토"]; // output 태그에 현재 요일 넣기 document.getElementsByTagName("output")[0].textContent = kordayname[new Date().getDay()];// 출력결과 // 2초마다 target 클래스를 가진 요소들의 색이 함께 바뀐다 // output 태그에는 현재 요일이 표시된다즉,
DOM제어는 하나만 바꾸는 기능이 아니라, 여러 요소를 묶어서 한 번에 처리하는 기능으로도 이어진다.
이벤트를 어떻게 쓰는가
이벤트는 버튼 클릭에만 쓰이는 기능이 아니다.
선택값이 바뀔 때, 폼을 전송할 때, 화면 일부를 바꾸고 싶을 때도 모두이벤트가 사용된다.
즉, 사용자의 입력 흐름을 실제 동작으로 연결하는 구간에서도이벤트는 계속 등장한다.
change이벤트로 선택값에 따라 이동하기버튼을 눌렀을 때만 이벤트가 일어나는 것은 아니다.
선택 목록에서 항목을 바꿀 때도change이벤트가 발생한다.
아래 예제는select에서 선택이 바뀌면 그 값에 들어 있는 주소로 이동한다.// exam13.html function go() { // 현재 선택된 option의 value 읽기 location.href = document.getElementById("choice").value; }// 출력결과 // select에서 항목을 선택하면 // 해당 value 주소로 페이지가 이동한다이 예제의 핵심은 선택 변화도 이벤트로 처리할 수 있다는 점이다.
즉, 사용자의 선택 자체가 화면 동작의 시작점이 될 수 있다.
submit이벤트는 전송 직전에 발생한다폼을 전송하면
submit이벤트가 발생한다.
이 시점은 입력값을 마지막으로 확인하거나 검사하기에 좋다.
아래 예제는 이름과 나이를 입력한 뒤 전송할 때, 입력값을 먼저 읽어서 알림창으로 보여 준다.// exam14.html document.querySelector("form").addEventListener("submit", function() { // 이름 입력값 읽기 const name = document.querySelector("[type='text']").value; // 나이 입력값 읽기 const age = document.querySelector("[type='number']").value; // 확인용 문자열 만들기 const content = `이름 : ${name}, \n나이 : ${age}`; // 전송 전에 사용자에게 확인 window.alert(content); });// 출력결과 // 폼 전송 시 // "이름 : 입력값, 나이 : 입력값" 형태의 알림창이 뜬다이 예제에서는
required속성도 함께 봐야 한다.
required는 브라우저가 기본적으로 빈 입력을 막아 준다.
즉,HTML만으로도 기본 검사를 할 수 있고, 필요하면JavaScript이벤트 처리로 확인 과정을 더 붙일 수 있다.
버튼 클릭으로 화면 일부만 바꾸는 것도 중요한
DOM활용이다아래 예제는 방명록 화면에서 버튼을 누를 때마다 다른 영역만 보이게 만드는 구조이다.
먼저section안의 모든article을 숨긴다.
그다음 필요한article하나만 다시 보이게 만든다.
즉, 페이지 전체를 새로 바꾸는 것이 아니라 현재 화면 안에서 필요한 부분만 전환하는 것이다.// exam15.html function displayTag(target) { // section 안의 모든 article 숨기기 document.querySelectorAll("section > *").forEach(function(elem) { elem.style.display = "none"; }); // 전달받은 id에 해당하는 article 찾기 let dom = document.querySelector("#" + target); // 필요한 article만 다시 보이게 만들기 dom.style.display = "block"; }// 출력결과 // "방명록 리스트 보기" 클릭 시 리스트 영역만 보인다 // "방명록 작성하기" 클릭 시 작성 영역만 보인다 // "방명록 검색하기" 클릭 시 검색 영역만 보인다이 예제는 나중에 탭 메뉴나 모달 전환을 이해할 때도 그대로 이어진다.
여러 요소를 한 번에 선택하고, 공통 처리를 하고, 그 뒤 필요한 것만 다시 보여 주는 흐름이기 때문이다.
이벤트 버블링은 왜 알아야 하는가
이벤트는 한 요소에서만 끝나는 것이 아니다.
안쪽 요소에서 발생한 이벤트가 바깥쪽 부모로 전달될 수 있다.
이 흐름을 이해하지 못하면 한 번 클릭했는데 왜 여러 함수가 실행되는지 헷갈리게 된다.
안쪽에서 발생한 이벤트가 바깥으로 올라간다
중첩된 구조 안에서 가장 안쪽 요소를 클릭했는데, 부모 요소의 이벤트까지 함께 실행되는 경우가 있다.
이것이이벤트 버블링이다.
즉, 안쪽 요소에서 발생한 이벤트가 바깥쪽 부모로 전달되는 흐름이다.
처음 보면 한 번 눌렀는데 왜 여러 함수가 실행되는지 이상하게 느껴질 수 있다.
하지만 실제로는 이벤트가 위쪽으로 계속 전달되고 있는 것이다.
target과currentTarget을 같이 봐야 흐름이 보인다버블링에서는
e.target과e.currentTarget을 함께 보는 것이 중요하다.
target은 실제로 클릭된 요소이다.
currentTarget은 지금 실행 중인 핸들러가 붙어 있는 요소이다.
즉, 클릭한 곳과 현재 처리 중인 곳이 다를 수 있다.// exam8.html function displayAlert(e) { // 실제 클릭된 요소와 현재 처리 중인 요소를 함께 보여 줌 window.alert( `${e.target.nodeName} 태그 에서 ${e.type} 이벤트 발생!! --- ${e.currentTarget.nodeName} 태그가 이벤트 처리 위임받음` ); }// 출력결과 // h1을 클릭하면 // h1 기준 메시지가 뜨고 // 이어서 div, section, body까지 차례대로 처리될 수 있다이 예제를 보면 클릭은
h1에서 했는데, 부모 요소에 연결한 핸들러도 함께 반응할 수 있다는 점이 보인다.
이것이 버블링의 핵심이다.
stopPropagation()은 전파를 중간에서 끊는다부모까지 이벤트가 계속 올라가는 것이 필요 없을 때도 있다.
그럴 때stopPropagation()을 사용한다.
이 함수는 지금 처리까지만 하고 더 위로는 전달하지 않겠다는 뜻이다.// exam8_2.html function displayAlert(e) { // 현재 처리 중인 이벤트 정보 출력 window.alert( `${e.target.nodeName} 태그 에서 ${e.type} 이벤트 발생!! --- ${e.currentTarget.nodeName} 태그가 이벤트 처리 위임받음` ); // 부모로 전달되는 흐름 중단 e.stopPropagation(); }// 출력결과 // 클릭한 요소의 핸들러는 실행되지만 // 부모 요소까지 계속 전달되지는 않는다이 단계에서는 버블링을 깊게 외우기보다, 이벤트는 한 요소에서 끝나지 않고 부모 쪽으로 전달될 수 있다는 점을 이해하면 충분하다.
그리고 필요하면stopPropagation()으로 그 흐름을 끊을 수 있다고 보면 된다.
Canvas API는 어떻게 이해하면 되는가
Canvas API는 웹 페이지 안에 그림을 그릴 수 있게 해 주는 기능이다.
즉, 문서 안에 빈 그림판 같은 영역을 만들고, 그 위에JavaScript로 선, 원, 사각형 같은 모양을 직접 그리는 방식이라고 이해하면 된다.
일반HTML태그는 제목, 문단, 이미지처럼 이미 준비된 요소를 화면에 배치하는 역할을 한다.
반면Canvas는 빈 공간을 하나 만든 뒤, 그 안에 필요한 그림을 직접 그린다.
그래서DOM의 글자나 속성을 바꾸는 예제와는 읽는 흐름이 조금 다르다.
Canvas를 사용할 때 먼저 알아야 하는 흐름
Canvas는<canvas>태그만 만든다고 바로 그림이 보이는 것이 아니다.
먼저<canvas>태그로 그림을 그릴 영역을 만든다.
그다음DOM으로 그 요소를 찾는다.
그리고getContext("2d")로 2차원 그림을 그릴 도구를 꺼낸 뒤, 그 도구로 원하는 모양을 직접 그린다.
즉, 흐름은 이렇게 보면 된다.
영역을 만든다.
영역을 찾는다.
그림 도구를 꺼낸다.
그다음 원하는 도형을 그린다.
이 순서를 먼저 잡고 있어야 뒤의 예제가 자연스럽게 이해된다.
이번 범위에서 먼저 익혀야 할 메서드
이번 예제에서 먼저 봐야 할 메서드는 많지 않다.
clearRect()는 이전에 그린 그림을 지운다.
beginPath()는 새 도형 그리기를 시작한다.
arc()는 원을 그린다.
stroke()는 테두리를 그린다.
fill()은 내부를 채운다.
이 다섯 개만 이해해도 이번Canvas예제를 읽는 데는 충분하다.
처음부터 모든 메서드를 한꺼번에 외우기보다, 지우고 다시 그리고 채우는 흐름부터 익히는 것이 더 중요하다.
Canvas예제는 이런 흐름으로 읽으면 된다아래 예제는
canvas요소를 찾고,getContext("2d")로 그리기 도구를 가져온 뒤,mousemove이벤트가 발생할 때마다 이전 그림을 지우고 눈과 눈동자를 다시 그리는 구조이다.
즉, 한 번 그려 두고 끝나는 그림이 아니라, 마우스가 움직일 때마다 계속 다시 그리는 방식의 예제이다.// exam11.html function initiate() { // canvas 요소 찾기 var elem = document.getElementById("canvas"); // 2차원 그림 도구 가져오기 canvas = elem.getContext("2d"); // 마우스가 움직일 때마다 animation 실행 window.addEventListener("mousemove", animation, false); } function animation(e) { // 이전 그림 지우기 canvas.clearRect(0, 0, 300, 500); // 현재 마우스 좌표 가져오기 var xmouse = e.clientX; var ymouse = e.clientY; // 눈의 중심 좌표 지정 var xcenter = 220; var ycenter = 150; // 마우스 방향에 맞는 각도 계산 var ang = Math.atan2(xmouse - xcenter, ymouse - ycenter); // 눈동자가 이동할 좌표 계산 var x = xcenter + Math.round(Math.sin(ang) * 10); var y = ycenter + Math.round(Math.cos(ang) * 10); // 눈 테두리 그리기 canvas.beginPath(); canvas.arc(xcenter, ycenter, 20, 0, Math.PI * 2, false); canvas.moveTo(xcenter + 70, 150); canvas.arc(xcenter + 50, 150, 20, 0, Math.PI * 2, false); canvas.stroke(); // 눈동자 채우기 canvas.beginPath(); canvas.moveTo(x + 10, y); canvas.arc(x, y, 10, 0, Math.PI * 2, false); canvas.moveTo(x + 60, y); canvas.arc(x + 50, y, 10, 0, Math.PI * 2, false); canvas.fill(); } // 페이지가 모두 준비되면 초기화 함수 실행 window.addEventListener("load", initiate, false);// 출력결과 // 페이지가 로드되면 canvas가 준비된다 // 마우스를 움직일 때마다 눈동자 위치가 바뀌면서 // 마치 눈이 마우스를 따라보는 것처럼 보인다이 예제는 순서대로 읽는 것이 중요하다.
canvas를 찾는다.
그릴 도구를 꺼낸다.
mousemove이벤트를 연결한다.
마우스 좌표를 읽는다.
이전 그림을 지운다.
그다음 눈과 눈동자를 다시 그린다.
즉,Canvas는 화면을 한 번 만들어 두는 방식이 아니라, 필요할 때마다 다시 그리는 방식이라고 보면 된다.
이벤트,DOM, 폼 처리, 화면 전환, 버블링,Canvas는 따로 떨어진 주제가 아니다.
이번 범위는 모두 하나의 큰 흐름으로 연결된다.
즉, 화면 안에서 어떤 일이 발생했을 때 그것을 받아서, 화면 내용을 다시 바꾸는 흐름을 배우는 구간이다.
먼저이벤트가 무엇인지 이해한다.
그다음인라인,고전,표준방식으로 이벤트를 연결하는 법을 배운다.
그리고DOM객체를 찾아서 내용, 스타일, 속성을 바꾸는 방법으로 이어진다.
이후에는 폼 전송, 링크 클릭, 화면 일부 전환처럼 실제 상호작용에 적용한다.
마지막으로 이벤트 전파와Canvas처럼 더 동적인 처리까지 확장된다.
즉, 이번 범위의 핵심은JavaScript가 화면 안에서 일어난 사건을 받아서,DOM이나Canvas를 통해 그 결과를 다시 화면에 반영하는 흐름을 익히는 것이다.
이 흐름을 잡고 있으면 각 예제가 따로 노는 것이 아니라 하나의 줄기로 보인다.
핵심만 짧게 다시 정리하면,이벤트는 실행 시점을 만들고,DOM은 바꿀 대상을 찾게 해 주며,이벤트 객체는 무엇이 일어났는지 알려 주고,Canvas는 그림까지 직접 바꾸게 해 주는 기능이다.
그래서 이번 단원은 웹 페이지를 단순히 보여주는 단계에서 벗어나, 실제로 반응하고 움직이게 만드는 첫 단계라고 보면 된다.