특히 웹 애플리케이션에서는 화면상에 나타나는 요소를 옮기거나 웹 브라우저와 다른 웹 브라우저 간의 자료를 전달하기 위해 사용됨
끌기 할 요소에 draggable 속성과 끌기 관련 이벤트인 dragstart, dragend, drag 이벤트 처리
놓기 영역 요소에는 dragenter, dragover, dragleave 이벤트 처리
놓기 영역에 요소를 끌어다 놓을 경우 drop 이벤트 발생
끌기 이벤트
dragstart : 요소를 끌기 시작했을 때 발생
drag : 요소를 끌기 도중에 발생
dragend : 요소를 끌기 끝났을 때 발생
<div id="imgs">
<!-- 기본 값은 draggable="true" -->
<img id="img1" class="image" src="../resources/images/pikachu.png" draggable="false">
<img id="img2" class="image" src="../resources/images/pikachu.png" draggable="true">
</div>
<div id="div1" class="div"></div>
<script>
// img 2개를 감싸는 div
let src = document.getElementById('imgs');
// 결과 출력용 div
let div1 = document.getElementById('div1');
// drag를 하고 있으면 계속 drag 이벤트가 호출 되므로
// 이를 막기 위해 한 번만 호출 되도록 변수로 컨트롤
let isDragging;
// src에 dragstart 이벤트가 일어났을 때
src.ondragstart = function(e){
div1.insertAdjacentHTML('beforeend', 'dragstart : ' + e.target.id + "<br>");
isDragging = false;
}
// src에 drag 이벤트가 일어났을 때
src.ondrag = function(e){
if(!isDragging){
div1.insertAdjacentHTML('beforeend', 'drag : ' + e.target.id + "<br>");
isDragging = true;
}
}
// src에 dragend 이벤트가 일어났을 때
src.ondragend = function(e){
div1.insertAdjacentHTML('beforeend', 'dragend : ' + e.target.id + "<br>");
}
</script>
놓기 이벤트
dragenter : 끌기한 요소가 놓기 영역으로 들어왔을 때 발생
dragover : 끌기한 요소가 놓기 영역에 있을 때 발생
dragleave : 끌기한 요소가 놓기 영역을 떠날 때 발생
drop : 끌기한 요소를 놓기할 때 발생
<img id="img3" class="image" src="../resources/images/pikachu.png">
<div id="div2" class="div"></div>
<script>
// 올려놓을 대상 div
let target = document.getElementById('div2');
// dragover를 하고 있으면 계속해서 이벤트가 호출 되므로 막기 위한 변수
let isDraggingOver;
// target에 dragenter 이벤트가 발생 했을 때
target.ondragenter = function(e) {
target.insertAdjacentHTML('beforeend', 'dragenter : ' + e.target.id + "<br>");
isDraggingOver = false;
}
// target에 dragover 이벤트가 발생 했을 때
target.ondragover = function(e) {
// HTML 요소들의 기본 값은 드롭을 받아들이지 않게 되어있어
// 드롭이 가능하도록 설정하려면 이벤트 객체의 preventDefault()
// 메소드를 호출해야 함 - 기본 값 제거
e.preventDefault();
// => 이 코드가 없으면 놓기 처리를 했을 때 drop 대신 leave 이벤트가 발생하므로
// drop 이벤트를 발생 시키기 위한 장치
if(!isDraggingOver){
target.insertAdjacentHTML('beforeend', 'dragover : ' + e.target.id + "<br>");
isDraggingOver = true;
}
}
// target에 dragleave 이벤트가 발생 했을 때
target.ondragleave = function(e) {
target.insertAdjacentHTML('beforeend', 'dragleave : ' + e.target.id + "<br>");
}
// target에 drop 이벤트가 발생 했을 때
target.ondrop = function(e) {
target.insertAdjacentHTML('beforeend', 'drop : ' + e.target.id + "<br>");
}
</script>
File Drag And Drop
<span id="droplabel">파일을 여기에 올려 놓으세요</span>
<br>
<a id="download" href="#">download file</a>
</div>
<script>
let dropbox = document.getElementById('dropbox');
// drop 이벤트 발생을 위해 div의 dragover 이벤트에 기본 이벤트 제거 호출
dropbox.addEventListener("dragover", () => event.preventDefault());
// drop 이벤트 발생 시 이벤트 핸들러 할당
dropbox.addEventListener("drop", drop);
function drop(event){
// window에 파일 drop이 일어나면 새 창이 뜨는 것 방지
event.preventDefault();
console.log(event);
let files = event.dataTransfer.files;
console.log(files);
handleFiles(files);
}
function handleFiles(files) {
let file = files[0];
// 파일명으로 span 태그 내용 변경
document.getElementById("droplabel").innerHTML = file.name + "이 올라갔습니다.";
// FileReader 객체 생성
let reader = new FileReader();
// 파일을 읽는 작업
reader.readAsDataURL(file);
// 정상적으로 읽었을 경우 수행 되는 onload 이벤트 핸들러
reader.onload = function(){
let a = document.getElementById('download');
a.download = file.name;
a.href = reader.result;
};
}
</script>
FileReader 객체는 File 또는 Blob 객체를 이용해 내용을 읽고 사용자의 컴퓨터에 저장하는 것을 가능하게 함
File 객체는 다음과 같은 것 등에서 얻는다
(1) input 태그를 이용하여 유저가 선택한 파일들의 결과로 반환 된 FileList 객체
(2) Drag And Drop으로 반환 된 DataTransfer 객체
텍스트 파일 프리뷰
읽어들이기에 성공 했을 때 호출 되는 이벤트 핸들러 정의 : 변수.onload = function( ) {
<h3>텍스트 파일 프리뷰</h3>
<input type="file" id="txtfile">
<pre id="txtArea">텍스트 파일 내용 출력 영역</pre>
<script>
// 파일 첨부 태그에 변화가 있을 때
document.getElementById('txtfile').addEventListener('change', function(){
console.log(this);
console.log(this.files);
console.log(this.files[0]);
// 만약 txtfile에 파일이 존재한다면
if(this.files && this.files[0]) {
// FileReader 객체 생성
let reader = new FileReader();
// 텍스트 파일로 읽기
reader.readAsText(this.files[0]);
// 읽어들이기에 성공 했을 때 호출 되는 이벤트 핸들러 정의
reader.onload = function(){
console.log(reader.result);
// txtArea에 읽어온 파일의 컨텐츠 넣기, result : 파일의 컨텐츠
document.getElementById('txtArea').innerHTML = reader.result;
};
}
});
</script>
이미지 파일 프리뷰
readAsDataURL([array]) : 파일 내용을 읽어들여 dataURL 형식의 문자열로 설정
<h3>이미지 파일 프리뷰</h3>
<input type="file" id="imgfile">
<div id="imgArea"></div>
<script>
document.getElementById('imgfile').addEventListener('change', function(){
if(this.files && this.files[0]) {
let reader = new FileReader();
// 파일 내용을 읽어들여 dataURL 형식의 문자열로 설정
reader.readAsDataURL(this.files[0]);
reader.onload = function() {
console.log(reader.result);
document.getElementById('imgArea').innerHTML
= "<img src='" + reader.result + "'>";
}
}
});
</script>
텍스트 파일로 다운로드
Blob(Binary Large Object) : 이미지, 사운드, 비디오와 같은 멀티미디어 데이터를 다룸
a 태그의 download 속성은 클릭 시 href 속성의 리소스를 다운로드하게 함
<textarea id="txt" cols="100" rows="10" style="resize:none;"></textarea>
<br>
<button id="test1">텍스트 파일 다운로드</button>
<script>
document.getElementById('test1').addEventListener('click', function(){
// a 태그의 download 속성은 클릭 시 href 속성의 리소스를 다운로드하게 함
let link = document.createElement('a'); // a태그 생성
link.download = "txtfile.txt"; // download 속성 설정 및 파일명 설정
// Blob(Binary Large Object)
// : 이미지, 사운드, 비디오와 같은 멀티미디어 데이터를 다룸
// File 객체는 Blob 객체를 상속
// new Blob([문자열 또는 이진데이터], option)와 같이 생성
// textarea에 작성 된 문자열을 text 타입으로 하여 blob 객체를 생성
let blob = new Blob([document.getElementById('txt').value], {type:'text/plain'});
// FileReader 객체 생성
let reader = new FileReader();
// blob을 base64로 변환하여 읽기 설정
// (8비트 이진 데이터를 64진법으로 변환하는 인코딩 기법)
reader.readAsDataURL(blob);
// 읽어들이기에 성공했을 때 호출 되는 이벤트 핸들러
reader.onload = function(){
// a 태그의 href 속성에 읽어온 data url 설정
link.href = reader.result;
// 링크 클릭 -> 자동 다운로드
link.click();
};
});
</script>
HTML5 이전에는 응용 프로그램이 데이터를 서버에 요청할 때마다 쿠키(cookie)에 정보를 저장함
웹 스토리지는 최소 5MB 이상의 많은 공간을 가지고 있음
이 정보는 절대 서버로 전송되지 않아 <b>사용자 측에서 좀 더 많은 양의 정보를 안전하게 저장 할 수 있도록 함
웹 스토리지 종류
(1) localStorage
보관 기한이 없는 데이터를 저장함
브라우저 탭이나 창이 닫히거나, 컴퓨터를 재부팅 해도 저장 된 데이터는 사라지지 않음
(2) sessionStorage
하나의 세션만을 위한 데이터를 저장함
사용자가 브라우저 탭이나 창을 닫으면 이 객체에 저장 된 데이터는 사라짐
// 키-값 쌍을 보관함(키는 무조건 문자열)
// localStorage setItem
localStorage.academy = '국립유치원';
localStorage['class'] = '햇님반';
localStorage.setItem('teacher', '햇님이');
// 키에 해당하는 값을 받아옴
// localStorage getItem
console.log('localStorage academy : ' + localStorage.academy);
console.log('localStorage class : ' + localStorage['class']);
console.log('localStorage teacher : ' + localStorage.getItem('teacher'));
// sessionStorage도 동일한 메소드 사용
// sessionStorage setItem
sessionStorage.loginUser = '별님이';
sessionStorage['userId'] = 'star';
sessionStorage.setItem('loginDate', new Date());
// 키에 해당하는 값을 받아옴
// sessionStorage getItem
console.log('sessionStorage loginUser : ' + sessionStorage.loginUser);
console.log('sessionStorage userId : ' + sessionStorage['userId']);
console.log('sessionStorage loginDate : ' + sessionStorage.getItem('loginDate'));
<button id="removeItem">일부 데이터 삭제</button>
<button id="clearItem">전체 데이터 삭제</button>
<script>
document.getElementById('removeItem').addEventListener('click', function(){
// localStorage에서 class 데이터 삭제
localStorage.removeItem('class');
// sessionStorage에서 userId 데이터 삭제
sessionStorage.removeItem('userId');
});
document.getElementById('clearItem').addEventListener('click', function(){
// localStorage에서 전체 데이터 삭제
localStorage.clear();
// sessionStorage에서 전체 데이터 삭제
sessionStorage.clear();
});
</script>
▶ 상호 간에 정의한 규칙을 의미하며 특정 기기 간에 데이터를 주고 받기 위해 정의 ▶ 쿠키는 주로 웹 서버에 의해 만들어지며 서버가 HTTP 응답 헤더의 set-cookie에 내용을 넣어 전달하면, 브라우저는 이 내용을 자체적으로 브라우저에 저장함 ▶ 브라우저는 사용자가 쿠키를 생성하도록 한 동일 서버(사이트)에 접속할 때마다 쿠키의 내용을 Cookie 요청 헤더에 넣어서 함께 전달
Web Server
▶HTTP를 통해 웹 브라우저에서 요청하는 HTML 문서나 오브젝트(이미지 파일 등)을 전송해주는 서비스 프로그램 ▶쿠키는 클라이언트 식별과 같은 인증에 가장 많이 쓰임 ▶사용자가 로그인하면 서버는 HTTP 응답 헤더의 set-cookie에 담긴 세션 식별자 정보를 사용해 쿠키를 설정 ▶사용자가 동일 도메인에 접속하려고 하면 브라우저는 HTTP cookie 헤더에 인증 정보가 담긴 고유값(세션 식별자)을 함께 실어 서버에 요청을 보냄 ▶서버는 브라우저가 보낸 요청 헤더의 세션 식별자를 읽어 사용자를 식별 ▶document.cookie 프로퍼티를 이용하면 브라우저에서도 쿠키에 접근할 수 있음
쿠키 읽기
document.cookie는 name=value 쌍으로 구성되어 있음
각 쌍은 ;로 구분하며 쌍 하나는 하나의 독립 된 쿠키
;을 기준으로 document.cookie의 값을 분리하면 원하는 쿠키를 찾을 수 있음
쿠키 쓰기
document.cookie에 직접 값을 쓸 수 있으며 document.cookie에 값을 할당하면, 브라우저는 이 값을 받아 해당 쿠키를 갱신
다른 쿠키의 값은 변경되지 않음
쿠키의 이름과 값에는 특별한 제약이 없기 때문에 모든 글자가 허용되지만 형식의 유효성을 일관성 있게 유지하기 위해 반드시 내장함수 encodeURIComponent를 사용하여 이름과 값을 이스케이프 처리해야 함
encodeURIComponent로 인코딩 한 이후의 name=value 쌍은 4KB를 넘을 수 없음
<script>
document.forms.memberJoin.onsubmit = function(){
// 1. 아이디 검사
// 첫 글자는 반드시 영문 소문자로 시작하고
// 영문 대소문자와 숫자로만 이루어진 6~12자 사이의 값
if(!check(/^[a-z][A-Za-z\d]{5,11}$/
, document.getElementById('userid')
, "아이디는 영문 소문자로 시작하여 영문과 숫자로만 6~12자 입력"))
return false; // onsubmit의 기본 동작 제거로 제출되지 않음
};
// 유효성 검사용 함수
function check(regExp, input, msg){
// 전달 받은 정규 표현식과 사용자 입력 양식의 값이 패턴 일치할 경우
if(regExp.test(input.value))
return true;
// 전달 받은 정규 표현식과 사용자 입력 양식의 값이 패턴 일치하지 않을 경우
alert(msg);
input.value = '';
input.focus();
return false;
}
</script>
<h1>마우스 이벤트</h1>
<h3>마우스 이벤트 종류</h3>
<ul>
<li>mousedown/mouseup
: 요소 위에서 마우스 버튼을 누를 때, 마우스 버튼을
누르고 있다가 뗄 때
</li>
<li>
mouseover/mouseout
: 마우스 커서가 요소 바깥에 있다가 요소 안으로 움직일 때,
커서가 요소 위에 있다가 요소 밖으로 움직일 때
</li>
<li>
mousemove : 마우스를 움직일 때
</li>
<li>
click : 마우스 왼쪽 버튼을 사용해 동일한 요소 위에서
mousedown 이벤트와 mouseup 이벤트를 연달아 발생 시킬 때
</li>
<li>
dblclick : 동일한 요소 위에서 마우스 왼쪽 버튼을
빠르게 클릭할 때
</li>
<li>
contextmenu : 마우스 오른쪽 버튼을 눌렀을 때
</li>
</ul>
<h3>마우스 이벤트 좌표</h3>
<p>
클라이언트 좌표(clientX, clientY)<br>
: 웹 문서를 기준으로 각각 왼쪽에서 얼마나 떨어져 있는지,
위에서 얼마나 떨어져 있는지
</p>
<span>클라이언트 좌표</span>
<span id="span1">마우스를 위에 올려보세요</span>
<script>
let span1 = document.querySelector("#span1");
span1.onmouseover = () => span1.innerHTML = event.clientX + ":" + event.clientY;
</script>
<h3>선택 막기, 복사 막기</h3>
<p>
글씨 선택 막기
: mousedown 이벤트가 발생할 때 나타나는
브라우저 기본 동작 막기<br>
글씨 복사 막기
: oncopy 이벤트 기본 동작 막기
</p>
<span ondblclick="alert('클릭되었습니다');" onmousedown="return false;">
이 영역은 더블 클릭해도 선택 되지 않도록 합니다
</span>
<div oncopy="alert('복사 불가능입니다!'); return false;">
이 편지는 영국에서 최초로 시작되어 일년에 한 바퀴 돌면서
받는 사람에게 행운을 주었고 지금은 당신에게로 옮겨진 이 편지는
4일 안에 당신 곁을 떠나야 합니다. 이 편지를 포함해서 7통을
행운이 필요한 사람에게 보내 주셔야 합니다. 복사는 안됩니다.
</div>
키보드와 스크롤 이벤트
<h1>키보드 이벤트</h1>
<h3>키보드 이벤트 종류</h3>
<ul>
<li>keydown : 키를 누를 때</li>
<li>keyup : 키를 놓을 때</li>
</ul>
<h3>키보드 이벤트 테스트</h3>
<input type="text" id="content" placeholder="아무 키나 입력하세요">
<p>
event.key : 문자 <br>
event.code : 물리적인 키 코드<br>
Ex. 소문자 a를 입력하면 event.key=a event.code=KeyA<br>
대문자 A를 입력하면 event.key=A event.code=KeyA
</p>
<h1>스크롤 이벤트</h1>
<p>
마우스의 스크롤을 움직였을 때 발생하는 이벤트로 컨텐츠
내용 더보기 등에 사용할 수 있음<br>
element.scrollHeight : 요소 스크롤 뷰 높이<br>
element.scrollTop : 요소 세로 스크롤 위치<br>
element.scrollLeft : 요소 왼쪽 스크롤 위치<br>
element.clientHeight : 요소 안쪽 높이
</p>
<div class="imageArea"></div>
<script>
// 추가할 이미지 목록
let imageArr = ['pikachu.png', 'pikachu2.png', 'pikachu3.jpg'];
// div 영역
let imageArea = document.querySelector(".imageArea");
let index = 0;
// 문서 로드 시 이미지 추가
addImage(imageArr[index]);
// fileName 전달 받아 해당 이미지를 div에 추가하는 함수
function addImage(fileName){
let html = '';
for(let i = 0; i < 36; i++){
html += "<img src='../resources/images/" + fileName +"' width='100' height='100'>"
}
imageArea.innerHTML += html;
}
// 스크롤 이벤트
imageArea.addEventListener('scroll', function(){
console.log("imageArea 높이 : " + imageArea.clientHeight);
console.log("imageArea 스크롤 위치 : " + imageArea.scrollTop);
console.log("imageArea 스크롤 높이 : " + imageArea.scrollHeight);
// 스크롤바를 가장 끝까지 내렸을 떄
// 스크롤 위치 + 요소 높이 == 스크롤 높이
if(imageArea.scrollTop + imageArea.clientHeight == imageArea.scrollHeight) {
index = ++index < imageArr.length ? index : index - imageArr.length;
addImage(imageArr[index]);
}
});
</script>
폼 이벤트
<h1>폼 이벤트</h1>
<p>
document.forms : 문서에 존재하는 form들을 반환<br>
Ex. document.forms.memberJoin : name 속성이 memberJoin인 문서 내의 form<br>
Ex. document.forms[0] : 문서 내의 가장 첫 번째 form<br>
form.elements
: 해당 form 내의 name 속성이 일치하는 element 들을 반환<br>
Ex. form.elements.userid : name 속성이 userid인
해당 form 내의 element<br>
폼 요소 탐색에 쓰이는 프로퍼티는 태그 구조에 의존하지 않아
태그 깊이와 무관하게 form.elements 사용해 접근<br>
반대로 모든 요소는 element.form으로 폼에 접근 가능(역참조)
</p>
// 폼 얻기
console.log(document.forms);
console.log(document.forms.memberJoin);
console.log(document.forms[0]);
// 요소 얻기
let form = document.forms.memberJoin;
console.log(form.elements);
console.log(form.elements.userid);
console.log(form.elements.gender);
console.log(form.elements.gender[0]);
console.log(form.elements.gender[1]);
// 역참조 가능
let email = form.elements.email; // 폼 -> 요소
console.log(email);
console.log(email.form); // 요소 -> 폼
console.log("=================================");
</script>
<h3>폼 요소 값 다루기</h3>
<p>
input, textarea : input.value 또는 input.checked
(checkbox 또는 radio)<br>
select.options : option 하위 요소들을 담고 있는 컬렉션<br>
select.value : 현재 선택 된 option 값<br>
select.selectedIndex : 현재 선택 된 option의 번호(인덱스)
</p>
<h3>focus, blur 이벤트</h3>
<p>
focus : 사용자가 폼 요소를 클릭하거나 tab 키를 눌러
요소로 이동 했을 때<br>
autofocus라는 HTML 속성을 사용해도 요소를 포커스 할
수 있으며 이는 페이지가 로드 된 후 자동으로 포커싱<br>
blur : 사용자가 다른 곳을 클릭하거나 tab 키를 눌러
다음 폼 필드로 이동했을 때<br>
또한 focus, blur 메소드로 요소에 포커스를 주거나
제거할 수 있음
</p>
<h3>focusin, focusout 이벤트</h3>
<p>
focus 이벤트는 해당 입력 필드에서만 동작하고
버블링 되지 않음<br>
focusin, focusout은 버블링 적용 됨
</p>
<script>
// 1. 폼 안에 포커스가 된 경우 클래스 추가해보기(X)
// focus 이벤트는 버블링 되지 않음
//form.onfocus = () => form.className = 'focused';
// 2. focusin과 focusout을 사용하면 이벤트 버블링 적용
form.addEventListener('focusin', () => form.classList.add('focused'));
form.addEventListener('focusout', () => form.classList.remove('focused'));
</script>
change 이벤트
<h3>change 이벤트</h3>
<p>
change : 요소 변경이 끝나면 발생<br>
텍스트 입력 요소인 경우 요소 변경이 끝날 때가 아니라
포커스를 잃었을 때 이벤트 발생<br>
select/checkbox/radio는 선택 값이 변경 된 직후 발생
</p>
<script>
form.introduce.addEventListener('change', () => alert('introduce change!'));
form.age.addEventListener('change', () => alert('age change!'));
</script>
input 이벤트
<h3>input 이벤트</h3>
<p>
input : 키보드 이벤트와 달리 어떤 방법으로든 값을
변경할 때 발생<br>
Ex. 마우스를 사용하여 글자를 붙여 넣거나
음성 인식 기능을 사용해서 글자를 입력할 때도 반응
</p>
<h3>submit 이벤트</h3>
<p>
submit : 폼을 제출할 때<br>
폼을 서버로 전송하기 전 내용을 검증하여 폼 전송을
취소할 때 사용<br>
폼을 전송하는 방법<br>
(1) input type="submit" 또는 input type="image" 클릭<br>
(2) input 필드에서 Enter 키 누르기<br>
form.submit() 메소드는 자바스크립트만으로 폼 전송을 하고자
할 때 사용<br>
동적으로 폼을 생성하고 서버에 보낼 수 있음<br>
단, 이 때는 submit 이벤트가 생성 되지 는 않음
</p>
이벤트 속성과 이벤트 핸들러(함수)를 연동하여 이벤트 발생 시 특정 기능을 하도록 하는 것
<h1>이벤트</h1>
<ul>
<li>마우스 이벤트(click, mouseover, mouseout, mousemove ...)</li>
<li>폼 요소 이벤트(submit, focus)</li>
<li>키보드 이벤트(keydown, keyup)</li>
<li>문서 이벤트</li>
</ul>
등의 <b>DOM 이벤트</b> 들이 있는데 이러한 이벤트가 발생했을 경우
실행되는 함수를 <b>이벤트 핸들러</b>라고 하며 핸들러를 할당하는
방법은 다양하다.
이벤트 설정방법
HTML 속성
DOM 프로퍼티
addEventListener (표준 이벤트 모델)
HTML 속성
HTML 내부 속성에 이벤트를 작성하는 방법
인라인 방식은 <script> 태그에 함수를 호출하는 방식을 선호
예) 클릭 시 이벤트 설정
<h1 onclick=‘처리로직’></h1>
또는
<h1 onclick=‘스크립트 내 함수 호출’></h1>
▼ 코드 예시 보기 ▼
<h3>1. HTML 속성</h3>
<p>
HTML 안의 onevent 속성에 이벤트 핸들러 할당하는 방법<br>
Ex. <h1 onclick="실행코드"> 등<br>
간단한 코드는 그냥 작성하기도 하지만 코드가 길다면
별도의 함수를 만들고 이를 호출한다.
</p>
<button onclick="alert('클릭했네?');">클릭해보세요</button>
<button onmouseover="mouseover(this);">마우스를 올려보세요</button>
<script>
function mouseover(elem){
alert('마우스 올리지마세요!');
// 핸들러 내부에 쓰인 this의 값은
// 핸들러가 할당 된 요소 => 이벤트가 발생한 button
console.log(elem);
console.log(elem.innerHTML);
elem.innerHTML = '마우스 올리지 마세요!';
}
</script>
DOM 프로퍼티
요소 객체가 갖고 있는 이벤트 속성에 이벤트 핸들러를 연결하는 방법
이벤트 객체를 제거할 땐 속성 값에 null을 넣어주면 됨
이벤트 발생 객체는 핸들러 내부에서 this로 표현 매개 변수로 이벤트 정보 전달(event)
예) 클릭 시 이벤트 설정
let h=document.getElementById(‘id명’);
h.onclick=function{
수행 기능 설정;
h(this).onclick=null; // 한 번만 실행
};
▼ 코드 예시 보기▼
<h3>2. DOM 프로퍼티</h3>
<p>
요소 객체가 가지고 있는 onevent 속성에 이벤트 핸들러를 연결
하는 방법<br>
Ex. element.onclick = 이벤트핸들러(함수);<br>
해당 프로퍼티는 하나 밖에 없기 때문에 여러 개의 이벤트를
할당할 수는 없다.<br>
만약 이벤트 객체를 제거할 때에는 속성 값에 null을 넣어주면 된다.
</p>
<button id="test1">test1 실행 확인</button>
<button id="test2">test2 실행 확인</button>
<div id="area1" class="area"></div>
<script>
let test1 = document.getElementById('test1');
let test2 = document.getElementById('test2');
test1.onclick = function(){
document.getElementById('area1').innerHTML
+= 'test1이 실행되었습니다.<br>';
// 핸들러 내부에 쓰인 this의 값은 핸들러가 할당 된 요소
// => 이벤트가 발생한 버튼
console.log(this);
console.log(this.innerHTML);
};
// 이전 이벤트 핸들러는 무시된다 => 하나의 이벤트 밖에 연결 할 수 없음
test1.onclick = () => alert('이벤트 덮어쓰기!');
function removeEvent(){
document.getElementById('area1').innerHTML
+= "test2가 실행되면서 test1 이벤트 제거<br>";
test1.onclick = null;
}
// 선언 되어 있는 함수를 핸들러에 할당함
test2.onclick = removeEvent;
</script>
addEventListener(표준 이벤트 모델)
w3에서 공식적으로 지정한 이벤트 모델
한번에 여러가지 이벤트핸들러 설정 가능
this키워드가 이벤트 발생 객체를 의미
예) 클릭 시 이벤트 설정
let h=document.getElementById(‘id명’);
h.addEventListener(‘click’,function(){
수행 기능 설정;
};
▼ 코드 예시 보기▼
<h3>3. addEventListener</h3>
<p>
1, 2번 방식의 이벤트 핸들러 할당의 경우 복수의 핸들러 할당 불가<br>
element.addEventListener(event, handler, [options])<br>
element.removeEventListener(event, handler, [options])<br>
위의 메소드로 핸들러를 추가/삭제하면서 복수의 핸들러를 할당할 수 있다.
</p>
<button id="btn">실행확인</button>
<script>
let btn = document.querySelector("#btn");
// 복수의 이벤트 핸들러 할당 가능
btn.addEventListener('click', () => alert('첫 번째 이벤트 동작!'));
btn.addEventListener('click', () => btn.style.background = 'red');
// 핸들러를 삭제하려면 핸들러 할당 시 사용한 함수를
// 그대로 전달해야 하므로 위와 같은 경우는 삭제 불가
// 함수 선언하여 핸들러 할당해서 삭제해보기
function myFunction(){
alert('곧 삭제될 친구!');
}
btn.addEventListener('mouseover', myFunction);
// 삭제 테스트
btn.removeEventListener('mouseover', myFunction);
</script>
이벤트 전달
버블링 방식 : 자식에서 부모 노드로 올라가면서 이벤트가 실행
캡쳐링 방식 : 부모노드에서 자식 노드로 내려가면서 이벤트가 실행
▼ 코드 예시 보기▼
<button id="evtObj">이벤트 객체 확인</button>
<!-- HTML 속성 안에서도 event 객체 사용 가능 -->
<button onclick="console.log(event);">이벤트 객체 확인</button>
<script>
let evtObj = document.querySelector("#evtObj");
evtObj.onclick = function(event){
console.log(event);
console.log(event.type + " 이벤트");
console.log(event.currentTarget);
console.log("에서 발생");
console.log("이벤트가 발생한 곳의 좌표는 ");
console.log(event.clientX + " : " + event.clientY);
};
</script>
<h1>버블링과 캡쳐링</h1>
<p>
버블링이란 한 요소에 이벤트가 발생하면 할당 된 핸들러가 동작하고,
이어서 부모 요소의 핸들러가 동작하는 것<br>
가장 최상단의 조상 요소를 만날 때까지 이 과정이 반복 되면서
요소 각각에 할당 된 핸들러가 동작한다.
</p>
<h3>이벤트 버블링 막기</h3>
<p>
event.target : 실제 이벤트가 시작 된 타깃 요소로
버블링이 진행되어도 변함이 없음<br>
event.currentTarget : 현재 실행 중인 핸들러가 할당 된 요소를
의미<br>
이벤트 객체의 메소드 event.stopPropagation()을 사용하면
버블링 중단을 명령함
</p>
<h3>기본 이벤트의 제거</h3>
<p>
기본 이벤트란<br>
- a 태그를 통한 페이지 이동<br>
- submit 시 입력 양식 제출 후 페이지 갱신<br>
등의 브라우저 기본 동작을 말함<br>
태그에 기본적으로 설정 되어 있는 이벤트를 제거하는
방법은 <br>
1. event.preventDefault()<br>
2. onevent를 통해 할당 된 이벤트 핸들러의 return
값을 false로 반환
</p>
<a href="14_BOM.html" onclick="event.preventDefault()">클릭해도 절대 이동할 수 없는 a태그</a>
<form onsubmit="return invalidate();">
<label for="password">비밀번호 : </label>
<input type="password" name="password" id="password" requried>
<br>
<label for="checkPwd">비밀번호 확인 : </label>
<input type="password" name="checkPwd" id="checkPwd" required>
<input type="submit" value="제출">
</form>
<script>
function invalidate(){
let pwd1 = document.getElementById('password').value;
let pwd2 = document.getElementById('checkPwd').value;
if(pwd1 == pwd2){
alert('입력 비밀번호가 일치합니다');
} else {
alert('입력 비밀번호가 일치하지 않습니다');
document.getElementById('checkPwd').select();
return false;
}
}
</script>
<h3>window 객체</h3>
<p>
브라우저 창에 대한 설정을 하는 객체
</p>
<button onclick="test1();">13_문서수정</button>
<button onclick="test2();">네이버</button>
<script>
function test1(){
//window.open('주소', '이름 또는 open 방식', '형태');
window.open('13_문서수정.html', 'popup1', 'width=1080, height=800');
// 창의 이름을 지정하면 동일한 이름으로 다시 open 했을 때
// 기존에 열린 창의 내용이 변경된다
// window.open('12_주요노드프로퍼티.html', 'popup1', 'width=1080, height=800');
}
function test2(){
window.open("https://www.naver.com", "_self");
// _blank : 새 창으로 열림. 기본 값.
// _self : 현재 페이지를 대체
}
</script>
window 객체 메소드
▼ 코드 예시 확인▼
<h3>window 객체의 timer 메소드</h3>
<h4>setTimeout</h4>
<button onclick="test3();">실행확인</button>
<script>
function test3(){
// 새 창이 열린 뒤 3초 후 자동으로 닫기
let myWindow = window.open();
// setTimeout(func, delay)
// func : 실행 함수, delay : 대기 시간 (밀리세컨단위)
setTimeout(function(){
myWindow.close();
}, 3000);
}
</script>
<h4>setInterval</h4>
<button onclick="test4();">실행확인</button>
<div id="area1" class="area"></div>
<script>
function test4(){
let area1 = document.getElementById('area1');
// setInterval(func, interval)
// func : 실행 함수, interval : 반복할 시간(밀리세컨단위)
setInterval(function(){
let date = new Date();
area1.innerHTML = date.getHours() + " : "
+ date.getMinutes() + " : "
+ date.getSeconds();
}, 1000);
}
</script>
윈도우 객체가 로드가 완료되면 자동으로 onload에 설정되어 있는 함수를 실행시키는 속성
윈도우 객체 로드 완료 : 모든 태그가 화면에 나타날 때
생성
window.onload =function(){
로직구성
};
또는
작성된 함수 호출 ;
screen객체
client 운영체제 화면에 대한 속성값을 가지는 객체
▼ 코드 예시 확인▼
<h1>BOM(Browser Object Model)</h1>
<h3>screen 객체</h3>
<p>
웹 브라우저 화면이 아닌 운영체제 화면의 속성을 가지는 객체
</p>
<button onclick="test6();">실행확인</button>
<script>
function test6(){
let child = window.open("", "", "width=800, height=500");
child.resizeTo(screen.width, screen.height);
setInterval(function(){
child.resizeBy(-20, -20);
child.moveBy(10, 10);
}, 500);
console.log("화면 너비 : " + screen.width);
console.log("화면 높이 : " + screen.height);
console.log("실제 화면에서 사용 가능한 너비 : " + screen.availWidth);
console.log("실제 화면에서 사용 가능한 높이 : " + screen.availHeight);
console.log("사용 가능한 색상 수 : " + screen.colorDepth);
console.log("한 픽셀 당 비트 수 : " + screen.pixelDepth);
}
</script>
location객체
브라우저의 주소표시줄(URL)과 관련된 객체
프로토콜 종류, 호스트 이름, 문서위치 등의 정보를 가진다.
▼ 코드 예시 확인▼
<h3>location 객체</h3>
<p>
브라우저 주소 표시줄과 관련 된 객체
</p>
<button onclick="test7();">실행확인</button>
<div id="area3" class="area-big"></div>
<script>
function test7(){
let area3 = document.getElementById('area3');
let html;
for(let key in location){
html += (key + " : " + location[key] + "<br>");
}
area3.innerHTML = html;
}
</script>
<!-- location.href : 현재 브라우저 창에 열린 문서의 url -->
<button onclick="location.href = 'https://www.naver.com'">네이버로 이동</button>
<button onclick="location = 'https://www.naver.com'">네이버로 이동</button>
<br><br>
<button onclick = "location = location">새로고침</button>
<button onclick = "location.href = location.href">새로고침</button>
<!-- reload는 현재 위치에서 새로고침을 한다 -->
<button onclick="location.reload();">현 위치에서 새로고침</button>
<br><br>
<!-- replace는 뒤로 가기 사용할 수 없다 -->
<button onclick="location.replace('https://google.com');">구글로 이동</button>
location 메소드
▼ 코드 예시 확인▼
<h3>navigator 객체</h3>
<p>
웹 페이지를 실행하고 있는 브라우저에 대한 정보를 가지는 객체
</p>
<button onclick="test8();">실행확인</button>
<div id="area4" class="area-big"></div>
<script>
function test8(){
let area4 = document.getElementById('area4');
let html = '';
html += '브라우저의 코드명 : ' + navigator.appCodeName + '<br>';
html += '브라우저의 이름 : ' + navigator.appName + '<br>';
html += '브라우저 전체 정보 : ' + navigator.userAgent + '<br>';
html += '브라우저 언어 : ' + navigator.language + '<br>';
html += '사용중인 운영체제 : ' + navigator.platform + '<br>';
area4.innerHTML = html;
}
</script>
<h3>history 객체</h3>
<button onclick="test9();">실행확인</button>
<div id="area5" class="area-big"></div>
<script>
function test9(){
// 히스토리 객체의 길이 출력
let area5 = document.getElementById('area5');
area5.innerHTML = 'history.length : ' + history.length;
// 뒤로 가기
// history.back();
// history.go(-2);
// 앞으로 가기
//history.forward();
history.go(1);
}
</script>