Share
Trang chủ / Tất cả hướng dẫn / Không phân loại / Bạn có thực sự cần jQuery

Bạn có thực sự cần jQuery

Giới thiệu các hàm của DOM API, Thay thế các hàm jQuery, khi chỉ có nhu cầu đơn giản, thì bạn không cần phải dùng nguyên thư viện jQuery, DOM API đã hỗ trợ.

Ngày nay, môi trường lập trình front-end phát triển rất nhanh chóng, các trình duyệt hiện đại đã cung cấp các API đủ tốt để làm việc với DOM/BOM. Bạn không còn cần phải học về jQuery nữa. Đồng thời, nhờ sự ra đời của các thư viện như React, Angular và Vue đã khiến cho việc can thiệp trực tiếp vào DOM trở thành một việc không tốt. jQuery đã không còn quan trọng như trước nữa. Bài viết này tổng hợp những cách để thay thế các hàm của jQuery bằng các hàm được hỗ trợ bởi trình duyệt, và hó cũng hoạt động trên IE 10+

Query Selector

Đối với những selector phổ biến như class, id hoặc thuộc tính thì chúng ta có thể sử dụng document.querySelector hoặc document.querySelectorAll để thay thế cho jQuery selector. Sự khác biệt của hai hàm này là ở chỗ:

  • document.querySelector trả về element đầu tiên được tìm thấy
  • document.querySelectorAll trả về tất cả các element được tìm thấy dưới dạng một instance của NodeList. Nó có thể được convert qua array bằng cách
    [].slice.call(document.querySelectorAll(selector) || []);
  • Nếu không có element nào được tìm thấy, thì jQuery sẽ trả về một array rỗng [] trong khi đó DOM API sẽ trả về null. Hãy chú ý đến Null Pointer Exception. Bạn có thể sử dụng toán tử || để đặt giá trị default nếu như không có element nào được tìm thấy, ví dụ như []document.querySelectorAll(selector) || []

Chú ý : document.querySelectordocument.querySelectorAll hoạt động khá CHẬM, hãy thử dùng getElementById, document.getElementsByClassName hoặc document.getElementsByTagName nếu bạn muốn đạt hiệu suất tốt hơn.

Query bằng selector

// jQuery
$('selector');

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

Query bằng class

// jQuery
$('.class');

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

// hoặc
document.getElementsByClassName('class');

Query bằng id

// jQuery
$('#id');

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

// hoặc
document.getElementById('id');

Query bằng thuộc tính

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

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

Tìm bất cứ gì.

Tìm node

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

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

Tìm body

// jQuery
$('body');

// Native
document.body;

Lấy thuộc tính

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

// Native

Lấy giá trị của thuộc tính data

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

// Native
// using getAttribute
el.getAttribute('data-foo');
// you can also use `dataset` if only need to support IE 11+
el.dataset['foo'];

Tìm element cùng level/trước/sau

Element cùng level

// jQuery
$el.siblings();

// Native
[].filter.call(el.parentNode.children, function(child) {
  return child !== el;
});

Element ở phía trước

// jQuery
$el.prev();

// Native
el.previousElementSibling;

Element ở phía sau

// next
$el.next();
el.nextElementSibling;

Element gần nhất

Trả về element đầu tiên có selector khớp với yêu cầu khi duyệt từ element hiện tại trở lên tới document.

// jQuery
$el.closest(queryString);

// Native
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;
}

Tìm parent

Truy ngược một cách đệ quy tổ tiên của element hiện tại, cho đến khi tìm được một element tổ tiên ( element cần tìm ) mà element đó là con trực tiếp của element khớp với selector được cung cấp, Return lại element cần tìm đó.

// 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;
}

Form

Input/Textarea

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

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

Lấy index của e.currentTarget

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

// Native
[].indexOf.call(document.querySelectAll('.radio'), e.currentTarget);

Nội dung Iframe

$(‘iframe’).contents() trả về thuộc tính contentDocument của iframe được tìm thấy

Nội dung iframe

// jQuery
$iframe.contents();

// Native
iframe.contentDocument;

Query Iframe

// jQuery
$iframe.contents().find('.css');

// Native
iframe.contentDocument.querySelectorAll('.css');

CSS & Style

CSS

Lấy style

// jQuery
$el.css("color");

// Native
// NOTE: Bug đã được biết, sẽ trả về 'auto' nếu giá trị của style là 'auto'
const win = el.ownerDocument.defaultView;
// null means not return presudo styles
win.getComputedStyle(el, null).color;

Đặt style

// jQuery
$el.css({ color: "#ff0011" });

// Native
el.style.color = '#ff0011';

Lấy/Đặt Nhiều style

Nếu bạn muốn đặt nhiều style một lần, bạn có thể sẽ thích phương thức setStyles trong thư viện oui-dom-utils.

Thêm class và element

// jQuery
$el.addClass(className);

// Native
el.classList.add(className);

Loại bỏ class class ra khỏi element

// jQuery
$el.removeClass(className);

// Native
el.classList.remove(className);

Kiểm tra class của element

// jQuery
$el.hasClass(className);

// Native
el.classList.contains(className);

Toggle class

// jQuery
$el.toggleClass(className);

// Native
el.classList.toggle(className);

Chiều rộng, chiều cao

Về mặt lý thuyết thì chiều rộng và chiều cao giống như nhau trong cả jQuery và DOM API:

Chiều rộng của window

// window height
$(window).height();
// trừ đi scrollbar
window.document.documentElement.clientHeight;
// Tính luôn scrollbar
window.innerHeight;

