본문 바로가기
Front/JavaScript & jQuery

jQuery를 바닐라 JS(Vanilla JS)로 변환하기 Pure Javascript

by 은z 2023. 2. 16.

상황

프로젝트를 진행하면서 스크립트를 짤 때, 나는 대부분 jQuery를 이용했다. 

가독성이 좋고, 편하다는 이유로 순수 자바스크립트로 코드를 작성하는 것을 미루고 있었다.

순수 자바스크립트로 작성하는 비중을 늘리기 위해, 

jQuery를 바닐라 JS(Pure JS)로 변환해보려고 한다.

 


적용

 

✔️1. 선택자( Selector )

1) 단순 선택자

DOM 요소를 선택하는 것은 가장 기본적인 요소 중 하나이다. 

 $(selector) -> querySelector() 또는 querySelectorAll()

// jQuery(.className모두 선택)
$(".className");

//.className의 첫번째 인스턴스 선택
document.querySelector(".className");

//.className 모두 선택 
document.querySelectorAll(".className");

//id 선택
document.querySelector('#idName')

//name 선택
document.querySelector('[name=issue]')
document.querySelectorAll('[name="issue"]');
document.querySelector('[name=issue]:checked'); // 체크박스 체크된 것 선택

//태그 선택
document.querySelector('#header > div > div > div > h2');

 

👀참고로, button태그의 onclick 이벤트에 매개변수로 넘겨줄 수도 있다.

<button onclick="fnName(document.querySelector('#number'), 'btn')" >버튼클릭</button>

 

2) 선택 영역의 모든 요소에 대해 함수 실행

querySelectorAll() 선택자는 쿼리와 일치하는 모든 요소를 ​​포함하는 NodeList를 반환한다.

jQuery는 객체에서 메서드를 호출하여 전체 요소 선택에 대해 jQuery로 함수를 실행한다면,  Pure JS에서는 forEach를 사용하여 요소의 NodeList를 반복해야 한다.

// with jQuery
// .list 클래스를 가진 모슨 요소 숨기기
$(".list").hide();

// Without jQuery
// .list 클래스를 가진 요소를 반복하여 꺼낸 뒤, 넘겨 준 인자 처리
document.querySelectorAll(".list").forEach(list => { list.style.display = "none" })

 

3) 다른 요소 내에서 하나의 요소 찾기

$ele.find(selector) ->  querySelector() 또는 querySelectorAll()

// With jQuery
var container = $(".container");
// Later...
container.find(".box");

// Without jQuery
var container = document.querySelector(".container");
// Later...
container.querySelector(".box");

 

4) parent(), next(), prev()

$ele.parent()-> ele.parentElement

$ele.prev()-> ele.previousElementSibling

 $ele.next()-> ele.nextElementSibling

// with jQuery
$(".box").next();
$(".box").prev();
$(".box").parent();

// Without jQuery
var box = document.querySelector(".box");
box.nextElementSibling;
box.previousElementSibling;
box.parentElement;

 

5) 그 외 요소

$("body")-> document.body

$("html")-> document.documentElement

$ele.closest('.country')-> ele.closest('.country')

$input.closest('form')-> input.form

 

 

✔️2. 이벤트 다루기

1) addEventListener

Pure JS는 addEventListener를 사용하여 이벤트 작업을 수행한다.

$ele.on(eventName, handler)-> ele.addEventListener(eventName, handler)

$ele.off(eventName)-> elem.removeEventListener(eventName, handler)

// With jQuery
$(".button").click(function(e) { /* handle click event */ });
$(document).keyup(function(e) {  /* handle key up event */  });

// Without jQuery
document.querySelector(".button").addEventListener("click", (e) => { /* ... */ });
document.addEventListener("keyup", (e) => { /* ... */ });

 

👀선택자(querySelectorAll)와 addEventListener() 사용 예시

