2015.03.29
jQuery iOSでもひよこを止めろ!
以前jQuery スクロールに付いてくるtopに戻るボタンという記事を書きました。
iPhoneでは謎の挙動で実現できなかった下までスクロールしたらfooterの他の物と重ならない位置に追随ボタンを固定したい。という望みが一応、叶いましたので備忘録として書き留めたいと思います。
ヘンな高さを算出してる問題
Mobile Safariの ’$(window).height()’で取得する数値が変なのよねーという問題だったようです。
当時は調べ方が悪く.scrollまわりのバグ?という情報しか拾えませんでしたが、scrollは関係なかったもよう。
正しいwindowの高さを取得するには、javascriptのinnerHeightを使うとのこと。
まるっと頂きました。
1 2 3 4 5 6 7 8 9 10 11 12 |
//元の var windowRoll = $(window), topBtn = $('#page_top'), showFlug = false, changeBottom = $('body').height() - windowRoll.height() - 190; //変更 var windowRoll = $(window), topBtn = $('#page_top'), showFlug = false, winHeight = window.innerHeight ? window.innerHeight : windowRoll.height(), changeBottom = $(document).height() - winHeight - 190; |
画像やAjaxを読み込む前に高さを算出してる問題
原因はもう一つ。
症状は止めたい位置にボタンがさしかかるといきなり画面上から消えてしまうというものでした。表示外のとんでもない位置に固定されていたんですねw 画像が全て読み込まれないreadyイベントの段階でdocument全体の高さを習得していたのも原因のようです。
画像を含めたページ全体の読み込みが出来たところで、documentの高さを.height()で取得するために
今回はjQueryの
1 |
jQuery.event.add(window,"load",function(){...}); |
を使うことにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
jQuery.event.add(window,"load",function(){ //画像読み込み後load //トップスクロール var windowRoll = $(window), topBtn = $('#page_top'), showFlug = false, winHeight = window.innerHeight ? window.innerHeight : $(window).height(), changeBottom = $(document).height() - winHeight - 190; topBtn.css('right', '-135px'); //スクロールが100に達したらボタン表示 windowRoll.scroll(function () { if ($(this).scrollTop() > 100) { if (showFlug == false) { showFlug = true; topBtn.stop().animate({'right' : '0px'}, 300); } } else { if (showFlug) { showFlug = false; topBtn.stop().animate({'right' : '-135px'}, 500); } } }); //スクロールが最下部に達したらボタンのbottom変化 windowRoll.scroll(function() { if ($(this).scrollTop() <= changeBottom) { topBtn.addClass("bottomsmall").removeClass("bottomlage");} else { topBtn.removeClass("bottomsmall").addClass("bottomlage"); } }); //スクロールしてトップ topBtn.click(function () { $('body,html').animate({ scrollTop: 0 }, 300); return false; }); }); |
最初のスライド動作がぎこちなくなるものの、ボタンがどっかに行っちゃうことはなくなりました。
でもでも、画像の読み込み後の処理は別にした方が良くない?問題
これでいいかなぁーと思っていたのですが、既にreadyイベントの中で’$(window).on(‘load’,function{..’ を使っている部分があったのを思い出しました。
モバイルなどでは、ページ読み込み完了前にスクロールを始めることの方が多いかもしれませんし、ボタンのスクリプト自体はDOMの構築後発動してくれておもいっきり差し支えない訳で…
ボタンを止める位置のスクリプト部分のみ.onの引数のfunction内に書き直しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
$(function() { //トップスクロール DOM構築後発動でok var windowRoll = $(window), topBtn = $('#page_top'), showFlug = false; topBtn.css('right', '-135px'); //スクロールが100に達したらボタン表示 windowRoll.scroll(function() { if ($(this).scrollTop() > 100) { if (showFlug == false) { showFlug = true; topBtn.stop().animate({'right' : '0px'}, 300); } } else { if (showFlug) { showFlug = false; topBtn.stop().animate({'right' : '-135px'}, 500); } } }); //スクロールしてトップ topBtn.click(function() { $('body,html').animate({scrollTop : 0}, 300); return false; }); //画像読み込み後の処理を.onで扱う $(window).on('load', function() { //スクロールが最下部に達したらボタンのbottom変化 var winHeight = window.innerHeight ? window.innerHeight : windowRoll.height(), changeBottom = $(document).height() - winHeight - 190; windowRoll.scroll(function() { if ($(this).scrollTop() <= changeBottom) { topBtn.addClass("bottomsmall").removeClass("bottomlage"); } else { topBtn.removeClass("bottomsmall").addClass("bottomlage"); } }); }); }); |
これでブラウザ共通のスクリプトになりました。iPhoneの分岐を書かなくてよくなったので、コードを少し減らす事ができました。
はーすっきり。
スポンサーリンク
コメントをどうぞ