Chiều cao của Document

// jQuery
$(document).height();

// Native
document.documentElement.scrollHeight;

Chiều cao của element

// jQuery
$el.height();

// Native
function getHeight(el) {
  const styles = this.getComputedStyles(el);
  const height = el.offsetHeight;
  const borderTopWidth = parseFloat(styles.borderTopWidth);
  const borderBottomWidth = parseFloat(styles.borderBottomWidth);
  const paddingTop = parseFloat(styles.paddingTop);
  const paddingBottom = parseFloat(styles.paddingBottom);
  return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
}
// chính xác tới số nguyên(khi có thuộc tính <code>box-sizing</code> là <code>border-box</code>, nó là <code>height</code>; khi <code>box-sizing </code>là <code>content-box</code>, nó là <code>height + padding + border</code>)
el.clientHeight;
// Chính xác tới số thập phân(khi <code>box-sizing</code> là <code>border-box</code>, nó là <code>height</code>; khi <code>box-sizing</code> là <code>content-box</code>, nó là <code>height + padding + border</code>)
<code>el.getBoundingClientRect().height;</code>

Position & Offset

Position

// jQuery
$el.position();

// Native
{ left: el.offsetLeft, top: el.offsetTop }

Offset

// jQuery
$el.offset();

// Native
function getOffset (el) {
  const box = el.getBoundingClientRect();

  return {
    top: box.top + window.pageYOffset - document.documentElement.clientTop,
    left: box.left + window.pageXOffset - document.documentElement.clientLeft
  }
}

Scroll Top

// jQuery
$(window).scrollTop();

// Native
(document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;

Thao tác với DOM

Loại bỏ

// jQuery
$el.remove();

// Native
el.parentNode.removeChild(el);

Text

Lấy text

// jQuery
$el.text();

// Native
el.textContent;

Đặt giá trị text

// jQuery
$el.text(string);

// Native
el.textContent = string;

HTML

Lấy HTML

// jQuery
$el.html();

// Native
el.innerHTML;

Đặt giá trị HTML

// jQuery
$el.html(htmlString);

// Native
el.innerHTML = htmlString;

Append

append một element sau element con cuối cùng của element cha

// jQuery
$el.append("
<div id='container'>hello</div>

");

// Native
let newEl = document.createElement('div');
newEl.setAttribute('id', 'container');
newEl.innerHTML = 'hello';
el.appendChild(newEl);

Prepend

// jQuery
$el.prepend("
<div id='container'>hello</div>

");

// Native
let newEl = document.createElement('div');
newEl.setAttribute('id', 'container');
newEl.innerHTML = 'hello';
el.insertBefore(newEl, el.firstChild);

insertBefore

Chèn một node vào trước element được query.

// jQuery
$newEl.insertBefore(queryString);

// Native
newEl.insertBefore(document.querySelector(queryString));

insertAfter

Chèn node vào sau element được query

// jQuery
$newEl.insertAfter(queryString);

// Native
function insertAfter(newEl, queryString) {
  const parent = document.querySelector(queryString).parentNode;

  if (parent.lastChild === newEl) {
    parent.appendChild(newEl);
  } else {
    parent.insertBefore(newEl, parent.nextSibling);
  }
},

Events

Bind event bằng on

// jQuery
$el.on(eventName, eventHandler);

// Native
el.addEventListener(eventName, eventHandler);

Unbind event bằng off

// jQuery
$el.off(eventName, eventHandler);

// Native
el.removeEventListener(eventName, eventHandler);

Trigger

// jQuery
$(el).trigger('custom-event', {key1: 'data'});

// Native
if (window.CustomEvent) {
  const event = new CustomEvent('custom-event', {detail: {key1: 'data'}});
} else {
  const event = document.createEvent('CustomEvent');
  event.initCustomEvent('custom-event', true, true, {key1: 'data'});
}

el.dispatchEvent(event);

Hàm tiện ích

isArray

// jQuery
$.isArray(range);

// Native
Array.isArray(range);

Trim

// jQuery
$.trim(string);

// Native
string.trim();

Object Assign

Mở rộng, sử dụng object.assign https://github.com/ljharb/object.assign

// jQuery
$.extend({}, defaultOpts, opts);

// Native
Object.assign({}, defaultOpts, opts);

Contains

// jQuery
$.contains(el, child);

// Native
el !== child && el.contains(child);

Lời kết

Sau những gì các bạn vừa đọc ở trên, chúng ta có thể thaaysd là DOM API ngày càng mạnh mẽ hơn, nhưng để một thư viện tồn tại và phát triển mạnh mẽ thì còn rất nhiều yếu tố khác. Sự tiện dụng, tính đóng gói, tính đồng nhất … Và một yếu tố quan trọng khác để jQuery có sức mạnh của mình đó là ở các thư viện phụ thuộc vào nó. Chúng ta có rất nhiều thư viện bổ sung cho jQuery, Bootstrap cũng sử dụng jQuery, vì vậy rất khó để chúng ta làm việc mà không hề biết jQuery là gì.

Tuy nhiên, đối với những công việc nhỏ, đơn giản, thì bạn không cần thiết phải dùng đến jquery, chỉ cần dùng những gì DOM API hỗ trợ là đủ, vì suy cho cùng, cái mà bạn đang làm việc trực tiếp chính là DOM, và nếu DOM API hỗ trợ đầy đủ, thì đơn giản là hãy sử dụng nó.