{"id":1994,"date":"2021-01-13T14:11:48","date_gmt":"2021-01-13T07:11:48","guid":{"rendered":"https:\/\/wptips.dev\/?p=1994"},"modified":"2021-04-27T19:17:29","modified_gmt":"2021-04-27T12:17:29","slug":"should-you-use-jquery","status":"publish","type":"post","link":"https:\/\/pixelstudio.id\/blog\/should-you-use-jquery\/","title":{"rendered":"Should You Use jQuery in 2021? (Well Yes, but No)"},"content":{"rendered":"\n<p>WordPress already enqueues jQuery by default. Why not make use of it?<\/p>\n\n\n\n<p>That, <strong>I agree<\/strong>. You can disable it but a lot of themes and plugins depend on it. So it&#8217;s not an option for most WordPress sites.<\/p>\n\n\n\n<p>However, more and more people are moving away from jQuery. That means a lot of community resources like libraries and StackOverflow questions you found are using <strong>native JavaScript<\/strong>.<\/p>\n\n\n\n<p>Being able to understand that and adapt it to your project will be <strong>highly beneficial<\/strong> to you. Moreover, it will prepare you to use a modern framework like React or Vue.<\/p>\n\n\n\n<p>So what&#8217;s the best way to learn native JS?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Learning Native JavaScript<\/h2>\n\n\n\n<p>Check out the website below. It lists out the native equivalent of most jQuery functions.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-dark-gray-color has-yellow-background-color has-text-color has-background\" href=\"http:\/\/youmightnotneedjquery.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">YouMightNotNeedJQuery.com<\/a><\/div>\n<\/div>\n\n\n\n<p>As you can see, most of them are quite simple. For the complex ones like AJAX and Custom Event, you can create helper functions.<\/p>\n\n\n\n<p><strong>EXAMPLE<\/strong><\/p>\n\n\n\n<p>Convert the jQuery snippet below into native JS:<\/p>\n\n\n\n<pre class=\"wp-block-code is-style-default\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ jQuery\n\n\/\/ get one element\nlet $el = $( '.my-div' );\n\n\/\/ change the HTML content\n$el.html( '&lt;span&gt;Hello World&lt;\/span&gt;' );\n\n\/\/ add class\n$el.addClass( 'new-class' );<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ JS\n\nlet $el = document.querySelector( '.my-div' );\n\n\/\/ need to check whether element exists or not\nif( $el ) {\n  $el.innerHTML = '&lt;span&gt;Hello World&lt;\/span&gt;';\n\n  $el.classList.add( 'new-class' );\n} <\/code><\/pre>\n\n\n\n<p>For the second example, we will take a look at multiple elements. This is the <strong>biggest inconvenience<\/strong> of native JS. You need to loop each one like shown below:<\/p>\n\n\n\n<pre class=\"wp-block-code is-style-default\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ jQuery\n\n\/\/ get multiple elements\nlet $cards= $( '.container .card' );\n\n\/\/ add click listener to all cards at once\n$cards.on( 'click', doSomething );<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ JS\n\nlet $cards = document.querySelectorAll( '.container .card' );\n  \n\/\/ Loop and assign the listener to each item\n[].<code>forEach.call( $cards, function( $card ) =&gt; {<\/code>\n  $card.addEventListener( 'click', doSomething );\n<code>});<\/code><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Using ES6 Syntax<\/h2>\n\n\n\n<p>Some of the snippets from that website can be shortened using ES6 syntax. It&#8217;s not supported by Internet Explorer (IE), but that only covers 1.3% global usage).<\/p>\n\n\n\n<p>The notable ones are:<\/p>\n\n\n\n<p><strong>LOOPING QUERY SELECTOR ALL<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code is-style-default\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ IE9\nvar $elements = document.querySelectorAll( '.selector' );\nArray.prototype.forEach.call( $elements, function( $el ) {\n  \/\/ do something\n} );<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ ES6\nlet $elements = document.querySelectorAll( '.selector' );\nfor( let $el of $elements ) {\n  \/\/ do something\n}<\/code><\/pre>\n\n\n\n<p><strong>MATCHING SELECTOR<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code is-style-default\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ IE9\nvar matches = function(el, selector) {\n   return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);\n };\n\nmatches(el, '.my-class');<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ ES6\nel.matches( '.my-class' );<\/code><\/pre>\n\n\n\n<p><strong>SIBLINGS SELECTOR<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code is-style-default\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ IE9\nvar $items = $el.parentNode.children;\nvar $siblings = Array.prototype.filter.call( $items , function( $item ) {\n  return $item !== $el;\n});<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ ES6\nlet $items= $el.parentNode.children;\nlet $siblings = [...$items].filter( $item => $item !== $el );<\/code><\/pre>\n\n\n\n<p><strong>FIND INDEX<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code is-style-default\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ IE9\nfunction index( $el ) {\n  if (!$el) return -1;\n  var i = 0;\n  do {\n    i++;\n  } while ( $el = $el.previousElementSibling );\n  return i;\n}\n\nlet $el = document.querySelector( '.my-item' );\nlet elIndex = index( $el );<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ ES6\nlet $el = document.querySelector( '.my-item' );\nlet elIndex = [...$el.parentNode.children].indexOf( $el );<\/code><\/pre>\n\n\n\n<p><strong>AJAX \/ API CALL<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code is-style-default\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ IE10\nvar request = new XMLHttpRequest();\n request.open('GET', '\/my\/api\/url', true);\n request.onload = function() {\n   \/\/ Do something with the data\n   if (this.status &gt;= 200 &amp;&amp; this.status &lt; 400) {\n     var data = JSON.parse(this.response);\n     console.log( data );\n   }\n   \/\/ Handle error\n   else {\n     throw new Error( this.responseText );\n   }\n };\n request.send();<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ ES6\nfetch(\u00a0'\/my\/api\/url',\u00a0{\u00a0method:\u00a0'GET'\u00a0}\u00a0)\n\u00a0\u00a0.then(\u00a0<em>response<\/em>\u00a0<em>=><\/em>\u00a0{\n\u00a0\u00a0\u00a0\u00a0if(\u00a0response.status\u00a0>=\u00a0200\u00a0&amp;&amp;\u00a0response.status\u00a0&lt;\u00a0400\u00a0)\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0response.json();\n\u00a0\u00a0\u00a0\u00a0}\u00a0else\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0<em>Promise<\/em>.reject(\u00a0response.statusText\u00a0);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0}\u00a0)\n\u00a0\u00a0\/\/\u00a0Do\u00a0something\u00a0with\u00a0the\u00a0data\n\u00a0\u00a0then(\u00a0<em>data<\/em>\u00a0<em>=><\/em>\u00a0{\n\u00a0\u00a0\u00a0\u00a0console.log(\u00a0data\u00a0);\n\u00a0\u00a0}\u00a0)\n\u00a0\u00a0\/\/\u00a0Handle\u00a0error\n\u00a0\u00a0.catch(\u00a0<em>err<\/em>\u00a0<em>=><\/em>\u00a0{\n\u00a0\u00a0\u00a0\u00a0throw\u00a0new\u00a0Error(\u00a0err\u00a0);\n\u00a0\u00a0}\u00a0);<\/code><\/pre>\n\n\n\n<p>ES5 version uses a slick Promise object but it&#8217;s as long as the old one. So I recommend creating a helper function as shown in this <a rel=\"noreferrer noopener\" href=\"https:\/\/gist.github.com\/hrsetyono\/2acecc35d321f1ee21dbf648a1098faa\" target=\"_blank\">Gist<\/a>.<\/p>\n\n\n\n<p>Now you only need the snippet below to do an API call:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">myAPI.get( '\/my\/api\/url' ).then( data =&gt; {\n  \/\/ Do something with the data\n} );<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<ul><li><strong>Practice makes perfect!<\/strong> Try converting one of your projects that uses jQuery into native JS. Do it little by little and keep testing so that the functionality stays the same.<\/li><li>Learn how to use <a rel=\"noreferrer noopener\" href=\"https:\/\/pixelstudio.id\/blog\/webpack-in-wordpress\/\" target=\"_blank\"><strong>Webpack<\/strong><\/a>.<\/li><li>Learn a modern framework like <strong>Vue<\/strong>. I recommend these <a rel=\"noreferrer noopener\" href=\"https:\/\/www.youtube.com\/watch?list=PL55RiY5tL51p-YU-Uw90qQH419BM4Iz07&amp;v=nyJSd6V2DRI\" target=\"_blank\">tutorials from Academind<\/a>.<\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>It&#8217;s fine to use jQuery. But <strong>don&#8217;t use it on a large scale project<\/strong>.<\/p>\n\n\n\n<p>jQuery is naturally disorganized. So if you need to create a rather complex and interactive feature, use a proper library like Vue or React.<\/p>\n\n\n\n<p>Don&#8217;t repeat my mistake. I had to rewrite a jQuery app I made 3 years ago into Vue because it&#8217;s getting very difficult to maintain and update.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>As always, leave your question in the comment section below \ud83d\ude42<\/p><p><\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s fine to use jQuery, especially in a WordPress environment where it&#8217;s included by default. But it will be very beneficial if you learn native JavaScript.<\/p>\n","protected":false},"author":1,"featured_media":2013,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[32],"class_list":["post-1994","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-frontend","tag-javascript"],"blocksy_meta":"","_links":{"self":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1994","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/comments?post=1994"}],"version-history":[{"count":9,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1994\/revisions"}],"predecessor-version":[{"id":2030,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1994\/revisions\/2030"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media\/2013"}],"wp:attachment":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media?parent=1994"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/categories?post=1994"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/tags?post=1994"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}