jQueryのscrollTop()にhtmlかbodyどちらを指定すればよいのか?
今まであまり深く考えていませんでしたが、 scrollTop()
を使う対象要素に html
を使うか body
を使うか、どんな仕様になっているのか気になったので調べてみました。
両方指定すると
$('html, body').animate({
scrollTop: 0
}, 500, function() {
// ここのコールバックが2回呼ばれる
});
html
か body
かどちらが動作するかわからないので、このように両方記述していたと思います。しかし、これだと コールバック関数が2回呼ばれる 現象が起こります。これを解決するには、ブラウザが対応している方を指定する必要がでてきます。
検証してみた
html | body | document.scrollingElement |
|
---|---|---|---|
IE8~11 | ✔ | 非対応 | |
Edge | ✔ | body ( document.body ) |
|
Chrome 43- | ✔ | 非対応 | |
Chrome 44~60 | ✔ | body ( document.body ) |
|
Chrome 61+ | ✔ | html ( document.documentElement ) |
|
Firefox 47- | ✔ | 非対応 | |
Firefox 48+ | ✔ | html ( document.documentElement ) |
|
Opera 30- | ✔ | 非対応 | |
Opera 31~47 | ✔ | body ( document.body ) |
|
Opera 48+ | ✔ | html ( document.documentElement ) |
|
Safari 7~8 | ✔ | 非対応 | |
Safari 9+ | ✔ | body ( document.body ) |
|
Android 4.3- | ✔ | 非対応 |
html
か body
どちらなら動作するかざっと調べました。また、モダンブラウザでは、 document.scrollingElement
という スクロールできる要素 を教えてくれるプロパティがあります。それについても、どのバージョンから対応しているか調べました。
html | body | document.scrollingElement |
|
---|---|---|---|
IE8~11 | ✔ | 非対応 | |
Chrome 43- | ✔ | 非対応 | |
Firefox 47- | ✔ | 非対応 | |
Opera 30- | ✔ | 非対応 | |
Safari 7~8 | ✔ | 非対応 | |
Android 4.3- | ✔ | 非対応 |
document.scrollingElement
が対応しているブラウザはそれを使えばいいので、非対応のみ抜き出してみました。IE と Firefox 47- が html
で、それ以外は body
とすれば良さそうですね。
JSで判定
var scrollableElement;
var firefox = navigator.userAgent.match(/Firefox\/([0-9]+)\./);
// document.scrollingElementに対応していればそれを使う
if ('scrollingElement' in document) {
scrollableElement = document.scrollingElement;
}
// IEのとき
else if (/*@cc_on!@*/false || (!!window.MSInputMethodContext && !!document.documentMode)) {
scrollableElement = document.documentElement;
}
// Firefox 47-のとき
else if (firefox && parseInt(firefox[1]) <= 47) {
scrollableElement = document.documentElement;
}
// それ以外
else {
scrollableElement = document.body;
}
先ほどの検証結果をもとに、条件分岐させます。 Firefox 47- についてはまあまあ古いので、対応しなくてもいいかもしれません。
var scrollableElement;
var firefox = navigator.userAgent.match(/Firefox\/([0-9]+)\./);
if ('scrollingElement' in document) {
scrollableElement = document.scrollingElement;
} else if (/*@cc_on!@*/false || (!!window.MSInputMethodContext && !!document.documentMode)) {
scrollableElement = document.documentElement;
} else if (firefox && parseInt(firefox[1]) <= 47) {
scrollableElement = document.documentElement;
} else {
scrollableElement = document.body;
}
// ページトップへ
$(scrollableElement).animate({
scrollTop: 0
}, 500, function() {
// コールバック
});
あとは、 scrollableElement
を指定すればよいです。 scrollableElement
があるおかげで今後新しいバージョンで変更があっても コードを修正する必要 がなくなるので非常にありがたいですね。
CSS本執筆しました!!!
CSS本出します!1/29発売予定
— たかもそ@CSS本1/29発売!! (@takamosoo) 2018年12月31日
自分がCSS学びたての頃にもっとはやく知りたかったテクニックを載せています。CSSの基礎知識について解説していないので、中級者〜向けとなります。CSS入門書を読んではみたものの、思い通りに作れない人にオススメです。
よろしくお願いします。https://t.co/fkz1dM03Pj pic.twitter.com/suYyaPqwIs