ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

    댓글

Designed by Tistory.