...
제이쿼리를 자바스크립트로
제이쿼리는 무겁고 느리다. 그리고 요즘에는 리액트, 뷰를 쓰지 제이쿼리는 레거시 프로젝트에만 잔존하는 구시대적 유물이 되어 버렸다.
그렇지만 이전에는 전세계에서 가장 많이 사용된 웹라이브러리라는 명성이 있었는데, 그 이유는 기존 자바스크립트에 없는 여러 편리한 전용 선택자나 메서드를 지원해 주었기 때문이다. 또한 제이쿼리를 이용한 파생 여러 스타일리쉬 라이브러리 숫자도 한몫했다. 하지만 퍼포먼스 문제 때문에 가능한 한 제이쿼리 사용을 지양해야 되지만, DOM을 다루는데 있어 압도적인 편리함은 포기하기엔 너무 달콤하다.
따라서 이번 포스팅에선 몇가지 자주 애용되는 제이쿼리 메서드를 바닐라 자바스크립트로 구현해보아 웹 코딩에 있어 좀 더 편하게 이용해보도록 하자.
You might not need jQuery
기존의 제이쿼리 코드를 바닐라 자바스크립트로 구현한 예제 모음 사이트 이다. 사이트 이름만 보면 알수있듯이 제이쿼리 존재를 전적으로 부인하고 있다. 다만 복잡한 메서드는 몇가지 빠져 있는 듯 하다.
You Might Not Need jQuery
Your search didn't match any comparisons.jquery📋$.getJSON('/my/url', function (data) {}); ie8+📋var request = new XMLHttpRequest(); request.open('GET', '/my/url', true); request.onreadystatechange = function () { if (this.readyState === 4) { if (this.
youmightnotneedjquery.com
제이쿼리 함수 → 바닐라 자바스크립트 리팩토링
위의 사이트에서도 없는 자주 쓰이는 제이쿼리 함수를 따로 모아 정리해 보았다.
has() 구현하기
has() 메소드는 특정 자식 요소를 가지고 있는 부모 요소들을 아주 간편하게 얻을수 있는 기능을 제공한다.
$('.category_list > li').has('ul').addClass('preclusion');
위의 제이쿼리 코드를 바닐라 자바스크립트로 구현하면 아래와 같다. 확장성을 위해 엘리먼트 리스트인 NodeList의 프로토타입 메서드로 등록해주었다.
NodeList.prototype.has = function(selector) {
// 현재 NodeList(this)를 배열로 변환하고 filter 고차함수를 돌며,
// 특정 selector를 자식으로 가지고 있는 요소만을 배열로 재구성하고 리턴
return Array.from(this).filter(e => e.querySelector(selector))
}
document.querySelectorAll('.tt_category .category_list > li').has('ul').forEach(el => {
el.querySelector('a').classList.add('preclusion');
})
siblings() 구현하기
jquery의 메소드중 하나인 siblings() 은 선택한 자신 요소와의 형제요소들을 모두 고르는 메소드이다.
HTML 요소
<div>
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
</div>
제이쿼리 (Jquery)
$('#one').siblings();
자바스크립트 (Javascript)
const siblings = (el) => [...el.parentElement.children].filter(node => node != el);
const one = document.getElementById('one');
console.log(siblings(one)); // 함수에 엘리먼트를 넣으면 그 엘리먼트의 형제요소들을 배열로 반환
// > (2) [div#two, div#three]
원리는 간단하다.
- 먼저 인자로 받은 엘리먼트의 부모엘리먼트(parentElement)를 구하고 자식(children)들을 배열로 반환한다.
- 다만 이때의 배열은 진짜 배열이 아닌 유사배열이라 filter() 고차함수를 사용하기위해선 진짜 배열로 변환해줘야 한다.
Array.from()을 이용하거나 spread문법으로 변환해주면 된다. - 그리고 filter 고차함수로 배열을 하나씩 순회하면서 인자로 받은 엘리먼트가 아닌 것들만 배열로 만들어 반환한다.
- 즉, 형제 엘리먼트로 이루어진 배열을 반환하게 된다.
prevAll() 구현하기
jquery의 메소드중 하나인 prevAll() 은 선택한 자신 요소 이전의 형제요소들을 모두 고르는 메소드이다.
제이쿼리 (Jquery)
$('div').prevAll();
자바스크립트 (Javascript)
function prevAll(element) {
var result = []; // 반환할 빈 배열을 만들고
while (element = element.previousElementSibling) // previousElementSibling가 있다면,
result.push(element); // 배열에 넣는다.
return result;
}
const prevSblings = prevAll(document.querySelector('div'));
replaceWith() 구현하기
jquery의 메소드중 하나인 replaceWith() 은 선택한 자신 요소를 매개변수로 받아온 html 텍스트로 바꿔주는 메소드 이다.
바닐라 자바스크립트에서도 replaceWith 메소드가 따로 존재하지만, 이 메소드는 매개변수로 Node만 받을 수 있어, 제이쿼리 같이 텍스트 형태의 html를 받으면 작동을 안한다.
제이쿼리 (Jquery)
$('div').replaceWith('<p><span>안녕하세요</span></p>');
자바스크립트 (Javascript)
// 바닐라 자바스크립트 replaceWith 구현 (사용하기 편하게 프로토타입 메소드로 등록)
Element.prototype.replaceWith = function (html) {
this.insertAdjacentHTML('afterend', html);
this.remove();
};
// 사용
document.querySelector('div').replaceWith('<p><span>안녕하세요</span></p>');
Wrap() 구현하기
jquery의 메소드중 하나인 replaceWith() 은 어느 요소를 래핑 하여 감싸는 기능을 해준다. 굉장히 편리한 기능중 하나이기도 하다.
HTML 요소
<p>안녕하세요.</p>
<p>devkuma입니다.</p>
제이쿼리 (Jquery)
$("p").wrap("<div class='wrap'></div>"); // <p>태그를 <div>로 감싼다.
자바스크립트 (Javascript)
function wrap(el) {
const wrappingElement = document.createElement('div');
wrappingElement.classList.add('wrap');
el.parentElement.insertBefore(wrappingElement, el);
wrappingElement.appendChild(el);
}
document.querySelectorAll('p').forEach(el => {
wrap(el);
});
... 추후 추가
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.