WEB NOTE
WEB関連の備忘録

脱・jQuery!よく使うものをVanillaJSへの置き換えをささっとメモ

Javascript

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を使います。
だって簡単で、素早く作成することができるんですもん!
なので、最新版を使い続け、レンダリングブロックをしないのであれば、全然問題ないと思います。
両方扱えるに越したことはないと思いますけど (笑)