Leeyanggoo
[JS] 자바스크립트 이벤트 문제 풀어보기!! 본문
1번 문제
이 문서에는 1번 이미지가 삽입되어 있습니다.
이미지 위에 마우스 포인터를 올려 놓았을 때 2번 이미지로 바뀌었다가,
이미지에서 마우스 포인터를 다른 곳으로 이동하면 1번 이미지로 바뀌는 소스를 작성해 보세요.
길라잡이
- <img> 태그에는 id나 class가 없습니다. 태그 이름을 사용하거나 2개 이상의 선택자를 연결 후 이미지를 가져와서 변수에 저장합니다.
- 마우스 포인터를 이미지 위에 올려놓을 때는 mouseover 이벤트가, 마우스 포인터를 다른 곳으로 이동할 때는 mouseout 이벤트가 발생합니다.
- 이벤트가 발생했을 때 이미지의 src 속성 값을 바꿉니다.
<h3>마우스를 대시오 당장!!</h3>
<img src="quiz/img/modal2.png">
let img = document.querySelector("img");
img.addEventListener("mouseover", () => {
img.src = "quiz/img/modal.png"
})
img.addEventListener("mouseout", () => {
img.src = "quiz/img/modal2.png"
})
길라잡의 순서에 따라 예제를 풀어봤습니다!
먼저 id와 class가 없는 <img> 태그를 만들고 src에 이미지 경로를 입력했습니다.
그리고 document.querySelector()를 사용해 문서의 이미지(img)를 선택했습니다.
먼저 마우스 포인터가 이미지 위에 올라갔을 경우에 mouseover 이벤트가, 다른 곳으로 갔을 때 mouseout 이벤트가 발생하기 때문에
img.addEventListener("mouseover")와 img.addEventListener("mouseout")를 작성하고, 해당 이벤트가 발생했을 경우 발생할 함수(() => {})를 작성했습니다.
함수에는 이벤트 발생 시 이미지의 src 속성 값을 바꿔야 하므로 각각 경로를 수정하는 속성(img.src=)을 입력했습니다.
그리고 각각 다른 이미지 경로를 입력하면 예제 완성입니다!!
2번 문제
이벤트를 활용해 필요에 따라 표시했다가 감추는 메뉴를 만들어보겠습니다.
여기서에서는 아이콘을 클릭하면 메뉴가 표시되고, 다시 클릭하면 메뉴가 숨겨지는 예제를 만들 것입니다.
버튼을 클릭할 때마다 변수와 메뉴에 .active 스타일을 토글하는 소스를 작성해 보세요.
길라잡이
- 웹 문서에 연결된 외부 스타일 시트 파일에 button.active와 nav.active 스타일이 미리 만들어져 있습니다.
- 버튼과 메뉴를 가져와서 각각 변수로 저장합니다.
- 버튼에 click 이벤트가 발생했을 때 실행할 함수를 연결하는데, 이 함수에서는 버튼과 메뉴에 active 클래스 스타일을 토글합니다.
<h3>마우스로 클릭하시오 당장!! 👉</h3>
<button></button>
<nav></nav>
let button = document.querySelector("button");
let nav = document.querySelector("nav");
//클릭하면 active가 class에 추가되도록 설정
button.addEventListener("click", () => {
//조건을 이용해 class에 click이 있으면 제거하고 없으면 추가함
button.getAttribute("class") !== "active" ? (button.classList.add("active"), nav.classList.add("active")) : (button.classList.remove("active"), nav.classList.remove("active"))
});
먼저 외부 스타일 시트는 여기서 가져오고 약간의 수정을 가했다.
<button>, <nav> 태그를 만들고 document.querySelector()를 이용해 변수 "button"과 "nav"에 각각 담았습니다.
버튼(button)에 "click" 이벤트가 발생했을 때 함수를 연결해야 하므로 button.addEventListener("click")으로 클릭 이벤트가 발생했을 때라고 만들고, 함수(() => {})를 작성했습니다.
이제 각각 버튼(button)과 메뉴(nav)에 외부 스타일 시트에 정의된 "active" class를 입력해야 하므로,
class를 추가하는 classList.add를 이용해 button.classList.add("active")와 nav.classList.add("active")를 입력합니다.
또한 다시 누르면 active가 사라져야 하기 때문에,
class를 제거하는 classList.remove를 이용해 (button.classList.remove("active"), nav.classList.remove("active")를 입력함으로써 각각 추가와 제거 함수를 만들었습니다.
그러나 여기서 문제가 생깁니다.
첫 클릭으로는 두 함수가 실행되나 두 번째부터 실행이 되질 않았습니다.
따라서 이런 경우를 조건문으로 작성해서 각각의 조건을 생성했습니다.
만약 버튼에 "active" class가 존재하지 않는다면(button.getAttribute("class") !== "active"),
버튼과 메뉴에 "active" class를 추가하고((button.classList.add("active"), nav.classList.add("active"))),
그렇지 않다면(버튼에 "active" class가 있는 경우) active를 삭제(button.classList.remove("active"), nav.classList.remove("active"))
하는 조건문을 작성하니 클릭 이벤트에 따라 표시하고 감추는 메뉴를 만들 수 있었습니다.
사실...
문제의 "토글합니다"의 의미가 클릭 또는 터치와 같은 이벤트에 반응하는 기능을 만드라는 뜻인 줄 알고 저렇게 만들었지만 알고 보니 classList.toggle()이라는 메서드가 있었다...
toggle() 메서드란?
toggle("클래스 이름")은 요소의 클래스에 특정 클래스 이름이 이미 존재하는지 확인하고, 존해하면 해당 클래스를 제거하고, 존재하지 않으면 해당 클래스를 추가합니다.
즉 toggle() 메서드는 add()와 remove()가 합쳐진 것처럼 동작하는 메서드입니다.
따라서 정답에 가깝게 코드를 작성한다면 아래와 같이 작성하면 되겠습니다.
let button = document.querySelector("button");
let nav = document.querySelector("nav");
button.addEventListener('click', () => {
nav.classList.toggle('active');
button.classList.toggle('active');
});