かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

javascript iPhoneで今まで使ってた判別方法だとscrollTopが効かなくなっていたので調べた。

jQueryを使ってページをスクロールさせるスクリプトでよく見かけるのは下記のような感じです。

$('body, html').animate( {scrollTop: 0}, 'fast' );

このコード動くんですけど、bodyhtml両方でイベントが起きているので、処理中にチラツキが発生したりコールバックが2回呼び出されてしまいます。スクロールした後に何か処理したい時とか結構困るのでスクロールイベントで使うのはbodyなのかhtmlなのかをブラウザで判別する必要があります。

今までは下記のコードを使っていました。

var scrollTag = (!document.uniqueID && !window.opera && !window.sidebar && window.localStorage && typeof window.orientation === "undefined")? 'body' : 'html';
$(scrollTag).animate( {scrollTop: 0}, 'fast', function() {
  console.log('スクロールおわったよ');
});

今までは問題なく動いていたと思っていたのですが、最近iPhoneで見ているとスクロールが上手く動作していない事に気づいてしまいました。(最近のアップデートで変わった!? 見逃していただけ??)

iPhoneで動作しなくなっていた原因は単純に判別で
window.localStorage // undefined
window.orientation === "undefined" // false
となっていて、webkitなのでscrollTagはbodyになって欲しい所がhtmlになってしまっていたのが原因でした。

使っていた判別方法もいつどうやってこうなったのか覚えていなかったので、折角の機会なので調べてみることにしました。

どのブラウザがどのタグ?

まずは、どのブラウザがbodyhtmlどちらのタグで動くのか解らないとダメなので調べます。 firefoxIE系がhtmlwebkit系がbodyだと記憶していましたが、変わっている可能性も大なのです。

See the Pen scroll test HTML or BODY? by Chaika (@chaika-design) on CodePen.

ブラウザ バージョン html body
Chrome 42.0.2311.152 ×
Safari 8.0.6 ×
Firefox 38.0.1 ×
Vivaldi 1.0.118.19 ×
Opera 29.0 ×
IE 11 ×
Safari (iPhone) 8.0 ×

手持ちのブラウザで調べた結果以上のような感じになりました。
Android端末を持ってなかったので確認できてません... webkit系だと信じることにします。

 

ブラウザ判別のコードを考える

先の調査結果からFirefoxIEhtmlでそれ以外のブラウザはbodyを使うようにすれば良さそうです。


こちらの判別コードを利用させて頂きました。
IE11はIE9以上IE10以上の両方にヒットしていましたが、まぁIE系はhtmlタグを使う事にするのでよしとすることにします。

そんな感じで出来上がったコードがこちらです。

var scrollTag = ( window.chrome || 'WebkitAppearance' in document.documentElement.style )? 'body' : 'html';

$('.js-scrollTopButton').on('click', function(e) {
  $(scrollTag).animate({
    scrollTop: 0
  }, 'fast', function() {
    // スクロールが完了した時に行うイベント
    console.log('スクロールおわったよ');
  });
  return false;
});

scrollTagの判別方法を変更しただけですが...
とはいえ、ブラウザが増えたりバージョンが上がったりすると、この判別方法を変更する必要が出てくるかと思います。統一して欲しいネ-。  


[参考]

Lovely Party Collection/チュチュ・バレリーナ

Lovely Party Collection/チュチュ・バレリーナ