MyTime - 크롬 익스텐션 만들기 - 8 (리팩토링)

남궁명, Nam-Goong Myoung·2020년 12월 12일
2

MyTime

목록 보기
9/12

개발을 하면서 코드를 너무 지저분하게 짠 것 같다고 느꼈다. 하루의 일정이 추가되거나 수정되면 그 하루의 박스들을 모두 지우고 다시 그려준다. 박스 요소는 하나하나 마다 이벤트 리스너를 달아주었는데, 다시 그려주는 과정에서 또 다시 이벤트 리스너를 달아주어야 했다. 또 화면을 그려주는 코드 자체도 그려주어야 하는 곳 마다 코드가 짜여져 있어서 같은 코드가 여기저기 많이 있었다. 그래서 이런 코드들을 개선하기로 했다.


이벤트 위임

newTime.addEventListener('click', (event) => {
    document.getElementById('start-time').value = i;
    parent = event.target.parentNode;

    elements.timeModalButtons[0].classList.remove('hide');
    elements.timeModal.classList.remove('hide');
});

newTime.addEventListener('click', (event) => {
    elements.timeModalButtons[1].classList.remove('hide');
    document.getElementById('time-modal').classList.remove('hide');

    let dateIndex = event.target.parentNode.getAttribute('data') * 1;
    let index = event.target.getAttribute('start-time') * 1;
    let currentData = data[dateIndex][index]; 

    document.getElementById('start-time').value = index;
    document.getElementById('end-time').value = event.target.getAttribute('end-time') * 1;
    document.getElementById('type').value = currentData.type;
    document.getElementById('contents').value = currentData.contents;
});

기존에는 박스의 요소 하나마다 이벤트 리스너를 달아주었다. 그러다 보니 화면을 다시 그려주는 부분에서 계속 이벤트 리스너를 추가해주어야하는 문제가 발생했다. 그래서 박스 요소를 감싸는 상위 요소인 time-container에 이벤트를 위임하여 이런 불필요한 작업을 없앴다.

timeContainer.addEventListener('click', (event) => {
    if(event.target.classList.contains('time')){
        if(event.target.getAttribute('type') == 0){
            //기본 박스
            document.getElementById('start-time').value = event.target.getAttribute('start-time') * 1;

            elements.timeModalButtons[0].classList.remove('hide');
            elements.timeModal.classList.remove('hide');
        }
        else{
            //입력된 박스
            elements.timeModalButtons[1].classList.remove('hide');
            document.getElementById('time-modal').classList.remove('hide');

            let dateIndex = event.target.parentNode.getAttribute('data') * 1;
            let index = event.target.getAttribute('start-time') * 1;
            let currentData = data[dateIndex][index]; 

            document.getElementById('start-time').value = index;
            document.getElementById('end-time').value = event.target.getAttribute('end-time') * 1;
            document.getElementById('type').value = currentData.type;
            document.getElementById('contents').value = currentData.contents;
        }
    }
})

Draw

