-
jQuery를 VanillaJS로 대체하기Frontend 2019. 9. 7. 16:07
최근 대부분의 브라우저는 ES6를 지원합니다.
jQuery는 엘리먼트 선택이나 이벤트 등록, 데이터 요청 등의 작업에서 브라우저 호환성에 신경쓰지 않고 사용할 수 있는 편리한 메소드를 제공해 주었습니다.
그러나 이제는 더 이상 라이브러리에 의존하지 않아도 되도록 브라우저 환경이 발전해 왔습니다.
이 글에서 VanillaJS는 아무 라이브러리도 사용하지 않는 순수 자바스크립트(ES6)를 의미합니다.
다음 작업들에 대해서 jQuery구현과 VanillaJS구현을 알아보겠습니다.- 엘리먼트 선택
- 이벤트
- 스타일 적용
- Document 로딩 완료 이벤트
- class 등록과 삭제
- ajax 요청
- 엘리먼트 생성
- DOM 제어
엘리먼트 선택
jQuery의 jQuery의 셀렉터인 $()는 querySelector로 대체될 수 있습니다.
// jQuery: 모든 .element 인스턴스 선택 $.(".element"); // .element 첫번째 요소만 선택 document.querySelector(".element"); // .element 모든 요소 선택 document.querySelectorAll(".element");
선택된 요소에 함수 실행
querySelectorAll()은 jQuery와 마찬가지로 배열을 리턴합니다.
jQuery 에서는 선택된 배열을 하나의 객체로 취급하여 함수를 한 번만 호출하면 되지만, VanillaJS에서는 배열을 루프를 돌며 각각 호출해 주어야 합니다.
// jQuery에서 모든 요소 안보이게 하기 $(".element").hide(); // VanillaJS에서는 .element 엘리먼트 배열의 각 원소마다 함수를 호출 document.querySelectorAll(".element").forEach(ele => { ele.style.display = "none" }
선택된 엘리먼트 배열에서 특정 요소 찾기
jQuery에서 find()는 querySelector()를 체인으로 호출하여 구현할 수 있습니다.
// jQuery에서 .container 엘리먼트들중 .element의 첫 번째 엘리먼트 가져오기 var container = $(".container"); container.find(".element"); // VanillaJS에서 동일한 기능 수행 var container = document.querySelector(".container"); container.querySelectorAll(".element");
엘리먼트 트리 구조 탐색
특정 엘리먼트의 부모, 형제 엘리먼트를 선택하는 방법입니다.
// jQuery $(".element").next(); $(".element").prev(); $(".element").parent(); // VanillaJS var element = document.querySelector(".element"); element.nextElementSibling; element.previousElementSibling; element.parentElement;
이벤트
jQuery에서 이벤트를 등록하는 방법은 여러가지가 있습니다.
VanillaJS에서는 addEventListener로 모두 대체됩니다.// jQuery $(".element").click(function(e) { /* 클릭 이벤트 처리 */ }); $(".element").mouseenter(function(e) { /* 클릭 이벤트 처리 */ }); $(document).keyup(function(e) { /* 키 입력 이벤트 처리 */ }); // vanillaJS document.querySelector(".element").addEventListener("click", (e) => { /* ... */ }); document.querySelector(".element").addEventListener("mouseenter", (e) => { /* ... */ }); document.addEventListener("keyup", (e) => { /* ... */ });
동적으로 추가되는 엘리먼트에 이벤트 등록
jQuery의 on()은 동적으로 추가되는 엘리먼트에 실시간으로 이벤트 등록을 해주는 메소드입니다.
VanillaJS에서는 우선 엘리먼트를 생성하여 DOM에 추가된 후 이벤트 핸들러를 등록해주는 방법을 사용해야 합니다.// jQuery // .item 엘리먼트가 DOM에 동적으로 추가 되는 경우에도 클릭 이벤트를 처리할 수 있다 $(".list").on("click", ".item", handleClick); // VanillaJS // 엘리먼트를 생성하고 DOM에 추가 var list = document.createElement("div"); document.querySelector(".item").appendChild(list); // 엘리먼트에 이벤트 등록 list.addEventListener("click", handleClick);
커스텀 이벤트 생성과 실행
이벤트를 수동으로 실행시키는 trigger()는 dispatchEvent()로 대체될 수 있습니다.
// jQuery // document와 .element에서 customEvent 실행 $(document).trigger("customEvent"); $(".element에서").trigger("customEvent"); // vanillaJS // customEvent 생성과 실행 document.dispatchEvent(new Event("customEvent")); document.querySelector(".element에서").dispatchEvent(new Event("customEvent"));
스타일 적용
스타일을 적용하는 css()메소드는, 각 엘리먼트의 style속성에 값을 대입하는 것으로 같은 기능을 할 수 있습니다.
// jQuery // .element 를 선택하고 텍스트 색상을 검정으로 변경 $(".element").css("color", "#000"); // vanillaJS // .element 에 해당하는 첫번째 엘리먼트를 선택하고 텍스트 색상을 검정으로 변경 document.querySelector(".element").style.color = "#000";
jQuery에서는 키-값 구조의 객체를 전달하여 여러 속성을 한번에 적용할 수 있습니다.
VanillaJS에서는 각 값을 문자열로 한번에 전달할 수 있지만, 약간의 제약사항이 있습니다.// jQuery // 여러개의 스타일 적용 $(".element").css({ "color": "#000", "Background-color": "red" }); // vanillaJS // 스타일을 한번에 적용 (그러나 이 엘리먼트에 있던 모든 CSS가 사라지고 이것으로 대체된다) element.style.cssText = "color: #000; background-color: red";
Document 로딩 완료 이벤트
모든 DOM객체가 로딩되었음을 알 수 있는 $(document).ready()를 다음과 같이 구현할 수 있습니다.
// jQuery $(document).ready(function() { /* DOM이 완전히 로드된 후에 할 일들 */ }); // vanillaJS // 메소드를 정의하고 그것을 호출한다 var ready = (callback) => { if (document.readyState != "loading") callback(); else document.addEventListener("DOMContentLoaded", callback); } ready(() => { /* DOM이 완전히 로드된 후에 할 일들 */ });
class 등록과 삭제
class관련 메소드는 classList속성으로 같은 기능을 할 수 있습니다.
// jQuery // focus 클래스의 추가, 제거, 적용/비적용 $(".element").addClass("focus"); $(".element").removeClass("focus"); $(".element").toggleClass("focus"); // vanillaJS // focus 클래스의 추가, 제거, 적용/비적용 var element = document.querySelector(".element"); element.classList.add("focus"); element.classList.remove("focus"); element.classList.toggle("focus");
classList는 여러개의 클래스를 동시에 제어할 수 있습니다.
// focus, highlighted 클래스를 추가하고, 다시 제거한다 var element = document.querySelector(".element"); element.classList.add("focus", "highlighted"); element.classList.remove("focus", "highlighted");
상호배타적인 두 개의 클래스를 서로 교체하는 replace() 메소드가 있습니다.
// focus클래스를 제거하고 blurred클래스를 추가 document.querySelector(".element").classList.replace("focus", "blurred");
엘리먼트에 특정 클래스가 적용되어 있는 확인 하려면, classList속성의 contains()메소드를 사용합니다.
// jQuery // "focus" 클래스가 적용 되어있는지에 따라 작업 수행 if ($(".element").hasClass("focus")) { // 작업 수행 } // vanillaJS // "focus" 클래스가 적용 되어있는지에 따라 작업 수행 if (document.querySelector(".element").classList.contains("focus")) { // 작업 수행 }
ajax 요청
fetch()는 비동기 네트워크 요청을 생성하는 메소드입니다. URL을 파라미터로 받아 서버 응답을 처리하는 Promise객체를 리턴합니다.
// jQuery $.ajax({ url: "data.json" }).done(function(data) { // 응답 처리 }).fail(fucntion() { // 에러 처리 }); // vanillaJS fetch("data.json") .then(data => { // 응답 처리 }).catch(error => { // 에러 처리 });
엘리먼트 생성
createElement()에 원하는 태그 이름을 전달하여 엘리먼트를 생성합니다.
// jQuery $("<div/>"); $("<span/>"); // VanillaJS document.createElement("div"); document.createElement("span");
DOM 제어
엘리먼트의 텍스트를 업데이트 하기 위해 흔히 innerHTML을 사용합니다만, 이것은 XSS공격에 취약합니다. textContent속성을 이용하면 안전하게 텍스트를 읽거나 수정할 수 있습니다.
그러나 innerHTML처럼 엘리먼트 추가와 같은 작업을 할 수 없습니다. 이 속성은 전달된 텍스트를 모두 원본(raw) 텍스트로 표현합니다.var element = document.createElement("div"); element.textContent = "Text"; // 또는 텍스트 노드를 생성하고 그것을 DOM에 추가한다. var text = document.createTextNode("Text"); element.appendChild(text);
새로운 엘리먼트의 생성과 추가는 appendChild()를 사용합니다.
// jQuery: div을 생성하고 .container에 붙인다 $(".container").append($("<div/>")); // VanillaJS: div을 생성하고 .container에 붙인다 var element = document.createElement("div"); document.querySelector(".container").appendChild(element);
'Frontend' 카테고리의 다른 글
CSS 다크 테마 구현 (0) 2019.09.14