중요한 내용인 것 같아 수업내용 이외에 블로그에 전체적인 수업 흐름을 기록하고자 한다.
Events : Respondingto user inputs and actions.
브라우저가 user events를 통해서 'listen for'할 수 있는 이벤트의 종류는 매우 많다. (clicks, drags, hovers, scrolls, form submission, key press, mouse wheel, copying&pasting, screen resizing..) 유저가 web page에 무언가를 더함에 따라 웹페이지는 그것에 반응하여 유저에게 웹페이지의 콘텐츠를 보여준다. "in respond to"라는 단어를 강조하심..
event listen엔 여러가지 방법이 있는데, 일단 아래 html예시를 보자.
<button id="mybtn">Click Me!</button>
<button id="v3">Click Me!(eventListener)</button>
이 버튼을 클릭하면 콘솔에 무언가를 쓰고싶어 app.js에 아래 코드를 추가할 수 있다.
const btn = document.querySelector("#mybtn");
btn.onclick = function() {
console.log('you clikced me!');
}
console.dir(btn);을 보면 btn의 object 요소의 on으로 시작하는 key의 value들이 전부 null임을 확인할 수 있다. on으로 시작하는 value값들이 그 element의 이벤트와 관련한 부분임을 간접적으로 알 수 있다. 그 null value를 우리가 설정한 ! 콜백 함수로 바꾸는 것이다. 실제로 mybtn을 클릭하면 내가 설정한 콘솔의 문구들이 프린트됨을 확인할 수 있다. 간단히 말하면, onclick property를 바꾸거나 추가하는 것이다. 이때 Property는 함수가 되어야 한다!
btn에서 on으로 시작하는 요소들은 매우 많다. 하고 싶은 것으로 하면 된다.(onmouseenter 등등. 자세한 사항은 mdn을 확인하자)
🌱 addEventListener(event, callback_function)
다음은 가장 많이 쓰이는 addEventListener이다. 위의 html에서 v3를 이용할 것이다.
const v3 = document.querySelector("#v3");
v3.addEventListener("click", () => {
console.log("you clicked 3rd ver of button!");
console.log("you used addEventListener!");
});
이런 방식을 가장 많이 사용한다고 한다. addEventListener에서 첫번째 "click"에 들어갈 다양한 종류의 event는 MDN의 event Reference를 참고하도록 하자. click 이외에도 dblclick(더블클릭), mouseenter(마우스가 정해진 구역 위로 올라왔을 때) 등등의 이벤트가 존재한다.
왜 addEventListener을 쓰냐고 한다면, 여러 가지의 이벤트에 따른 여러가지의 call back function을 동시에 사용할 수 있기 때문이다. 여러번 add를 하면 하나개의 event에 대하여 여러 개의 respond function을 쓸 수 있다. 그래서 "ADD"가 사용된다고 생각하면 된다. 또한 removeEventListener역시 존재한다.
.. 그냥 addEventListener을 원툴로 쓴다고 생각하면 된다.
🌱 THIS
const generateRandomColor = () => {
let r = Math.floor(Math.random()*255);
let g = Math.floor(Math.random()*255);
let b = Math.floor(Math.random()*255);
return `rgb(${r},${g},${b})`;
}
const btns = document.querySelectorAll('button');
for (let btn of btns) {
btn.addEventListener('click',() => {
btn.style.backgroundColor = generateRandomColor();
}
}
위 코드는 화면상에 보이는 모든 버튼들에 대해서, 버튼을 클릭할 때마다 버튼의 색을 랜덤으로 바꾸는 코드이다.
그런데 btn.addEventListener의 call back function을 조금 더 generic하게 쓸 수 있는 방법이 없을까? 저기서는 for-of 루프를 통해 btn을 직접 select하여 문제가 없는 것처럼 보이지만, 제네릭한 함수에서 selected one을 쓸 수 있는 방법이 있으면 훨신 편할 것이다. 여기서 나오는 것이 this!
function changeColor() {
this.style.backgroundColor = generateRandomColor();
}
위 코드를 작성한 뒤 btn.addEventListener('click',changeColor); 을 하면 첫 코드와 똑같은 generic function이 완성된다~. call back function에서는 함수 콜을 하면 안되기 떄문에 괄호가 있는 changeColor()가 아니라 changeColor만이 들어간다는 사실을 다시 한 번 상기하도록 하자.
🌱 keydown
const input = document.querySelector("input");
input.addEventListener("keydown", function () {
console.log("keydown");
});
input.addEventListener("keyup", function () {
console.log("keyup");
});
나의 html에 어떠한 input(type='text')를 두고 거기서 놀았다고 가정해보자. 스크립트를 저렇게 짠 뒤 커서를 input 위에다 두고 키보드를 뚱땅거리면 내 콘솔에 keydown, keyup이라는 문자가 마구잡이로 프린트된다. 그러나 여기선 user가 키보드의 어떤 키를 눌렀는지 전혀 알 수가 없다.
어떤 키가 눌렀는지 알고싶다!! -> event object를 사용하자. 간단히 우리의 콜백 함수에 인자 하나를 추가하자.
const input = document.querySelector("input");
input.addEventListener("keydown", function (evt) {
console.log(evt);
console.log("keydown");
});
input.addEventListener("keyup", function (evt) {
console.log(evt);
console.log("keyup");
});
스크립트를 이렇게 짠 뒤 콘솔에 뜨는 object 정보를 유심히 보면 evt.key와 evt.code가 중요한 요소로 나옴을 확인할 수 있다. 유저가 키보드의 어떤 부분을 눌렀는지 알 수 있다. 아래 코드를 돌리고 input 위에서 신나게 놀다보면 이해할 것이다.
input.addEventListener("keydown", function (evt) {
console.log(evt.key);
console.log(evt.code);
});
여기서 code는 진짜 키 자체!로 조금 더 unique한 값이고, key는 유저가 친 키보드의 결과값을 나타낸다. (ex:내가 만약 'ㅂ'을 치면 Key값은 'ㅂ'으로 나오지만 코드값은 'KeyQ'로 나온다). 다른 language keyboard를 사용해도 같은 결과를 나타내고 싶으면 code를 사용하는 것이 굳.
window 자체에서 무언가를 꾸미고 싶으면?
window.addEventListener()을 사용한다.
const span = document.querySelector("span");
window.addEventListener("keydown", function (evt) {
if (evt.code === "ArrowLeft") {
span.innerText = "left!";
} else if (evt.code === "ArrowRight") {
span.innerText = "right!";
} else if (evt.code === "ArrowUp") {
span.innerText = "up!";
} else if (evt.code === "ArrowDown") {
span.innerText = "down!";
}
});
내가 임의로 만들어본건데 뭐 이런 식으로.
keydown을 이용하기 위해선 event object의 information을 사용하는 것이 필수적이라는 사실을 배웠다.
🌱 Form Event
<form action="/shelter" id="shelterForm">
<input type="text" id="input" />
<button type="submit">submit!</button>
</form>
위와 같은 html에서 user가 form 안에 무언가를 넣어서 submit 버튼을 누른다고 생각해보자. 우리의 form의 action부분으로 form 데이터가 전송되게 될 것이다. 그리고 페이지가 refresh되고 // 잠깐!! 여기서 페이지가 refresh 되는 것을 멈추고 싶다면?
const form = document.querySelector("#shelterForm");
form.addEventListener("submit", function (e) {
console.log("submitted!");
e.preventDefault();
});
매우 간단하다. 콜백 함수의 인자에 preventDefault()를 하면 브라우저 초기 설정에 따라 submit을 누르면 자동으로 refresh되는 설정을 막을 수 있다. 콘솔을 살펴보면 새로고침 되지 않아도 우리의 form 데이터가 안전하게 보내졌다는 뜻의 로그 submitted!는 여전히 남게된다. stop automatic(normal) behavior을 하는 가장 대표적인 방법이자 거의 유일한 방법이다.
그리고 form으로부터 data extracting을 하려면. value라는 값을 이용하면 된다.
플러스로, Form 안의 element들을 name으로 구분하여 form 내부의 여러 input들을
form.elements.name으로 접근할 수 있다.
🌱 Event bubbling
🌱 Event Delegation