이제 form에 관련한 것들로부터는 잠깐 쉬어갈 것이다. index.html에 nomadcoders.co로 연결되는 anchor 요소를 하나 만들어 줄 것이다.
<a href="https://nomadcoders.co">Go to courses!</a>
클릭하면 노마드코더 홈페이지로 이동한다. 이제! 다시 한 번 JS를 이용해서 기본 동작을 막아볼 것이다. prevent the default behavior. 전에 말했듯이 JS는 우리가 기본 동작을 막는 것을 허용한다.
이전 영상에서 form의 기본 동작은 submit이라는 것을 배웠다. 그렇다면 링크의 기본 동작은 무엇일까? 클릭 시 다른 페이지로 이동하는 것이다! 그럼 이제 우리가 그것을 막아볼 것이다.
다시 app.js로 돌아와서 다음과 같이 코딩해보자.
const link = document.querySelector("a");
function handleLinkClick() {
alert("clicked!");
}
link.addEventListener("click", handleLinkClick);
(링크도 하나 뿐이고 설명하는 용도이니까 이렇게 써도 상관 없다.)
clicked라고 alert가 표시되고, 지금 이 alert가 이 page가 다른 동작을 하지 못하도록 막고 있다. 그래서 아무 일도 일어나지 않고 있지만, 내가 alert 창의 ok를 눌러서 alert가 없어지면, 이 브라우저의 기본 동작이 실행되는 것을 볼 수 있게 될 것이다.
다시 말해서, JS가 모든 것을 멈추게 한다. alert는 (좀 특이해서) 모든 동작들을 막게 한다. 모든 것들이 막혀있다가 ok를 누르면 다시 기본 동작이 실행 된다.
이전 영상에서 말했듯, 우리가 eventListener를 만들고 거기에 함수를 줬다는 것을 JS가 보게 되면, JS는 누군가 링크를 클릭할 때, 우리를 위해 함수를 실행시키게 될 것이다. JS press the play for you. 다시 한 번 말하지만, link.addEventListener("click", handleLinkClick);에서 handleLinkClick 함수는 우리가 실행시키는 것이 아니다.
handleLinkClick() 이렇게 ()를 추가하면 이 함수는 한 번만 실행되고 그걸로 끝이다. 이건 우리가 원하는 것이 아니다! 우리는 JS한테 함수의 이름만 주고 실행하는 것은 JS의 몫이다.
하지만 가끔 우리는 기본 동작을 막아야 할 필요가 있다. 가끔은 뭐가 클릭됐는지, 어디가 클릭됐는지 등 정보를 알고 싶을 때가 있다. 그럴 때 JS는 단순히 함수를 실행시키기만 하는 것이 아니라, JS는 함수를 실행시키는 동시에 그 함수(eventListener function)에 첫번째 인자로 object를 넣어줄 것이다.(정보를 준다.) 그리고 이 object에는 방금 일어난 event에 대한 여러 정보가 담겨있다. handleLinkClick(information about the event that just happend) 방금 일어난 event에 대한 정보를 담은 이 object는 handleLinkClick을 위한 eventListener 함수의 첫번째 인자로 주어지게 될 것이다. 우리는 자리만 제공해주면 된다. 우리는 공간만 만들고 받기만 하면 된다. 우리가 해야 할 것은 받는 것일 뿐이다. receiving. 계산기를 만들었을 때처럼 우리는 argument를 받아줘야 한다. 우리는 여기서 받을 것이다.
그리고 console.log(event)해주고 확인해보자.
보다시피 이건 좀 다른 것이다. 이것은 MouseEvent다. 상당히 흥미롭다! 전에는 submitEvent였다. 다르게 나온 이유는 event의 종류가 다양하기 때문이다. 지금은 콘솔에서 아무것도 클릭이 안되는데,(클릭할 수 있지만 정보가 열리진 않는다. 새로운 페이지가 열리진 않는다.) 그 이유는 alert가 떠 있기 때문이다. (ok를 누르면 새로운 페이지가 열리고 진행 된다.)
포인트는 얼마나 멋있는지 보자! screenX, Y는 내가 클릭한 위치의 X, Y좌표를 보여주고 있다. 이것은 엄청 중요한 정보다. 유저가 어디를 클릭했는지 알아야 할 때가 있기 때문이다. 그리고 여기에 유저가 스크린 상 클릭한 위치를 X, Y좌표로 제공하고 있다. 이렇게, 이벤트로부터 얻을 수 있는 다양한 정보가 존재하고, 굉장히 다양한 이벤트들이 존재한다. 이것은 클릭으로 비롯된거니까 mouseEvent다. (전에 본 것은 submitEvent였고, 완전히 다른 것이다. 다른 정보들이 제공되고 있다.)
(💡 저도 찾아보니까 MouseEvent보다 PointerEvent가 더 많은 기능을 포함하고 있어서 이제 PointerEvent를 쓴다고하네요(전자기기가 다양해져서 나왔다고합니다.)
https://javascript.info/pointer-events)
지금 우리는 기본 동작을 막고 있지 않으니까 alert의 ok를 누르면 바로 이동하게 된다. 이것은 우리가 원하는 것이 아니다. 그래서 우리가 해줄 것은 event.preventDefault()다. console.dir로 바꿔주고, 이제 event의 내부를 살펴보자.
새로고침 후, preventDefault로 인해(기본 동작을 막고 있기 때문에) go to courses를 클릭해도 더 이상 노마드코더 페이지로 이동되지 않는다. 브라우저는 링크를 클릭할 때 해당 사이트로 이동하도록 설정되어 있는데, 그것을 지금 우리가 막고 있는 것이다. 이제 event 내부를 살펴보자.
내부를 보면 이것저것 많다. X,Y좌표, movement, offset, page, ...
이것은 우리가 클릭할 때 무슨 일이 있었는지, 어디서 발생했는지 array로 보여주고 있다. 우리는 window>document>html>body>a를 클릭한 것이다.
type은 click이었고, 시간 등등. super sweet!
중요한 것은 우리가 기본 동작을 막았다는 것이다.
이 값이 true라는 것은, 우리가 브라우저가 하려고 하는 동작을 허용하지 않았다는 것이다. 허용하지 않고 막아버렸다.
이것이 event를 활용하는 방법이고, 우리가 preventDefault를 사용하는 이유다.
다시, 가장 중요한 것은 addEventListener 안에 있는 함수는 직접 실행하지 않는다는 것이다.
우리가 하는 것이 아니라, 이것은(함수 실행) 브라우저가 해주는 것이다. 브라우저는 실행만 시켜주는 것이 아니라, event에 대한 정보도 담아줄 것이다. handleLinkClick({event information}) 우리는 자리만 만들어주면 되고, 이 정보 안에는 몇 가지 함수도 같이 들어있을 것이다. 예를 들어 preventDefault 함수, 이것을 호출하게 되면, event는 멈추게 되고 아무것도 진행되지 않을 것이다. 우리가 브라우저에 대한 모든 것을 컨트롤 할 수 있게 된다.
이제 event.preventDefault를 이해 했으니, 링크들은 지우고 다시 우리 form을 작성해보자.
(💡댓글)
addEventListener 안에 있는 함수는 직접 실행하지 않는다.
브라우저가 실행시켜주고
브라우저에서 해당 이벤트에 대한 정보 즉, object를 가지게 된다.
addEventListener의 함수에서 object에 대한 자리만 할당해주면
해당 이벤트가 발생시킨 정보들에 대한 object들을 볼 수 있다!
이때 해당 이벤트가 가진 기본 Default값을 발생시키지 않기 하게 위해선 preventDefault를 이용하여 막을 수 있다!