몇 달 전에, 개발 용어 위키를 위한 JS 태그 작업을 하고자 JavaScript 코드를 아래와 같이 작성했다.
/* add Tag by click or press enter, comma, space */
var elements = document.getElementById("element");
var taskSubmit = document.getElementById("btn_add_task");
var taskBox = document.querySelector("#text_task");
var taskList = document.getElementById("list_tasks");
var taskLi = document.querySelectorAll("ul li");
/* Prevent input other than Korean, English and numbers */
taskBox.addEventListener("keyup", removeSpecial);
function removeSpecial(e) {
e.target.value = e.target.value.replace(/[^ㄱ-힣a-zA-Z0-9+#]/gi, "");
}
/* Prevent duplicate tags */
var checkSame = [];
/* click */
$("#text_task").keyup(function (e) {
var keyCode = e.keyCode;
if (e.keyCode == 13 || e.keyCode == 188 || e.keyCode == 32) {
var task = taskBox.value.trim().toLowerCase();
var newLi = document.createElement("li");
var input = document.createElement("input");
input.type = "hidden";
input.value = task;
input.name = "tagList";
var removeBtn = document.createElement("button");
var element = newLi.appendChild(document.createTextNode(task));
if (taskBox.value != "" && checkSame.includes(task) === false) {
checkSame.push(task);
taskList.appendChild(newLi);
newLi.appendChild(input);
newLi.appendChild(removeBtn);
removeBtn.innerHTML = "X";
taskBox.value = "";
removeBtn.addEventListener("click", function () {
removeBtn.parentNode.removeChild(removeBtn);
newLi.parentNode.removeChild(newLi);
checkSame.splice(checkSame.indexOf(task), 1);
});
} else {
taskBox.value = "";
alert("중복된 태그입니다.");
}
}
});
taskSubmit.addEventListener("click", clickFunction, false);
function clickFunction(e) {
var keyCode = e.keyCode;
var task = taskBox.value.trim().toLowerCase();
var newLi = document.createElement("li");
var removeBtn = document.createElement("button");
var element = newLi.appendChild(document.createTextNode(task));
if (taskBox.value != "" && checkSame.includes(task) == false) {
checkSame.push(task);
e.preventDefault();
taskList.appendChild(newLi);
newLi.appendChild(removeBtn);
removeBtn.innerHTML = "X";
taskBox.value = "";
removeBtn.addEventListener("click", function () {
removeBtn.parentNode.removeChild(removeBtn);
newLi.parentNode.removeChild(newLi);
checkSame.splice(checkSame.indexOf(task), 1);
});
} else {
taskBox.value = "";
alert("중복된 태그입니다.");
}
}
이 난잡한 코드들은, 아래 영상의 기능을 구현하기 위한 것이다.
이 JavaScript 코드가 동작을 잘 하긴 하지만, 문제는 '단지 구현만 되도록 만든 코드'였다는 점이다. 처음에 keyup으로 이벤트 리스너를 줬을 때, click 이벤트로는 먹지 않았고 그래서 그냥 중복되었다는 것을 알고 있음에도 불구하고 click에 대한 이벤트 리스너를 또 만들어서, 거기다가 똑같은 내용을 또 추가했다.
그래서 작동은 되지만 전혀 좋은 코드라고 볼 수가 없었다. 즉 재사용이 불가능한 코드라는 점이다.. 그래서 하나를 하더라도 제대로 하자는 생각을 하게 되었고, 그에 따라 개발자 친구의 말에 따라 코드 리팩토링을 했다. 우선 첫 번째 목표는, click과 keyup 각각에 대해 둘 다 작동을 제대로 할 수 있도록 하나의 통일된 function을 만드는 것이었다.
두 개에 동시에 사용될 코드라고 한다면, 우선 e.keyCode에 대한 if문부터 없애야 했다. 그래서 이를 없앤 후
function tagFunction() {
const task = taskBox.value.trim().toLowerCase();
const newLi = document.createElement("li");
const input = document.createElement("input");
input.type = "hidden";
input.value = task;
input.name = "tagList";
const removeBtn = document.createElement("button");
const element = newLi.appendChild(document.createTextNode(task));
if (taskBox.value != "" && checkSame.includes(task) === false) {
checkSame.push(task);
taskList.appendChild(newLi);
newLi.appendChild(input);
newLi.appendChild(removeBtn);
removeBtn.innerHTML = "X";
taskBox.value = "";
removeBtn.addEventListener("click", function () {
removeBtn.parentNode.removeChild(removeBtn);
newLi.parentNode.removeChild(newLi);
checkSame.splice(checkSame.indexOf(task), 1);
});
} else if (checkSame.includes(task) === true) {
taskBox.value = "";
alert("중복된 태그입니다.");
}
}
이와 같은 형태로 나타냈다. 그 다음에, click에 대해서는 바로 tagFunction이 실행될 수 있도록
taskSubmit.addEventListener("click", tagFunction, false);
이와 같이 처리했고, keyup에 대해서는, keyCode에 대한 if문이 필요했기 때문에
taskBox.addEventListener("keyup", function (e) {
const keyCode = e.keyCode;
if (e.keyCode == 188 || e.keyCode == 32 || e.keyCode == 13) {
tagFunction();
}
});
이와 같이 188 (,), 32(스페이스바), 13(엔터) 을 눌렀을 때 tagFunction이 실행되도록 하였다.
종합하면,
/* add Tag by click or press enter, comma, space */
var elements = document.getElementById("element");
var taskSubmit = document.getElementById("btn_add_task");
var taskBox = document.querySelector("#text_task");
var taskList = document.getElementById("list_tasks");
var taskLi = document.querySelectorAll("ul li");
/* Prevent input other than Korean, English and numbers */
taskBox.addEventListener("keyup", removeSpecial);
taskSubmit.addEventListener("click", removeSpecial);
function removeSpecial(e) {
e.target.value = e.target.value.replace(/[^ㄱ-힣a-zA-Z0-9+#]/gi, "");
}
let checkSame = [];
taskBox.addEventListener("keyup", function (e) {
const keyCode = e.keyCode;
if (e.keyCode == 188 || e.keyCode == 32 || e.keyCode == 13) {
tagFunction();
}
});
taskSubmit.addEventListener("click", tagFunction, false);
function tagFunction() {
const task = taskBox.value.trim().toLowerCase();
const newLi = document.createElement("li");
const input = document.createElement("input");
input.type = "hidden";
input.value = task;
input.name = "tagList";
const removeBtn = document.createElement("button");
const element = newLi.appendChild(document.createTextNode(task));
if (taskBox.value != "" && checkSame.includes(task) === false) {
checkSame.push(task);
taskList.appendChild(newLi);
newLi.appendChild(input);
newLi.appendChild(removeBtn);
removeBtn.innerHTML = "X";
taskBox.value = "";
removeBtn.addEventListener("click", function () {
removeBtn.parentNode.removeChild(removeBtn);
newLi.parentNode.removeChild(newLi);
checkSame.splice(checkSame.indexOf(task), 1);
});
} else if (checkSame.includes(task) === true) {
taskBox.value = "";
alert("중복된 태그입니다.");
}
}
이와 같은 방식인 것이다. 쓸 데 없는 중복은 좀 줄였으나 아직 코드가 좋은 코드라고 생각하진 않는다. 위에 코드에서
$("#text_task").keyup(function(e) { ... });
이 부분은, Vanilla JS로 바꿨을 때 오류가 났던 거라 어쩔 수 없이 jQuery로 한 건데, 이 부분도 해결이 되어서 다행이다.
'토이프로젝트' 카테고리의 다른 글
2/8 maplestory JS 코드 리팩토링 완성 (0) | 2021.02.08 |
---|---|
2/2 maplestory JS 코드 리팩토링 (0) | 2021.02.02 |
1/20 maplestory JavaScript 코드 리팩토링 (0) | 2021.01.20 |
1/10 JavaScript를 이용해서 클릭 시 이미지 변경하기 (0) | 2021.01.10 |
1/2 음식 추천 서비스 토이프로젝트 시작 (0) | 2021.01.02 |