脱・jQuery!よく使うものをVanillaJSへの置き換えをささっとメモ
VanillaJS(ただのJavaScript)を書くとき、IE Fack っていつも思いながら、終焉を迎える2025年10月14日まで莫大な時間と労力を無駄にしています。
ポリフィルを入れることで一部の対応は可能ですが、対応させるなら古い書き方をするのが無難ですね。
個人的に、「IEシェア多い→対応させる→対応しているサイトが多いし続ける」って負の連鎖が起きて?日本ではサポート終了までなくなる気がしません。
使う側もそうですが、製作側もどこかで割り切る必要があると思います。。。
なんで脱jQuery?ってのはいったん置いといて、さっそく置き換えていきます。
※jQuery の置き換えのメモなので、意味は省略しています。
$(function(){})の置き換え
/* ===== jQuery ===== */
$(function(){
//コード
}
/* ===== Vanilla ===== */
document.addEventListener('DOMContentLoaded',function(){
//コード
});
セレクタ系の置き換え
/* ===== jQuery =====*/
$('#id');
$('.class');
/* ===== Vanilla ===== */
document.querySelector('#id'); //単一要素
document.querySelectorAll('.class'); //複数要素
.querySelectorAll()は配列要素として取得されるので、注意!
ちなみにDOMリストは Nodelist になります。
子要素、親要素、兄弟要素の取得
子要素の取得
/* ===== jQuery ===== */
$('xxx').find('.child');
$('xxx').children();
$('xxx').children('.child');
$('xxx').children().first();
$('xxx').children().last();
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
// find
xxx.querySelectorAll('.child');
//children
xxx.children;
//children('.child')
let childArr = [];
const allChild = xxx.children;
for(let i = 0; i < allChild.length; i++) {
const child = allchild[i];
if(child.classList.contains('child')) {
childArr.push(child); //配列にする必要がなければここに処理
}
}
//first
xxx.firstElementChild;
//last
xxx.lastElementChild;
親要素の取得
/* ===== jQuery ===== */
$('xxx').parent();
$('xxx').closest('elm');
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//parent
xxx.parentNode;
//closest ※IEはポリフィル
xxx.closest('elm');
兄弟要素の取得
/* ===== jQuery ===== */
$('xxx').next();
$('xxx').prev();
/* ===== vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//next
xxx.nextElementSibling;
//prev
xxx.previousElementSibling;
その他
/* ===== jQuery =====*/
$('xxx').eq(1);
$('xxx').eq(-1);
$('xxx').not('elm');
$('xxx').slice(2)
/* ===== vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//eq
xxx[1];
xxx[xxx.length - 1];
//not
for(let i = 0; i < xxx.length; i++) {
if(!xxx[i].classList.contains('elm')) {
xxx[i]. //ここに処理
}
}
//slice
for (let i = 1; i < xxx.length; i++) {
li[i]. //ここに処理
}
要素の存在チェック
/* ===== jQeury ===== */
if($('xxx').length) {
//あれば処理
}
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//単一要素 querySelector
if(xxx !== null) {
//あれば処理
}
//複数要素 querySelectorAll
if(xxx.length) {
//あれば処理
}
クラスの操作
/* ===== jQuery ===== */
if($('xxx').hasClass('elm')) {}
$('xxx').addClass('elm');
$('xxx').removeClass('elm');
$('xxx').toggleClass('elm');
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//hasclass
if(xxx.classList.contains('elm')) {}
//addclass
xxx.classList.add('elm');
//removeclass
xxx.classList.remove('elm');
//toggleclass
xxx.classList.toggle('elm');
複数の要素にクラス名を付けたりするためには for文 などでループさせて処理する必要があります。
for (let i = 0; i < xxx.length; i++) {
xxx[i].classList.add('elm');
xxx[i].classList.remove('elm');
xxx[i].classList.toggle('elm');
}
属性・要素の操作
/* ===== jQuery ===== */
$('xxx').attr('data-xxx');
$('xxx').attr('data-xxx','add');
$('xxx').removeAttr('data-xxx');
$('xxx').prop('checked');
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//属性取得
xxx.getAttribute('data-xxx');
//属性セット
xxx.setAttribute('data-xxx','add');
//属性削除
xxx.removeAttribute('data-xxx');
//prop
xxx.checked;
スタイルの操作
/* ===== jQuery ===== */
$('xxx').css('color');
$('xxx').css('color','#fff');
$('xxx').css({
'color': '#fff',
'backgorund-color': '#000'
});
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//スタイル取得
xxx.style.color;
//スタイルセット
xxx.style.color = '#fff';
//複数セット ※一括でセットできない。
xxx.style.color = '#fff';
xxx.style.backgroundColor = '#000';
要素のサイズを取得
/* ===== jQuery ===== */
$('xxx').innerWidth();
$('xxx').innerHeight();
$('xxx').outerWidth();
$('xxx').outerHeight();
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//innerWidth・innerHeight
xxx.clientWidth();
xxx.clientHeight();
//outerWidth・outerHeight
xxx.offsetWidth;
xxx.offsetHeight;
要素の中身の操作
/* ===== jQuery ===== */
$('xxx').text();
$('xxx').text('テキストを追加');
$('xxx').html();
$('xxx').html('<p>テキストを追加</p>');
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//text
xxx.textContent;
xxx.textContent = 'テキストを追加';
//html
xxx.innerHTML;
xxx.innerHTML = '<p>テキストを追加</p>';
要素の挿入
/* ===== jQuery ===== */
$('xxx').before($add);
$('xxx').after($add);
$('xxx').append($add);
$('xxx').prepend($add);
$('xxx').wrap('<div></div>');
$('xxx').wrapInner('<div></div>');
/* ===== Vanilla ===== */
const xxx = document.querySelectorAll('xxx');
//before
xxx.parentNode.insertBefore(add, xxx);
//after
xxx.parentNode.insertBefore(add,xxx.nextElementSibling);
//append
xxx.appendChild(add);
//prepend
xxx.insertBefore(add,xxx.firstElementChild);
//wrap
xxx.outerHTML = '<div>${xxx.outerHTML}</div>';
//wrapInner
xxx.innerHTML = '<div>${xxx.innerHTML}</div>'
各イベント
loadイベント
/* ===== jQuery ===== */
$(window).on('load',function(){
//ここに処理
});
/* ===== Vanilla ===== */
window.addEventListener('load',function(){
//ここに処理
});
clickイベント
/* ===== jQuery ===== */
$('xxx').on('click',function(){
//ここに処理
});
/* ===== Vanilla ===== */
xxx.addEventListener('click',function(){
//ここに処理
});
hoverイベント
/* ===== jQuery ===== */
$('xxx').hover(function(){
//乗った時の処理
},function(){
//離れた時の処理
});
/* ===== Vanilla ===== */
xxx.addEventListener('mouseover',function(){
//乗った時の処理
});
xxx.addEventListener('mouseout',function(){
//離れた時の処理
});
scrollイベント
/* ===== jQuery ===== */
$('window').on('scroll',function(){
//ここに処理
});
/* ===== Vanilla ===== */
window.addEventListener('scroll',function(){
//ここに処理
});
フォームの操作
/* ===== jQuery ===== */
$('xxx').val();
$('xxx').val('value');
$('xxx').prop('checked', true);
/* ===== Vanilla ===== */
//val
xxx.value;
xxx.value = 'value';
//checked
xxx.checked = true;
座標系
/* ===== jQuery ===== */
const offset = $('xxx').offset();
offset.top;
offset.left;
$(window).scrollTop();
/* ===== Vanilla ===== */
//offset
const offset = xxx.getBoundingClientRect(); //{x, y, whidth, height, top, right, bottom, left}
offset.top;
offset.left
//scrollTop
window.pageYOffset;
さいごに なぜ脱jQueryするべきなの
結論から先に述べると、最新版を使い続け、レンダリングブロックをしないのであれば全然、脱jQyeryで問題ないと思います。
jQueryは、JavaScriptをより簡易的に記述でき、各ブラウザへの互換性を持つため非常に便利なライブラリです。
では、なぜ脱jQueryという風潮が起きてしまっているのでしょうか。私自身は大きく4つあると思っています。
ブラウザ間の差異がなくなりつつある
昔は、ブラウザによって表示が異なるという現象が多々ありました。
特にInternetExplorerとか、InternetExplorerとか、InternetExplorer、、、
そんなブラウザによる違いを解決してくれたのがjQueryです。
しかし、ブラウザが進化を続けてきた結果、極端なブラウザ間の差異はなくなってきました。
つまり、ブラウザ間の差異解消のために、jQueryを導入する必要性が薄れてきたのです。
パフォーマンスを重視される
パフォーマンスの向上に目が向けられている昨今、ブラウザ間での差異がほとんどないため、無理にリソースの読み込みによるパフォーマンスの低下を引き起こす必要がなくなったのです。
他の便利なライブラリ、フレームワークの登場
jQueryはフロントエンド界ではかなりの古株で、たくさんのシェアを持っているライブラリですが、10年以上たつと、jQueryの他にも便利なライブラリ、フレームワークが登場します。
最後のひとつでも述べますが、WEBサイトは「単なる文書を伝える」だけではなくなりました。それに伴い、JavaScriptが担う部分も複雑化しました。
Angular、React、Vueなど、どれか一つマスターすれば、世の中のだいたいのWEBサービスを作れるようになります。
新しいライブラリ、フレームワークが登場し、より高度なことがWEB上で実現できるようになったため「脱jQuery」が出てきたのです。
WEBページのアプリケーション化
もともとWEBサイトは、HTMLとCSSで作るモノでした。
HTMLで文書を書き、CSSでタイトルの文字を大きくしたり、行間を整えて見やすくするためにスタイリングします。
時は流れ、WEBサイトは「単なる文書を伝える」だけではなくなりました。
ショッピングサイトが登場し、WEB上で買い物ができるようになったり、ホテルや映画、お店などの予約ができるようになったり、SNSでユーザー同士がつながれるようになったりと、様々なWEBサービスを展開できるようになりました。
それに伴い、JavaScriptが担う部分も複雑化しました。
昔はピコピコ光ったり、アニメーションを付けたりとCSS+α的な部分で使われることがほとんどでした。
しかし、今現在jQueryが使われる部分はスライドだったり、タブの切り替えだったりとCSS+αな部分がほとんどです。
最近の複雑で巨大なWEBサービス、リッチなゲーム、アプリのような高度なシステム、複雑なUI、サーバー間のやり取りをjQueryでやるのが難しくなってきたのです。
だったらjQueryをやめるべき?
そんなことはないと思います。
実際に私自身、コーポレートサイトなど、普通のサイトを作る際はjQueryを使います。
だって簡単で、素早く作成することができるんですもん!
なので、最新版を使い続け、レンダリングブロックをしないのであれば、全然問題ないと思います。
両方扱えるに越したことはないと思いますけど (笑)