10. Native DOM 선택

React, Vue같은 프론트엔드 라이브러리들이 주도권을 차지하는 동안 DOM을 바로 처리하는 것은 안티패턴이 되었습니다. jQuery의 중요성은 줄어들었습니다. 이번 글은 대부분의 jQuery 메소드의 대안을 IE 10 이상을 지원하는 Native(바닐라 자바스크립트) 구현으로 소개합니다.

1.selector로 찾기

// jQuery
$('selector');

// Native
document.querySelectorAll('selector');

2.class로 찾기

// jQuery
$('.class');

// Native
document.querySelectorAll('.class');

// 또는
document.getElementsByClassName('class');

3.id로 찾기

// jQuery
$('#id');

// Native
document.querySelector('#id');

// 또는
document.getElementById('id');

// 또는
window['id']

4. 속성(attribute)으로 찾기

// jQuery
$('a[target=_blank]');

// Native
document.querySelectorAll('a[target=_blank]');

5.자식에서 찾기

// jQuery
$el.find('li');

// Native
el.querySelectorAll('li');

6.형제 엘리먼트

// jQuery
$el.siblings();

// Native - latest, Edge13+
[...el.parentNode.children].filter((child) =>
  child !== el
);
// Native (alternative) - latest, Edge13+
Array.from(el.parentNode.children).filter((child) =>
  child !== el
);
// Native - IE10+
Array.prototype.filter.call(el.parentNode.children, (child) =>
  child !== el
);

7. 이전 엘리먼트

// jQuery
$el.prev();

// Native
el.previousElementSibling;

8. 다음 엘리먼트

// jQuery
$el.next();

// Native
el.nextElementSibling;

9. 모든 이전 형제 엘리먼트

// jQuery (선택적 필터 셀렉터)
$el.prevAll($filter);

// Native (선택적 필터 함수)
function getPreviousSiblings(elem, filter) {
  var sibs = [];
  while (elem = elem.previousSibling) {
      if (elem.nodeType === 3) continue; // 텍스트 노트 무시
      if (!filter || filter(elem)) sibs.push(elem);
  }
  return sibs;
}

10. 모든 다음 형제 엘리먼트

// jQuery (선택적 셀렉터 필터)
$el.nextAll($filter);

// Native (선택적 필터 함수)
function getNextSiblings(elem, filter) {
    var sibs = [];
    var nextElem = elem.parentNode.firstChild;
    do {
        if (nextElem.nodeType === 3) continue; // 텍스트 노드 무시
        if (nextElem === elem) continue; // 대상 elem 무시
        if (nextElem === elem.nextElementSibling) {
            if (!filter || filter(elem)) {
                sibs.push(nextElem);
                elem = nextElem;
            }
        }
    } while(nextElem = nextElem.nextSibling)
    return sibs;
}

11. Closest

현재 엘리먼트부터 document로 이동하면서 주어진 셀렉터와 일치하는 가장 가까운 엘리먼트를 반환합니다.

// jQuery
$el.closest(selector);

// Native - 최신 브라우저만, IE는 미지원
 el.closest(selector);

// Native - IE10 이상
function closest(el, selector) {
  const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

  while (el) {
    if (matchesSelector.call(el, selector)) {
      return el;
    } else {
      el = el.parentElement;
    }
  }
  return null;
}

12. Parents Until

주어진 셀렉터에 매칭되는 엘리먼트를 찾기까지 부모 태그들을 위로 올라가며 탐색하여 저장해두었다가 DOM 노드 또는 jQuery object로 반환합니다.

// jQuery
$el.parentsUntil(selector, filter);

// Native
function parentsUntil(el, selector, filter) {
  const result = [];
  const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

  // match start from parent
  el = el.parentElement;
  while (el && !matchesSelector.call(el, selector)) {
    if (!filter) {
      result.push(el);
    } else {
      if (matchesSelector.call(el, filter)) {
        result.push(el);
      }
    }
    el = el.parentElement;
  }
  return result;
}

13. Form - Input/Textarea

// jQuery
$('#my-input').val();

// Native
document.querySelector('#my-input').value;

14. e.currentTarget이 몇 번째 .radio 인지 (index )구하기

// jQuery
$(e.currentTarget).index('.radio');

// Native
Array.from(document.querySelectorAll('.radio')).indexOf(e.currentTarget);
또는
Array.prototype.indexOf.call(document.querySelectorAll('.radio'), e.currentTarget);

------------------------ Native (index를 사용하는 부분입니다.) ------------------------
1번.
Array.from(document.querySelectorAll('.accordion-inner button'), function(el) {
        el.addEventListener('click', function() {
            console.log( index(document.querySelectorAll('.accordion-inner button'), el) );
        });
});

2번. 
const els = Array.from(document.querySelectorAll('.tab'));
    els.forEach((el) => {
        el.addEventListener('click', function(e) {
            console.log( index(document.querySelectorAll('.tab'), e.currentTarget) );
        });
});

15. 속성 얻기

// jQuery
$el.attr('foo');

// Native
el.getAttribute('foo');

16. 속성 설정하기

// jQuery, DOM 변형 없이 메모리에서 작동됩니다.
$el.attr('foo', 'bar');

// Native
el.setAttribute('foo', 'bar');

17. data - 속성 얻기

// jQuery
$el.data('foo');

// Native (`getAttribute` 사용)
el.getAttribute('data-foo');

// Native (IE 11 이상의 지원만 필요하다면 `dataset`을 사용)
el.dataset['foo'];

18. 문자열을 포함하는 셀렉터(대소문자 구분)

// jQuery
$("selector:contains('text')");

// Native
function contains(selector, text) {
  var elements = document.querySelectorAll(selector);
  return Array.from(elements).filter(function(element) {
    return RegExp(text).test(element.textContent);
  });
}

Last updated