overflow: hidden;
을 줘서, 이미지가 움직일 때, 문의 영역 밖으로 이동하면 안 보이도록 하려고 했다.이렇게 3개의 문을 감싸고 있는 box-container
밖으로 나가면, overflow: hidden;
속성들이 먹히지 않았다.
그래서, box-container
나 각 문의 영역을 담당하고 있는 box1, box2, box3들에게 overflow: hidden;
을 줘봤는데, 이 경우 3D로 움직여야할 문이 영역 밖에서는 다 잘린다. => 문을 담당하는 div인 red-door에 overflow: visible;
을 줘봤지만 먹히지 않았다. !important
까지 먹여봤지만, 여전히 효과를 보지 못했다.
overflow: hidden;
과 함께 position: absolute;
을 줘봤는데, 위와 같은 현상이 발생하지 않고 제대로 작동한다.
if( container.classList.contains("container") ){
door.classList.remove("door-open");
... 이런 식으로
}
문제는 이 if절 구문이 작동하지 않았다. !
표를 써서 반대로도 실행해봤으나, 작동되지 않아서 고민 끝에 다른 접근법을 사용했다.
for 문을 2번이나 돌려서 해결하는 방식은 쿼리로 잡아야하는 태그의 갯수가 많아지면 많아질 수록 로딩을 느리게하는 원인이 된다.
그래서, for문을 사용하지 않는 방법으로 바꿔봤다.
중요한 점은 문은 항상 딱하나만 열려있다는 점이다.
function remove_class() {
const doorAll = document.querySelectorAll(".door");
for (let i = 0; i < doorAll.length; i++) {
const element = doorAll[i];
if (element.classList.contains("door-open")) {
element.classList.remove("door-open");
}
}
const imgAll = document.querySelectorAll("img");
for (let i = 0; i < imgAll.length; i++) {
const element = imgAll[i];
if (element.classList.contains("img-open")) {
element.classList.remove("img-open");
}
}
}
function remove_class() {
const Currentdoor = document.querySelector(".door-open");
if (Currentdoor) {
Currentdoor.classList.remove("door-open");
}
const Currentimg = document.querySelector(".img-open");
if (Currentimg) {
Currentimg.classList.remove("img-open");
}
}
또한, 기존에 전역변수로 선언되있던 변수들을 전부 익명 실행함수로 만들어줘서 접근할수 없게 만들었다.
DOM에 접근하는 거는 연산 속도가 가장 느린 것 중에 하나이다.
그런 이유로, 다른 방법으로 리펙토링 해보는 것도 좋을 것같다.
ClassList에 의존하는 방법이 아닌, 좀 더 범용성이 높은 방법을 찾아보자!!
(function () {
const container = document.querySelector(".container");
let Currentdoor;
let Currentimg;
function container_control(e) {
remove_class(Currentdoor, Currentimg);
const nearest_door = e.target.closest(".door");
if (!nearest_door) return;
const nearest_img = e.target.nextElementSibling.firstElementChild;
if (!nearest_img) return;
nearest_door.classList.add("door-open");
// 쿼리셀렉터를 쓰지않고, 열려있는 문을 잡아냄
Currentdoor = nearest_door;
nearest_img.classList.add("img-open");
// 쿼리셀렉터를 쓰지않고, 잡아냄
Currentimg = nearest_img;
}
container.addEventListener("click", container_control);
})();
function remove_class(Currentdoor, Currentimg) {
// const Currentdoor = document.querySelector(".door-open");
if (Currentdoor) {
Currentdoor.classList.remove("door-open");
}
// const Currentimg = document.querySelector(".img-open");
if (Currentimg) {
Currentimg.classList.remove("img-open");
}
}
단일 책임 원칙이란 하나의 객체는 반드시 하나의 동작만의 책임을 갖는다는 원칙이다.
모듈화가 강해질수록 다른 객체와의 의존/연관성이 줄어든다. 반대로 이야기하면 모듈화가 약해질수록 다른 객체와의 의존/연관성은 크게 늘어나며, 최악의 경우 어떠한 은닉화 정책도 존재하지 않아 모듈의 메소드에 무분별하게 접근할 수도 있게된다.
객체가 담당하는 동작. 즉, 책임이 많아질 수록 해당 객체의 변경에 따른 영향도의 양과 범위가 매우 커진다. 단일 책임 원칙은 특정 객체의 책임 의존성 과중을 최대한 지양하기 위한 원칙이다.
이 단일 책임 원칙으로 현재 코드를 바라보면, 하나의 이벤트 리스너 함수가 너무 많은 역할을 담당하고 있다.
이벤트 리스너 함수는 최대한 간결하게 작성하자!!
그래야 코드가 유연해진다.
(function () {
코드 내용...
})();
팀원들과 변수명이나 함수명의 중복을 막기 위해, 미리 이름을 정해놓으면 크게 문제가 없기는 하지만, 그런 경우가 아니라면, 전역 변수 사용을 최소하기 위해서, 즉시실해 익명함수를 사용하는 습관을 들이자!!
=> 이 로직을 사용한 이후로, 어지간한 전역 변수 사용은 막을 수있었다.