이벤트 기초
1.어트리뷰트 방식
<button id="btn" onclick="greeting()" >클릭하세요</button>
function greeting(){
alert('안녕하세요!');
}
2.프로퍼티 방식 : 하나의 요소에 하나의 이벤트 핸들러만 바인당 할 수 있다 .
<button id="btn" >클릭하세요</button>
function hello(){
alert('hello!');
}
$btn.onclick=hello;
$btn.onclick=function(){ // 즉석에서 선언하고 사용
alert('안녕하세요');
}
$btn.onclick=()=>alert('안녕~');
3.addEventListner
<button id="btn">클릭!</button>
function hello(){
alert('hello');
}
const $btn=document.getElementById('btn');
$btn.addEventListener('click',hello);
$btn.addEventListener('click',function(){
alert('world!');
});
$btn.addEventListener('click',()=>{
alert('bye~');
});
//이벤트 핸들러 제거
$btn.removeEventListener('click',hello);
이벤트 객체와 전파
1.이벤트 객체
<p>아무곳이나 클릭하세요!</p>
<em class="message"></em>
const $em=document.querySelector('.message');
//문서 전체에 이벤트 핸들러 등록 ::파라미터 선언 해 두면 , 이벤트객체가 인자로 들어감
//파라미터 e의 이름은 자유롭게 작성
//이벤트가 발생하면 이벤트에 대한 다양한 정보가 들어 있는
//이벤트 객체가 동적으로 생성됩니다.
//생성된 이벤트 객체는 이벤트 핸들러의 첫번째 인자로 자동 전달 됩니다.
//어떤 이벤트가 발생했느냐에 따라 그에 맞는 객체가 알아서 전달.
document.addEventListener('click',(e)=>{
console.log(e);
$em.textContent=`x :${e.clientX},y:${e.clientY}`;
});
2.이벤트객체와 프로퍼티
<label>
<input type="checkbox" >
<em class="message"></em>
</label>
<script>
const $checkbox=document.querySelector('input[type=checkbox]');
const $em=document.querySelector('.message');
//checkbox의 여부가 바뀌었다면 change를 쓴다
$checkbox.addEventListener('change',e=>{ //괄호안에 파라미터 한개면 생략 가능
//실제로 이벤트가 일어난 요소
//console.log(e.target); // 이건 알아둬야 함!!!!!강사 강조
$em.textContent=e.target.checked?'체크됨!':'체크안됨!';
});
3.마우스 이벤트
<style>
.box{
width: 100px;
height: 100px;
background: #fff700;
border: 5px solid orange;
position : absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
//드래그 대상 요소 취득
const $box=document.querySelector('.box');
//드래그 시작 지점의 마우스 포인터 위치
const initialMousePos={
x:0,
y:0
};
//오프셋 : 이동한 거리
const offset={
x:0,
y:0
};
//이벤트 핸들러 정의
const move=function(e){
//오프셋 =
//현재(드래그 하는 시점)마우스 포인터 좌표에서 드래그 시작 시점의 좌표를 뺀다.
offset.x=e.clientX-initialMousePos.x;
offset.y=e.clientY-initialMousePos.y;
console.log(`x:${offset.x} ,y:${offset.y}`);
$box.style.left=offset.x+'px';
$box.style.top=offset.y+'px';
}
//mousedown(마우스 버튼을 눌렀을 때) 이벤트가 발생하면
//드래그 시작지점의 마우스 포인터 좌표를 저장.
$box.addEventListener('mousedown',function(e){
/*
이동거리를 계산하기 위해서 mousedown이벤트가 발생(드래그 시작)
드래그 시작 지점의 마우스 포인터 좌표(cllientX,Y)를 저장해 둔다
한 번 이상 드래그로 이동한 경우 move에서 left,top만큼 이동한 상태 이므로
이전의 이동한 거리 offset.x,y만큼 빼 줘야 처음위치(0,0)로 돌아가지 않는다.
*/
initialMousePos.x=e.clientX-offset.x;
initialMousePos.y=e.clientY-offset.y;
console.log('드래그 시작지점 x:'+initialMousePos.x);
console.log('드래그 시작지점 y:'+initialMousePos.y);
//마우스 이동이 시작된다면 , 따로 선언한 move()함수를 호출
document.addEventListener('mousemove',move);
}) ;
//mouseup 이벤트가 발생하면 ,mousemove 이벤트를 제거해서
//이동을 멈추게 하자
document.addEventListener('mouseup',function(){
document.removeEventListener('mousemove',move);
});
</script>
4 키보드이벤트
<input type="text">
<p class="msg"></p>
<script>
const $input=document.querySelector('input');
const $msg=document.querySelector('.msg');
//keyup은 누르고 올라올 때를 지정 , 누를 때는 keypress
$input.addEventListener('keyup',e=>{
console.log(e.key); //e.target 으로 작성하면 input태그를 지목함
if(e.key==='Enter'){
$msg.textContent=e.target.value; //e.key라고 하면 Enter가 나와서 ,value로 해야 한다.
e.target.value='';
}else if(e.key==='Escape'){
$msg.textContent='';
}
});
</script>
5 이벤트전파1
<style>
#fruits{
padding: 50px;
border: 2px solid red;
}
#fruits >li{
background: yellow;
margin-bottom: 10px;
}
</style>
</head>
<body>
<ul id="fruits">
<li>Apple</li>
<li>Banana</li>
<li>Grape</li>
</ul>
<script>
const $fruits=document.getElementById('fruits');
//부모에 이벤트를 걸었이 때문에, li클릭을해도 ul에 이벤트 걸린것으로 인정됨
$fruits.addEventListener('click',e=>{
console.log('ul에 클릭 이벤트가 발생!');
console.log('이벤트 핸들러가 붙은 타겟 :'+e.currentTarget);
console.log('실제 이벤트가 발생한 요소 :'+e.target);
});
$fruits.firstElementChild.addEventListener('click',e=>{
console.log('apple에 클릭 이벤트가 발생!');
//이벤트 전파를 중단(버블링 방지) :: 자식요소 이벤트만 발생하고 , 부모의 이벤트 실행을 방지
//부모와 자식의 이벤트가 같을 때만 버블링이 실행됨
e.stopPropagation();
});
</script>
6 이벤트전파2
<style>
#fruits{
list-style: none;
padding: 0;
}
#fruits li{
width: 100px;
cursor: pointer;
}
#fruits .active{
color:red;
text-decoration: underline;
}
</style>
</head>
<body>
<ul id="fruits">
<li id="apple" class="active">Apple</li>
<li id="banana">Banana</li>
<li id="grape" class="aa">Grape</li>
</ul>
<div>선택된 과일 : <em class="msg">apple</em></div>
<br>
#새로운 과일 추가 :
<input type="text" class="text-box">
<button id="add">추가</button>
<script>
const $fruits=document.getElementById('fruits');
const $msg=document.querySelector('.msg');
const $liList=[...$fruits.children];
//이벤트 핸들러 함수
function activate(e){
//이벤트 발생 타겟이 특정 요소인지를 검증 ::matches() :선택자 작성
if(!e.target.matches('#fruits>li')){
//console.log('여기는 이벤트가 발생하면 안돼요!');
return;
}
//console.log('여기는 이벤트가 발생해도 됨~!');
for(let $target of $liList){
// 클래스추가 메서드 , 조건이 true일 때 추가 ,false면 삭제
/*
toggle메서드의 두번째 매개값으로 논리값을 전달할 수 있는데 ,
해당 논리값이 true면 지정한 클래스를 추가하고 ,
false면 지정한 클래스를 삭제
flase인데 지정한 클래스가 존재하지 않으면 아무일도 일어나지 않는다.
*/
$target.classList.toggle('active',$target===e.target)
}
$msg.textContent=e.target.id;
}
//ul에 이벤트 등록
$fruits.addEventListener('click',activate);
//동적으로 과일 추가 기능 작성하기
const $btn=document.getElementById('add');
const $textBox=document.querySelector('.text-box');
//버튼에 입엔트 등록
$btn.addEventListener('click',e=>{
const $newLi=document.createElement('li'); // 가상 돔으로 <li></li> 가 생성
$newLi.textContent=$textBox.value; // <li>Orange</li>
$newLi.setAttribute('id',$textBox.value.toLowerCase());//소문자로 넣기
$fruits.appendChild($newLi);
$textBox.value='';
//새롭게 추가된 li에 이벤트를 부여하기 위해 배열에 추가
$liList.push($newLi);
});
</script>
7 이벤트 전파3
네이버로 이동
//부모의 이벤트를 자식에게 전달하기 위해서는 이벤트리스너 두번째 매개변수에 값을 true로 준다
document.querySelector('.root').addEventListener('click', e => {
alert('root');
}, true);
document.querySelector('.parent').addEventListener('click', e => {
alert('parent');
//e.stopPropagation();
}, true);
document.querySelector('.child').addEventListener('click', e => {
alert('child');
//e.stopPropagation();
});
const $link = document.querySelector('a');
$link.addEventListener('click', e => {
if(!confirm('정말 이동하시겠어요?')) {
e.preventDefault(); //태그의 고유 기능을 막음.
}
});
Quiz
이벤트 기초
1.어트리뷰트 방식
<button id="btn" onclick="greeting()" >클릭하세요</button>
function greeting(){
alert('안녕하세요!');
}
2.프로퍼티 방식 : 하나의 요소에 하나의 이벤트 핸들러만 바인당 할 수 있다 .
<button id="btn" >클릭하세요</button>
function hello(){
alert('hello!');
}
$btn.onclick=hello;
$btn.onclick=function(){ // 즉석에서 선언하고 사용
alert('안녕하세요');
}
$btn.onclick=()=>alert('안녕~');
3.addEventListner
<button id="btn">클릭!</button>
function hello(){
alert('hello');
}
const $btn=document.getElementById('btn');
$btn.addEventListener('click',hello);
$btn.addEventListener('click',function(){
alert('world!');
});
$btn.addEventListener('click',()=>{
alert('bye~');
});
//이벤트 핸들러 제거
$btn.removeEventListener('click',hello);
이벤트 객체와 전파
1.이벤트 객체
<p>아무곳이나 클릭하세요!</p>
<em class="message"></em>
const $em=document.querySelector('.message');
//문서 전체에 이벤트 핸들러 등록 ::파라미터 선언 해 두면 , 이벤트객체가 인자로 들어감
//파라미터 e의 이름은 자유롭게 작성
//이벤트가 발생하면 이벤트에 대한 다양한 정보가 들어 있는
//이벤트 객체가 동적으로 생성됩니다.
//생성된 이벤트 객체는 이벤트 핸들러의 첫번째 인자로 자동 전달 됩니다.
//어떤 이벤트가 발생했느냐에 따라 그에 맞는 객체가 알아서 전달.
document.addEventListener('click',(e)=>{
console.log(e);
$em.textContent=`x :${e.clientX},y:${e.clientY}`;
});
2.이벤트객체와 프로퍼티
<label>
<input type="checkbox" >
<em class="message"></em>
</label>
<script>
const $checkbox=document.querySelector('input[type=checkbox]');
const $em=document.querySelector('.message');
//checkbox의 여부가 바뀌었다면 change를 쓴다
$checkbox.addEventListener('change',e=>{ //괄호안에 파라미터 한개면 생략 가능
//실제로 이벤트가 일어난 요소
//console.log(e.target); // 이건 알아둬야 함!!!!!강사 강조
$em.textContent=e.target.checked?'체크됨!':'체크안됨!';
});
3.마우스 이벤트
<style>
.box{
width: 100px;
height: 100px;
background: #fff700;
border: 5px solid orange;
position : absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
//드래그 대상 요소 취득
const $box=document.querySelector('.box');
//드래그 시작 지점의 마우스 포인터 위치
const initialMousePos={
x:0,
y:0
};
//오프셋 : 이동한 거리
const offset={
x:0,
y:0
};
//이벤트 핸들러 정의
const move=function(e){
//오프셋 =
//현재(드래그 하는 시점)마우스 포인터 좌표에서 드래그 시작 시점의 좌표를 뺀다.
offset.x=e.clientX-initialMousePos.x;
offset.y=e.clientY-initialMousePos.y;
console.log(`x:${offset.x} ,y:${offset.y}`);
$box.style.left=offset.x+'px';
$box.style.top=offset.y+'px';
}
//mousedown(마우스 버튼을 눌렀을 때) 이벤트가 발생하면
//드래그 시작지점의 마우스 포인터 좌표를 저장.
$box.addEventListener('mousedown',function(e){
/*
이동거리를 계산하기 위해서 mousedown이벤트가 발생(드래그 시작)
드래그 시작 지점의 마우스 포인터 좌표(cllientX,Y)를 저장해 둔다
한 번 이상 드래그로 이동한 경우 move에서 left,top만큼 이동한 상태 이므로
이전의 이동한 거리 offset.x,y만큼 빼 줘야 처음위치(0,0)로 돌아가지 않는다.
*/
initialMousePos.x=e.clientX-offset.x;
initialMousePos.y=e.clientY-offset.y;
console.log('드래그 시작지점 x:'+initialMousePos.x);
console.log('드래그 시작지점 y:'+initialMousePos.y);
//마우스 이동이 시작된다면 , 따로 선언한 move()함수를 호출
document.addEventListener('mousemove',move);
}) ;
//mouseup 이벤트가 발생하면 ,mousemove 이벤트를 제거해서
//이동을 멈추게 하자
document.addEventListener('mouseup',function(){
document.removeEventListener('mousemove',move);
});
</script>
4 키보드이벤트
<input type="text">
<p class="msg"></p>
<script>
const $input=document.querySelector('input');
const $msg=document.querySelector('.msg');
//keyup은 누르고 올라올 때를 지정 , 누를 때는 keypress
$input.addEventListener('keyup',e=>{
console.log(e.key); //e.target 으로 작성하면 input태그를 지목함
if(e.key==='Enter'){
$msg.textContent=e.target.value; //e.key라고 하면 Enter가 나와서 ,value로 해야 한다.
e.target.value='';
}else if(e.key==='Escape'){
$msg.textContent='';
}
});
</script>
5 이벤트전파1
<style>
#fruits{
padding: 50px;
border: 2px solid red;
}
#fruits >li{
background: yellow;
margin-bottom: 10px;
}
</style>
</head>
<body>
<ul id="fruits">
<li>Apple</li>
<li>Banana</li>
<li>Grape</li>
</ul>
<script>
const $fruits=document.getElementById('fruits');
//부모에 이벤트를 걸었이 때문에, li클릭을해도 ul에 이벤트 걸린것으로 인정됨
$fruits.addEventListener('click',e=>{
console.log('ul에 클릭 이벤트가 발생!');
console.log('이벤트 핸들러가 붙은 타겟 :'+e.currentTarget);
console.log('실제 이벤트가 발생한 요소 :'+e.target);
});
$fruits.firstElementChild.addEventListener('click',e=>{
console.log('apple에 클릭 이벤트가 발생!');
//이벤트 전파를 중단(버블링 방지) :: 자식요소 이벤트만 발생하고 , 부모의 이벤트 실행을 방지
//부모와 자식의 이벤트가 같을 때만 버블링이 실행됨
e.stopPropagation();
});
</script>
6 이벤트전파2
<style>
#fruits{
list-style: none;
padding: 0;
}
#fruits li{
width: 100px;
cursor: pointer;
}
#fruits .active{
color:red;
text-decoration: underline;
}
</style>
</head>
<body>
<ul id="fruits">
<li id="apple" class="active">Apple</li>
<li id="banana">Banana</li>
<li id="grape" class="aa">Grape</li>
</ul>
<div>선택된 과일 : <em class="msg">apple</em></div>
<br>
#새로운 과일 추가 :
<input type="text" class="text-box">
<button id="add">추가</button>
<script>
const $fruits=document.getElementById('fruits');
const $msg=document.querySelector('.msg');
const $liList=[...$fruits.children];
//이벤트 핸들러 함수
function activate(e){
//이벤트 발생 타겟이 특정 요소인지를 검증 ::matches() :선택자 작성
if(!e.target.matches('#fruits>li')){
//console.log('여기는 이벤트가 발생하면 안돼요!');
return;
}
//console.log('여기는 이벤트가 발생해도 됨~!');
for(let $target of $liList){
// 클래스추가 메서드 , 조건이 true일 때 추가 ,false면 삭제
/*
toggle메서드의 두번째 매개값으로 논리값을 전달할 수 있는데 ,
해당 논리값이 true면 지정한 클래스를 추가하고 ,
false면 지정한 클래스를 삭제
flase인데 지정한 클래스가 존재하지 않으면 아무일도 일어나지 않는다.
*/
$target.classList.toggle('active',$target===e.target)
}
$msg.textContent=e.target.id;
}
//ul에 이벤트 등록
$fruits.addEventListener('click',activate);
//동적으로 과일 추가 기능 작성하기
const $btn=document.getElementById('add');
const $textBox=document.querySelector('.text-box');
//버튼에 입엔트 등록
$btn.addEventListener('click',e=>{
const $newLi=document.createElement('li'); // 가상 돔으로 <li></li> 가 생성
$newLi.textContent=$textBox.value; // <li>Orange</li>
$newLi.setAttribute('id',$textBox.value.toLowerCase());//소문자로 넣기
$fruits.appendChild($newLi);
$textBox.value='';
//새롭게 추가된 li에 이벤트를 부여하기 위해 배열에 추가
$liList.push($newLi);
});
</script>
7 이벤트 전파3
네이버로 이동
//부모의 이벤트를 자식에게 전달하기 위해서는 이벤트리스너 두번째 매개변수에 값을 true로 준다
document.querySelector('.root').addEventListener('click', e => {
alert('root');
}, true);
document.querySelector('.parent').addEventListener('click', e => {
alert('parent');
//e.stopPropagation();
}, true);
document.querySelector('.child').addEventListener('click', e => {
alert('child');
//e.stopPropagation();
});
const $link = document.querySelector('a');
$link.addEventListener('click', e => {
if(!confirm('정말 이동하시겠어요?')) {
e.preventDefault(); //태그의 고유 기능을 막음.
}
});