元々JQueryを多用していた物をVanilla JS(普通のJavascript)に徐々に書き換えていくポイントメモ的な物と関連記事を集めてきたもの。
書き換えの前提
- 時間がある時に、ちょっとずつ変えていく。一気に変更しない。
- 普通のJavascriptであれば5年以上は持ちそう。XMLHttpRequestなんて20年前からある。
- JQueryを無理に無くそうとはしない。JQueryじゃなくても良いところを書き換えていく。(ただしJQuery1.xは脆弱性があるので3.xにする)
- 中途半端に変えるとわかりにくくなる場合もある。時間と人に余裕があるなら最初から作り直すことも考える。
- そのままでIE11でも動くようにする。Babelの使用までは考えない。
- なるべく自力で書き換える場合の例なので、実際はある程度共通化したり、ライブラリ等を活用した方が良いかもしれない。
ブラウザによって未対応な物を押さえておく。
Chromeであれば、ES6以降の多くをサポートしているが、特にIEは対応できていないものが多いので把握しておく必要がある。
内容によってはPolyfillを使うことで対応できることもあるが、それによってJSのサイズが肥大化してしまう可能性もある。
- ECMAScript 6 compatibility table
- [Javascript] IE11非対応らしきモノをかき集める
- JavaScriptのブラウザごとの互換性をポリフィル・Babelで解決する!
なお、let
は、IE11の場合は使用出来るが、SafariはiOS10以上しか使えないため、iPhone4Sや、iOSをアップデートしていない端末があった場合は、動作しない。
JQueryオブジェクトをJavascriptのDOMに変換
var elm1 = $('.test');
const dom1 = elm1[0]; // インデックス0番目からDOMが取得できる
const dom2 = elm1.get(0); // インデックス0番目からDOMが取得できる
ページ読み込み時のイベント処理
// JQueryの場合
$(function(){
// DOM利用可能になった場合の処理
});
// Javascriptの場合
document.addEventListener("DOMContentLoaded", function(){
// DOM利用可能になった場合の処理
});
// JQueryの場合
$(window).on("load", function(){
// コンテンツが読み込み完了後の処理
});
// Javascriptの場合
window.addEventListener("load", function(){
// コンテンツが読み込み完了後の処理
});
クリックされたときのイベント処理
// JQueryの場合(対象は一つのみ)
$('.btn').on('click',function(){
// 処理
});
// Javascriptの場合(対象は一つのみ)
const btn = document.querySelector(".btn");
btn.addEventListener("click", function(){
// 処理
});
// JQueryの場合(対象は複数ある)
$('.btn').on('click',function(){
// 処理
});
// Javascriptの場合(対象は複数ある) for文の場合
const btns = document.querySelectorAll(".btn");
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener("click",function(){
// 処理
});
}
// Javascriptの場合(対象は複数ある) forEachの場合
const nodelist = document.querySelectorAll(".btn");
const btns = Array.prototype.slice.call(nodelist,0);
btns.forEach(function(btn){
btn.addEventListener("click",function(){
// 処理
});
});
要素の取得、セレクターの指定
// JQuery
$("セレクター");
JQuery独自拡張があるので、セレクタをそのまま置き換えられない場合もある。
参考サイトが詳しい
- jQueryからネイティブJavaScriptへ置き換えの第一歩
- ライブラリを使わない素のJavaScriptでDOM操作
- jQuery -> Vanilla JSの変換
- nefe/You-Dont-Need-jQuery
要素の検索、親子兄弟要素へのアクセス、要素の作成・追加、要素の削除、属性の操作、スタイル関連操作
参考サイトが詳しい
.height() .width() .offset() .scrollTop()
参考サイトが詳しい
.find()、.closest()
// .find()
// JQuery
$("#main").find("ul li");
// Javascript
document.getElementById("main").querySelectorAll("ul li");
// .closest()
// JQuery
$('#main').closest('.contents');
// Javascript
// IE以外はOK
document.getElementById("main").closest(".contents");
// IEの場合は参考サイトを参照
fadeIn、fadeOut、fadeToggle、fadeTo
// JQuery
$('.item').fadeIn(1000); // 1秒後にfadeIn
$('.item').fadeOut(1000); // 1秒後にfadeOut
$('.item').fadeToggle(1000); // 1秒後にfadeToggle
// Javascript
// fadeIn(CSS Transitionを使う)
const ms = 1000;
const elm = document.querySelector(".item");
elm.style.opacity = 0; // 透過度0
elm.style.transition = "opacity " + ms + "ms";
setTimeout(function(){elm.style.opacity = 1;}, 1); // 0.001秒後に transition開始(透過度1にする)
// fadeOut(CSS Transitionを使う)
const ms = 1000;
const elm = document.querySelector(".item");
elm.style.opacity = 1; // 透過度1
elm.style.transition = "opacity " + ms + "ms";
setTimeout(function(){elm.style.opacity = 0;}, 1); // 0.001秒後に transition開始(透過度0にする)
setTimeout(function(){elm.style.display = "none";}, ms + 10); // 1.01秒後に完全に消す。
// fadeToggle
const ms = 1000;
const elm = document.querySelector(".item");
elm.style.transition = "opacity " + ms + "ms";
if (elm.style.display !== "none") {
elm.style.opacity = 1;
setTimeout(function(){elm.style.opacity = 0;}, 1);
setTimeout(function(){elm.style.display = "none";}, ms + 10);
} else {
elm.style.opacity = 0;
elm.style.display = "";
setTimeout(function(){elm.style.opacity = 1;}, 1);
}
// fadeTo
slideUp、slideDown、slideToggle
// JQuery
$('.item').slideUp(1000); // 1秒後にslideUp
$('.item').slideDown(1000); // 1秒後にslideDown
$('.item').slideToggle(1000); // 1秒後にslideToggle
// Javascript
// slideUp
const ms = 1000;
const elm = document.querySelector(".item");
elm.style.transition = "height " + ms + "ms";
elm.style.height = "";
elm.style.overflow = "hidden";
setTimeout(function(){elm.style.height = "0px";}, 1);
// slideDown
const ms = 1000;
const elm = document.querySelector(".item");
elm.style.transition = "height " + ms + "ms";
elm.style.height = "0px";
elm.style.display = "";
setTimeout(function(){elm.style.height = "";}, 1);
// slideToggle
const ms = 1000;
const elm = document.querySelector(".item");
elm.style.transition = "height " + ms + "ms";
if (elm.style.display !== "none") {
elm.style.height = "";
elm.style.overflow = "hidden";
setTimeout(function(){elm.style.height = "0px";}, 1);
setTimeout(function(){elm.style.display = "none";}, ms + 10);
} else {
elm.style.height = "0px";
elm.style.display = "";
setTimeout(function(){elm.style.height = "";}, 1);
setTimeout(function(){elm.style.overflow = "";}, ms + 10);
}
animate
時間によって設置をを徐々に変えるのはCSS Transitionで実装できるがJQueryのanimateと異なって設定できる値は限定されている。詳細は参考サイトを参照。
scrollTopなどはCSS Transitionを使えないのでscrollIntoViewを使う。
// 指定箇所まで自動スクロール
// JQuery
$("html,body").animate({scrollTop:$('.foo').offset().top});
// Javascript
document.querySelector('.foo').scrollIntoView(true);
// ChromeとFirefoxであればsmoothscrollも出来る。
document.querySelector('.foo').scrollIntoView({behavior: 'smooth'});
もしくはCSS の scroll-behaviorを使う。
ajax、get、post、ajaxSetup、load
// JQuery
$.ajax({
type: "POST",
url: "http://foo.com/submitform.php",
data: {
"key1": "data1",
"key2": "data2"
}
})
.then(
function (data) {
// 成功
console.log(data);
},
function () {
// 失敗
});
// Javascript
var formData = new FormData();
formData.append("key1", "data1");
formData.append("key2", "data2");
var xhr = new XMLHttpRequest();
xhr.open('POST', "http://foo.com/submitform.php");
xhr.addEventListener('loadend', function() {
if (xhr.status === 200) {
console.log(xhr.response);
} else {
};
});
xhr.send(formData);
fetch APIでもpolyfillを使えばIEでもOK
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/3.3.1/es6-promise.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.4/fetch.min.js"></script>
<script>
var formData = new FormData();
formData.append("key1", "data1");
formData.append("key2", "data2");
fetch("http://foo.com/submitform.php", {
method: "post",
cache: "no-cache",
headers: {},
body : formData
}).then(function(response) {
console.log(response.text());
});
</script>
- 一休.comホテルページのスマホ版からjQuery依存を取り除くためにやったこと
- jQueryを使わない書き方 ajax, each, trigger, on/off, extend, deferred, animate, css編
JQuery Lazy Load
画像を遅延で読み込ませるプラグインとしては、JQuery Lazy Loadなどがあるが、
Chrome限定であればHTMLだけで対応できる。
<img loading="lazy" src="lazy-cat.png" height="100" width="100" />
IE以外であれば、Intersection Observerを使って、表示位置にきたら自動で画像を読み込むように出来る。
<html>
<body>
<img class="lazyload" src="" data-src="sample.jpg" />
<script>
const imgs = document.querySelectorAll('img.lazyload');
const observer = new IntersectionObserver(function(changes){
changes.forEach(function(change) {
change.target.src = change.target.dataset.src;
observer.unobserve(change.target);
});
});
imgs.forEach(function(img){
observer.observe(img);
});
</script>
</body>
</html>
IEの場合は、単に画面ロード時にimgを置き換えるという手も。
<html>
<body>
<img class="lazyload" src="" data-src="sample.jpg" />
<script>
window.addEventListener("load", function(){
const imgs = document.querySelectorAll('img.lazyload');
for (let i = 0; i < imgs.length; i++) {
imgs[i].setAttribute('src', imgs[i].getAttribute('data-src'));
}
});
</script>
</body>
</html>