document.querySelectorAll('.example').forEach((e) => {	//example 클래스를 보유한 모든 대상
    e.addEventListener('click', (target) => {		//클릭 이벤트를 추가함
        let thisTag = e;	//자신
        let parentTag = e.parentNode;	//1단계 위 부모
        if (thisTag.classList.contains('show')) {	//자신에게 show 클래스가 있는 경우
            thisTag.classList.remove('show')	//show 클래스 삭제
            parentTag.childNodes.forEach(e => {	//1단계 위 부모의 자식(형제) 노드
                if (e.type == 'text') {			//형제중 타입이 text인 노드
                    e.type = 'password'			//password 타입으로 변경
                }
            })
        } else {
            thisTag.classList.add('show')		//자신에게 show 클래스 추가
            parentTag.childNodes.forEach(e => {	//1단계 위 부모의 자식(형제) 노드
                if (e.type == 'password') {		//형제중 타입이 password인 노드
                    e.type = 'text'				//text 타입으로 변경
                }
            })
        }
    })
})

 

2)  동적으로 추가된 요소에 대한 이벤트 적용

DOM에 객체가 동적으로 추가되는 경우에, jQuery는 on()을 사용하면 문제 없이 작동 가능하다.

Pure JS는 DOM에 객체를 추가할 때 요소에 이벤트 핸들러를 첨부할 수 있다.

// With jQuery
$(".search-container").on("click", ".search-result", handleClick);

// Without jQuery
// Create and add an element to the DOM
var searchElement = document.createElement("div");
document.querySelector(".search-container").appendChild(searchElement);
// Add an event listener to the element
searchElement.addEventListener("click", handleClick);

 

3) 이벤트 트리거

Pure JS에서는 dispatchEvent 메서드를 사용하여 이벤트를 트리거 할 수 있다.

dispatchEvent() 메서드는 모든 요소에서 호출할 수 있으며 Event 첫 번째 인수로 사용한다.

// With jQuery
$(document).trigger("goEvent");
$(".box").trigger("goEvent");

// Without jQuery
document.dispatchEvent(new Event("goEvent"));
document.querySelector(".box").dispatchEvent(new Event("goEvent"));

 

✔️3. CSS, Style 요소

1) inline

$(".box").css("color", "#000"); -> document.querySelector(".box").style.color = "#000";

 

2) Show & Hide

document.querySelector(".box").style.display = "none";

document.querySelector(".box").style.display = "block";

 

✔️4. Class 관련

classList 속성을 이용하면 class를 쉽게 다룰 수 있다.

1) 추가, 제거, 토글

// With jQuery
$(".box").addClass("focus");
$(".box").removeClass("focus");
$(".box").toggleClass("focus");

// Without jQuery
var box = document.querySelector(".box");
box.classList.add("focus");
box.classList.remove("focus");
box.classList.toggle("focus");

//여러 클래스 제거 및 추가
box.classList.add("focus", "highlighted");
box.classList.remove("focus", "highlighted");

//클래스를 다른 클래스로 교체
box.classList.replace("focus", "focusOut");

 

2) 존재 여부 확인

$elem.hasClass(c) -> elem.classList.contains(c)

 

 

✔️5. DOM 수정

요소의 텍스트 변경, 또는 새 요소 추가할 때 innerHTML()을 사용할 수도 있지만  XSS 공격에 노출될 위험이 있다.

좀 더 안전한 대안을 사용할 수 있다.

1) 텍스트만 읽거나, 수정

// With jQuery
$(".className").text("testing");
$(".className").text();

// Without jQuery
document.querySelector(".className").textContent = "testing";
document.querySelector(".className").textContent; // Returns "testing"

2) 새 요소 구성 appendChild()

var element = document.createElement("div");
document.querySelector(".container").appendChild(element);

 

✔️6. 그 외

1) value

$input.val()

-> input.value


$input.val("hello")

-> input.value = "hello"

 

2) attribute, props

$elem.attr("placeholder") -> elem.getAttribute("placeholder")

$elem.attr("placeholder", p) -> elem.setAttribute("placeholder", p)

$el.props("disabled") -> el.disabled

$el.props("readonly") -> el.readOnly

댓글