| 이벤트(Event)
- 웹 브라우저가 알려주는 HTML 요소에 대한 사건을 발생
- 웹 페이지에 사용된 자바스크립트는 발생한 이벤트에 반응하여 특정 동작을 수행할 수 있음
- 자바스크립트는 비동기식 이벤트 중심의 프로그래밍 모델
<input type="button" onclick="sendit()" value="확인">
------ ------- -------
이벤트타겟 이벤트타입 이벤트리스너
| 이벤트타입(Event Type)
- 발생한 이벤트의 종류를 나타내는 문자열로 이벤트명이라고도 함
- 키보드, 마우스, HTML DOM, window 객체등을 처리하는 이벤트 제공
- https://developer.mozilla.org/ko/docs/Web/Events
- on이 안붙어있는이유는 on은 html에서 만 붙이는거고 js기준으로 만들어진거라 on안붙음
이벤트타겟(Event Target)
- 이벤트가 일어날 객체를 의미
이벤트리스너(Event Listener)
- 이벤트가 발생했을 때 그 처리를 담당하는 함수
- 이벤트 핸들러라고도 부름
- 지정된 타입의 이벤트가 특정 요소에서 발생하면 웹 브라우저는 그 요소에 등록된 이벤트리스너를 실행
이벤트 등록
객체.addEventListener(이벤트타입, 이벤트리스너);
이벤트 제거
객체.removeEventListener(이벤트타입, 이벤트리스너);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>이벤트 타입</title>
<script>
window.onload = function() {
const text = document.getElementById('text');
text.innerHTML = "<b style='color:deeppink;'>HTML문서가 모두 로드되었습니다.</b>"
}
function changeText(el){
el.innerHTML = "<b style='color:deepskyblue;'>짠! 문자열이 변경되었어요.</b>"
}
</script>
</head>
<body>
<h2>이벤트 타입</h2>
<p id="text"></p>
<p onclick="changeText(this)">click a string</p> //this : 현재 자기 객체 즉 p태그
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>이벤트 리스너</title>
<script>
window.onload = function(){
const btn = document.getElementById('eventBtn');
btn.addEventListener('click',clickBtn);
btn.addEventListener('mouseover',mouseOverBtn);
btn.addEventListener('mouseout', mouseOutBtn);
}
function clickBtn(){
document.getElementById('text').innerHTML = "<b>버튼을 클릭했어요</b>";
}
function mouseOverBtn(){
document.getElementById('text').innerHTML ="<b>버튼위에 커서가 올라갔어요</b>";
}
function mouseOutBtn(){
document.getElementById('text').innerHTML ="<b>버튼밖으로 커서가 나갔어요</b>";
}
function delEvent(){
const btn = document.getElementById('eventBtn');
btn.removeEventListener('click',clickBtn);
btn.removeEventListener('mouseover',mouseOverBtn);
btn.removeEventListener('mouseout', mouseOutBtn);
document.getElementById('text').innerHTML = "<b>이벤트 리스너가 삭제되었어요</b>"
}
</script>
</head>
<body>
<h2>이벤트 리스너</h2>
<p><button id="eventBtn">event button</button><button id="delBtn" onclick="delEvent()">remove event</button></p>
<p id="text"></p>
</body>
</html>
| 이벤트 객체(Event Object)
- 특정 타입의 이벤트와 관련이 있는 객체
- 이벤트 객체는 해당 타입의 이벤트에 대한 상세 정보를 저장하고 있음
- 모든 이벤트 객체는 이벤트의 타입을 나타내는 type 프러퍼티와 이벤트 대상을 나타내는 target 프로퍼티를 가지고 있음
- 이벤트 객체는 이벤트 리스너가 호출될 때 인수로 전달
function sendit(e){ // e는 이벤트 객체 onclick="sendit()"에서 매개변수를 주지않아도 자동으로 매개변수를 갖는다
console.log(e.target); //이벤트 타겟(button)
console.log(e.type); //이벤트 타입(onclick)
}
<input type='button" onclick="sendit()" value="완료">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>이벤트 객체1</title>
<script>
window.onload = function(){
const btn = document.getElementById('btn');
btn.addEventListener('click',clickBtn);
}
function clickBtn(e){
console.log(e.target);
console.log(e.target.id);
console.log(e.target.value);
console.log(e.type)
}
</script>
</head>
<body>
<h2>이벤트 객체1</h2>
<input type="button" id="btn" value="확인">
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>이벤트 객체2</title>
<script>
window.onload = function(){
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
const btn3 = document.getElementById('btn3');
btn1.addEventListener('click',clickBtn);
btn2.addEventListener('click',clickBtn);
btn3.addEventListener('click',(e) => {
console.log(`e.targe.id: ${e.target.id}`);
console.log('버튼 3이 눌렸어요!');
});
}
function clickBtn(e){
switch(e.target.id){
case 'btn1' :
console.log('버튼 1이 눌렸어요!');
break;
case 'btn2' :
console.log('버튼 2가 눌렸어요!');
break;
}
}
</script>
</head>
<body>
<h2>이벤트 객체2</h2>
<input type="button" id="btn1" value="버튼1">
<input type="button" id="btn2" value="버튼2">
<input type="button" id="btn3" value="버튼3">
</body>
</html>
| 이벤트 전파(Event Propagtion)
- 이벤트가 발생했을 때 브라우저가 이벤트 리스너를 실행시킬 대상 요소를 결정하는 과정
- document 객체나 HTML 문서의 요소에서 이벤트가 발생하면 대상 요소를 결정하기 위해 이벤트 전파가 일어남
- document 부터 쭉 내려와가지구 어디서 이벤트가 발생했는지 확인하고 다시 document로 쭉 올라가게 됨
- 타고 내려오는게 캡쳐링 확인하고 다시올라가는게 버블링
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>이벤트 전파</title>
<style>
#divBox {width: 100%; height: 300px; border: 3px solid red;}
#pBox { width: 70%; height: 150px; border: 1px solid blue;}
#spanBox { border: 3px solid gold; }
</style>
<script>
window.onload = function(){
// 버블링 전파방식
document.getElementById('divBox').addEventListener('click',clickDiv);
document.getElementById('pBox').addEventListener('click',clickP);
document.getElementById('spanBox').addEventListener('click',clickSpan);
// 캡처링 전파방식
// document.getElementById('divBox').addEventListener('click',clickDiv,true);
// document.getElementById('pBox').addEventListener('click',clickP,true);
// document.getElementById('spanBox').addEventListener('click',clickSpan,true);
}
function clickDiv(e){
//e.stopPropagation(); 전파방해
document.getElementById('text').innerHTML += "<span style = 'color:red;'>div를 클릭했어요</span><br>";
}
function clickP(e){
//e.stopPropagation(); 전파방해
document.getElementById('text').innerHTML += "<span style = 'color:blue;'>p를 클릭했어요</span><br>";
}
function clickSpan(e){
//e.stopPropagation(); 전파방해
document.getElementById('text').innerHTML += "<span style = 'color:gold;'>span을 클릭했어요</span><br>";
}
</script>
</head>
<body>
<h2>이벤트 전파</h2>
<div id="divBox">
<p id="pBox">
<span id="spanBox">
클릭
</span>
</p>
</div>
<p id="text"></p>
</body>
</html>
캡처링 전파방식
- 부모에서 자식으로 이벤트를 전파
// 캡처링 전파방식
document.getElementById('divBox').addEventListener('click',clickDiv,true);
document.getElementById('pBox').addEventListener('click',clickP,true);
document.getElementById('spanBox').addEventListener('click',clickSpan,true);
버블링 전파방식
- 자식에서 부모로 이벤트를 전파
// 버블링 전파방식
document.getElementById('divBox').addEventListener('click',clickDiv);
document.getElementById('pBox').addEventListener('click',clickP);
document.getElementById('spanBox').addEventListener('click',clickSpan);
✔ 이벤트 전파를 막는 방법
이벤트객체명.stopPropagation();
| Iterable
- 순회가 가능한 것
const arr = [1,2,3,4,5];
console.log(arr.values());
console.log(arr.entries());
console.log(arr.keys());
const iterator = arr.values();
while(true){
const item = iterator.next();
if(item.done) break;
console.log(item.value);
}
for(let item of arr){
console.log(item);
}
for(let item of arr.values()){
console.log(item);
}
--결과--
Object [Array Iterator] {}
Object [Array Iterator] {}
Object [Array Iterator] {}
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
| generator
- 순회가 가능한 것
- 좀 더 심플하게 사용할 수 있는 객체
function* 제너레이터명(){
실행문
...
}
function* multipleGenerator(){
try{
for(let i=0; i<5; i++){
console.log(i);
yield i ** 2;
}
}catch(error){
console.log(error);
}
}
const multiple = multipleGenerator();
let next = multiple.next();
console.log(next.value, next.done)
next = multiple.next();
console.log(next.value, next.done)
next = multiple.next();
console.log(next.value, next.done)
next = multiple.next();
console.log(next.value, next.done)
next = multiple.next();
console.log(next.value, next.done)
--결과--
0
0 false
1
1 false
2
4 false
3
9 false
4
16 false
| Spread
https://wlswoo.tistory.com/12?category=861943
매개변수로 받을때 ... 쓰면
Rest파라미터
객체내에 값을 쏙 복사해서 가져오는것
Spread연산자 - 깊은복사 - 값복사
Spread 연산자, 전개구문
- 모든 iterable은 Spread가 될 수 있음
- 순회가능한 데이터는 펼쳐 질 수 있음
func(...iterable)
[...iterable]
{...obj}
function add(num1, num2, num3){
return num1 + num2 + num3
}
add(10, 20, 30); // 일반적인 값
const nums = [10, 20, 30];
add(nums[0], nums[1], nums[2]);
add(...nums)
스프레드
function add(num1, num2, num3){
return num1 + num2 + num3;
}
function sum(num1, num2, ...nums){
console.log(nums)
}
const nums = [10,20,30];
console.log(add(nums[0],nums[1],nums[2]));
console.log(add(...nums));
4
sum(1,2,3,4,2,5,6,32);
--결과--
60
60
[ 3, 4, 2, 5, 6, 32 ]
배열 - concat vs 스프레드
const fruits1 = ['🍎', '🍊']
const fruits2 = ['🍔', '🍊']
let arr = fruits1.concat(fruits2);
console.log(arr);
arr = [...fruits1,...fruits2];
console.log(arr);
--결과--
[ '🍎', '🍊', '🍔', '🍊' ]
[ '🍎', '🍊', '🍔', '🍊' ]
arr = [...fruits1,'👍',...fruits2];
console.log(arr);
--결과--
[ '🍎', '🍊', '👍', '🍔', '🍊' ]
스프레드 응용 프로퍼티추가
const apple = {name : '김사과', age : 20, address : {si : 'seoul'}};
console.log(apple);
// apple.job = '프로그래머'; 이렇게 추가할수도있지만 나는 새로 하나 만들고싶어
const apple_update = {...apple,job: '프로그래머'}
console.log(apple);
console.log(apple_update);
--결과--
{ name: '김사과', age: 20, address: { si: 'seoul' } }
{ name: '김사과', age: 20, address: { si: 'seoul' } }
{ name: '김사과', age: 20, address: { si: 'seoul' }, job: '프로그래머' }
| 구조분해할당
const fruits = ['🍊','💕','🍎','✔','🍌'];
const [fruit1, fruit2, ...others] = fruits; // 오렌지 fruit1로 감 하트는 프룻2 나머지는 다 others로
console.log(fruit1);
console.log(fruit2);
console.log(others);
--결과---
🍊 //fruit1
💕 //fruit2
[ '🍎', '✔', '🍌' ] //others
const point = [1,2];
const [y, x, z] = point;
//const [y,x,z=0] =point; //이런식으로 z=0 으로 기본값을 지정해주면 undefined안나옴
console.log(x);
console.log(y);
console.log(z);
--결과--
2
1
undefined
function sendEmoji(){
return ['🍊','💕','🍎','✔'];
}
const [orange,heart,redapple,check] = sendEmoji();
console.log(orange);
console.log(heart);
console.log(redapple);
console.log(check);
--결과--
🍊
💕
🍎
✔
console.log(apple_update)
//apple_update = { name: '김사과', age: 20, address: { si: 'seoul' }, job: '프로그래머' }
//초보스타일
// function display(apple){
// console.log('name',apple.name);
// console.log('age',apple.age);
// console.log('job',apple.job);
// }
//고수스타일
//apple_update 안에있는 실제 변수명과 동일하게 적어야 인식하고 값이 들어감
//괄호가 중요 {}
function display({name,age,job}){ // 받을때는 안을 펼쳐서 받고싶은것만 받을수있는느낌?
console.log('name',name);
console.log('age',age);
console.log('job',job);
}
display(apple_update) //던져주는건 객체 통째로 던져주지만
--결과--
{ name: '김사과', age: 20, address: { si: 'seoul' }, job: '프로그래머' }
name 김사과
age 20
job 프로그래머
const{name, age, pet='루시',job: hobby} = apple_update;
//속성명 변경은 :(콜론)!!!!!!
//없던 요소를 적으면 apple_update에 추가되는것은 아님
//구조분해할당? 그냥 값복사임 참조값 복사가아님
//변수선언묶음 느낌인데 오브젝트에 값들이 많으니 편하게 값을 할당해주는느낌
console.log(name);
console.log(age);
console.log(pet);
//console.log(job) 변수명이 변경되었기때문에 에러
--결과--
김사과
20
루시
객체안에 객체인 프로퍼티가 들어갈수있는데
그 객체안의 객체안의 프로퍼티 는 어케 받아야할까?
const component = {
name: 'Button',
style: {
size: 20,
color: 'black'
}
};
//객체내부 접근은 콜론(:)을 통해!
//변수명 변경도 콜론(:)
function changeColor({style:{color:cr}}){
console.log(cr);
}
changeColor(component)
--결과--
black
| Set
set생성방법
new Set([ ])
const set = new Set([1, 2, 3, 4, 5]);
console.log(set);
--결과--
Set(5) { 1, 2, 3, 4, 5 }
사이즈 확인-size
console.log(set.size);
--결과--
5
값이 존재하는지 확인-has()
console.log(set.has(2));
//2라는값이 존재하나요?;
console.log(set.has(7));
//7이라는값이 존재하나요?
--결과--
true
false
순회
set.forEach((item) => console.log(item)) //화살표 함수 알맹이를 이용
for(let value of set.values()){
console.log(value);
}
--결과--
1
2
3
4
5
1
2
3
4
5
추가-add()
set.add(6);
console.log(set);
set.add(6);
console.log(set); //추가안됨 중복안되기때문
--결과---
Set(6) { 1, 2, 3, 4, 5, 6 }
Set(6) { 1, 2, 3, 4, 5, 6 }
삭제-delete()
set.delete(6);
console.log(set);
--결과--
Set(5) { 1, 2, 3, 4, 5 }
전부삭제-clear()
set.clear();
console.log(set);
--결과--
Set(0) {}
오브젝트 세트
const obj1 = { name:'apple', emoji:'🍎',price: 1000};
const obj2 = { name:'banana', emoji:'🍌',price: 2000};
const set2 = new Set([obj1, obj2]);
console.log(set2);
obj1.price = 1500; // true
set2.add(obj1); // false set에 저장될때 주소로 저장하기때문에
console.log(set2);
const obj3 = { name:'apple', emoji:'🍎',price: 1000};
set2.add(obj3);
console.log(set2);
--결과--
Set(2) {
{ name: 'apple', emoji: '🍎', price: 1000 },
{ name: 'banana', emoji: '🍌', price: 2000 }
}
Set(2) {
{ name: 'apple', emoji: '🍎', price: 1500 },
{ name: 'banana', emoji: '🍌', price: 2000 }
}
Set(3) {
{ name: 'apple', emoji: '🍎', price: 1500 },
{ name: 'banana', emoji: '🍌', price: 2000 },
{ name: 'apple', emoji: '🍎', price: 1000 }
}
문제-1 : 중복제거해보자
const fruits = ['🍎','🍉','🍈','🍎','🍉','🍈'];
function removeDuplication(){
const set = new Set([...fruits]);
return set
}
console.log(removeDuplication(fruits))
문제-2 : 교집합만 뽑아보자
const set1 = new Set([1,2,3,4,5]);
const set4 = new Set([1,2,3]);
//방법1
function findIntersection(set1, set2){
const set = new Set([]);
set1.forEach( (item) => { if(set2.has(item)){set.add(item)} })
return set
}
//방법2
//function findIntersection(set1, set2){
// return new Set([...set3].filter((item) => set2.has(item)))
// }
//방법3
// function findIntersection(set1, set2){
// return set1.forEach( (item) => { if(set2.has(item)){console.log(item)} })
// }
// findIntersection(set1, set4);
| Map
map객체 생성방법 ([ [ ], [ ] ])
키와 값으로 이루어진 순서x,중복x
const map = new Map([
['key1','🍎'],
['key2','🍌']
])
console.log(map);
--결과--
Map(2) { 'key1' => '🍎', 'key2' => '🍌' }
사이즈확인-size()
console.log(map.size);
--결과--
2
존재하는지 확인-has()
console.log(map.has('key1'));
console.log(map.has('key6'));
--결과--
true
false
순회 - forEach((벨류,키) => ~~~) // 순서 중요!! 벨류먼저!
map.forEach((value,key) => console.log(key,value));
//벨류먼저,키는 나중 순서 중요!
--결과--
key1 🍎
key2 🍌
찾기- get(키값)
console.log(map.get('key1'));
console.log(map.get('key2'));
console.log(map.get('key3'));
obj = {'key1':'🍎','key2':'🍌'};
console.log(obj['key1']); //
console.log(map['key1']); // undefined
--결과--
🍎
🍌
undefined
🍎
undefined
추가-set(키값,벨류값)
map.set('key3', '🍊');
console.log(map)
--결과--
Map(3) { 'key1' => '🍎', 'key2' => '🍌', 'key3' => '🍊' }
삭제-delete(키값)
map.delete('key3');
console.log(map);
--결과--
Map(2) { 'key1' => '🍎', 'key2' => '🍌' }
전부삭제-clear()
map.clear();
console.log(map)
--결과--
Map(0) {}
| Operator
논리연산자 &&, ||
|| : 트루인놈 바로 대입
const obj1 = {name:'김사과'};
const obj2 = {name:'반하나', lover:'이메론'};
if(obj1 || obj2){ //조건문에서는 true/false 만 반환
console.log('둘다 true!');
}
let result = obj1 && obj2; //대입문일때는 obj1이 true obj2가 true 이면 obj2가 대입
console.log(result);
result = obj1 || bool; // 둘 중 트루인놈이 들어가고 둘다 트루면 젤앞놈이 바로들어ㅏㅁ
console.log(result)
--결과--
{ name: '반하나', lover: '이메론' }
{ name: '김사과' }
&& : 앞,뒤 둘다 true일때 뒤에놈 반환
function changeLover(obj){
if(!obj.lover){
throw new Error('애인이 없어!')
}
obj.lover = '애인바뀜'
}
function makeNewLover(obj){
if(!obj.lover){
throw new Error('애인이 있다');
}
obj.lover - ' 새롱'
}
obj1.lover && changeLover(obj1);
console.log(obj1);
obj2.lover && changeLover(obj2);
console.log(obj2);
--결과--
{ name: '김사과' }
{ name: '반하나', lover: '애인바뀜' }
null 또는 undefined인 경우를 확인할때
let item = { price: 1000};
const price = item && item.price;
console.log(price)
--결과--
1000
.
기본값설정
default parameter : undefined 만 취급
0, -0, null, ' ' 취급안함
function print(message){
const text = message || 'hello'
console.log(message);
}
print('안녕')
print();
print(undefined);
print(null);
print('');
console.log(`-----------------`);
--결과--
안녕
undefined
undefined
null
-------------------
옵셔널 체이닝 연산자
- ECMA Script 11
- ?. , ??
- null 또는 undefined을 확인할 때
?. : 부모자식관계에서 사용하는것!
let item2 = {price2: 1000};
const price2 = item && item.price; // item && item.price;
console.log(price2);
let banana = {name:'반하나',lover:{name:'오렌지'}};
function printLoverName(obj){
// const loverName = obj && lover && lover.name;
const loverName = obj?.lover?.name;
console.log(loverName);
}
printLoverName(banana);
--결과--
1000
오렌지
??
let num = 0; //0이 원래가격인데 falsy 하니까 어케해야함
console.log(num || '-1');
console.log(num ?? '-1'); // null, undefined
--결과--
-1
0
'웹 개발 > 🌐 JavaScript' 카테고리의 다른 글
JavaScript | promise,async,json,fetch (0) | 2022.11.17 |
---|---|
JavaScript | 주석,에러처리,index,콜스택,settimeout,비동기 (0) | 2022.11.17 |
JavaScript | 함수,오브젝트,클래스,상속,래퍼객체 (0) | 2022.11.09 |
JavaScript | history,navigator,dom,node,정규표현식 (1) | 2022.11.08 |
JavaScript | 화살표함수,객체,프로토타입,math,string,date,window,엘리먼트접근 (0) | 2022.11.07 |