LoginSignup
83
97

More than 3 years have passed since last update.

JQueryをVanilla JSに緩やかに置き換える

Last updated at Posted at 2019-11-14

元々JQueryを多用していた物をVanilla JS(普通のJavascript)に徐々に書き換えていくポイントメモ的な物と関連記事を集めてきたもの。

書き換えの前提

  • 時間がある時に、ちょっとずつ変えていく。一気に変更しない。
  • 普通のJavascriptであれば5年以上は持ちそう。XMLHttpRequestなんて20年前からある。
  • JQueryを無理に無くそうとはしない。JQueryじゃなくても良いところを書き換えていく。(ただしJQuery1.xは脆弱性があるので3.xにする)
  • 中途半端に変えるとわかりにくくなる場合もある。時間と人に余裕があるなら最初から作り直すことも考える。
  • そのままでIE11でも動くようにする。Babelの使用までは考えない。
  • なるべく自力で書き換える場合の例なので、実際はある程度共通化したり、ライブラリ等を活用した方が良いかもしれない。

ブラウザによって未対応な物を押さえておく。

Chromeであれば、ES6以降の多くをサポートしているが、特にIEは対応できていないものが多いので把握しておく必要がある。
内容によってはPolyfillを使うことで対応できることもあるが、それによってJSのサイズが肥大化してしまう可能性もある。

なお、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独自拡張があるので、セレクタをそのまま置き換えられない場合もある。

参考サイトが詳しい

要素の検索、親子兄弟要素へのアクセス、要素の作成・追加、要素の削除、属性の操作、スタイル関連操作

参考サイトが詳しい

.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>

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>
83
97
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83
97