let currentStartTime = 0, currentEndTime = 1, currentType = currentDay[0].type, currentId = currentDay[0].id;
for(let i = 0; i < 24; i++){
    if(i < 23){
        if(currentDay[i + 1].type == 0 || currentId != currentDay[i + 1].id){
            if(currentType == 0){
                const newTime = createElement('div', ['time']);
                newTime.addEventListener('click', (event) => {
                    document.getElementById('start-time').value = i;
                    parent = event.target.parentNode;

                    timeModalButtons[0].classList.remove('hide');
                    timeModal.classList.remove('hide');
                });

                parent.appendChild(newTime);
            }
            else{
                const newTime = createElement('div', ['time', 'checked']);
                newTime.style.background = arr[currentType][1];
                console.log(i, currentStartTime, currentEndTime);
                newTime.style.width = `${16*(currentEndTime-currentStartTime) + 6*(currentEndTime-currentStartTime-1)}px`;

                newTime.addEventListener('click', (event) => {
                    timeModalButtons[1].classList.remove('hide');
                    document.getElementById('time-modal').classList.remove('hide');
                    document.getElementById('start-time').value = s;
                    document.getElementById('end-time').value = e;
                    document.getElementById('type').value = t;
                    document.getElementById('contents').value = c;
                });

                parent.appendChild(newTime);
            }

            currentStartTime = i + 1;
            currentEndTime = currentStartTime + 1;
            currentType = currentDay[currentStartTime].type;
            currentId = currentDay[currentStartTime].id; 
        }
        else{
            currentEndTime++;
        }
    }
    else{
        if(currentType == 0){
            const newTime = createElement('div', ['time']);
            newTime.addEventListener('click', (event) => {
                document.getElementById('start-time').value = i;
                parent = event.target.parentNode;

                timeModalButtons[0].classList.remove('hide');
                timeModal.classList.remove('hide');

            });
            parent.appendChild(newTime);
        }
        else{
            const newTime = createElement('div', ['time', 'checked']);
            newTime.style.background = arr[currentType][1];
            newTime.style.width = `${16*(currentEndTime-currentStartTime) + 6*(currentEndTime-currentStartTime-1)}px`;

            newTime.addEventListener('click', (event) => {
                timeModalButtons[1].classList.remove('hide');
                document.getElementById('time-modal').classList.remove('hide');
                document.getElementById('start-time').value = s;
                document.getElementById('end-time').value = e;
                document.getElementById('type').value = t;
            });

            parent.appendChild(newTime);
        }
    }
}

이 긴 코드가 재사용 되는게 아니라 다른 곳에서는 다른 방식으로 작성되었다. 하는 일은 같은데 말이다. 그래서 이 코드를 하나의 함수로 만들고, 박스를 그릴 때 함수를 호출하게 만들었다.

const drawBox = () => {
    const boxContainers = document.getElementsByClassName('time-container');

    for(let i = 0; i < 7; i++){
        let parent = boxContainers[i];

        parent.innerHTML = '';

        let dateIndex = parent.getAttribute('data') * 1;
        let currentDay = data[dateIndex];

        let currentStartTime = 0, currentEndTime = 1, currentType = currentDay[0].type, currentId = currentDay[0].id;
        for(let i = 0; i < 24; i++){
            if(i < 23){
                if(currentDay[i + 1].type == 0 || currentId != currentDay[i + 1].id){
                    const newTime = createElement('div', ['time']);
                    newTime.setAttribute('type', currentType);
                    newTime.setAttribute('start-time', currentStartTime);
                    newTime.setAttribute('end-time', currentEndTime);

                    if(currentType != 0){
                        newTime.style.background = arr[currentType][1];
                        newTime.style.width = `${16*(currentEndTime-currentStartTime) + 6*(currentEndTime-currentStartTime-1)}px`;
                    }

                    parent.appendChild(newTime);
    
                    currentStartTime = i + 1;
                    currentEndTime = currentStartTime + 1;
                    currentType = currentDay[currentStartTime].type;
                    currentId = currentDay[currentStartTime].id; 
                }
                else{
                    currentEndTime++;
                }
            }
            else{
                const newTime = createElement('div', ['time']);
                newTime.setAttribute('type', currentType);
                newTime.setAttribute('start-time', currentStartTime);
                newTime.setAttribute('end-time', currentEndTime);

                if(currentType !== 0){
                    newTime.style.background = arr[currentType][1];
                    newTime.style.width = `${16*(currentEndTime-currentStartTime) + 6*(currentEndTime-currentStartTime-1)}px`;
                }

                parent.appendChild(newTime);
            }
        }
    }
};

drawBox();

이 뿐 아니라 변수명이 그 뜻을 제데로 담고 있지 못하다고 느꼈다. 한 시간을 나타내는 박스가 어느 곳에서는 box, 어느 곳에서는 time이라고 쓰여지고 있다. 내가 헷갈리지 않으려면 이런 부분들도 후에 개선해야 할 것 같다.

profile
아직 잘 모르겠다!

2개의 댓글

comment-user-thumbnail
2020년 12월 12일

점점 발전하구잇군요!

1개의 답글

관련 채용 정보