レスポンシブWebデザイン導入計画(Parllet の場合 その8(スライドメニュー Animated Border Menus 篇-5)) [公開アプリ]
前回の続きです。
レスポンシブWebデザイン導入計画シリーズでは同じ挿絵を使います。(決して手抜きではありません。)
これまでのあらすじ
ドットインストールのレスポンシブなウェブサイトを作ろう に沿ってParllet(個人で作成・公開しているアルファ版のWeb家計簿)のトップページを改修し、相談役の妻の一言でFacebookやGoogle+のようなスライドメニューの実装をと思い立つ。
jQuery Mobile からスライドメニューの要素だけ取り込もうと目論むも、あえなく失敗。
PageSlide を試すが "overlay" の動きの方が良いと感じ、Animated Border Menus をParllet(パレット) に組み込みはじめる。
単純に組み込んだ状態から Parllet(パレット) にそぐうように修正し、メニューを増やした時のスクロールの動きも PC では確認できた。
今度こそ残るは "Android 2.3 スクロール" 問題だが・・・。
ざっくり環境です。
OS:Windows 7 Home Premium
ブラウザ:IE 11.0
Android:2.3.3(HTC Desire HD 001HT)
PC での動きが調整出来たので、Android で見てみます。
メニューの上で指を滑らせても、後ろの本体の方がスクロールしてしまい、やはりメニューはスクロールしないようです。
"android ブラウザ overflow" で検索して見つけたページがこちら。
androidでoverflow:scrollがきかないのをjavascript(jQuery)で解決する
jQuery のソースを参考にさせてもらって、以下を stylePrlt.css に追加。
if (navigator.userAgent.indexOf('Android') > 0) {
var box = $('#divUlFrm')[0],
touchStartPositionX,
touchStartPositionY,
touchMovePositionX,
touchMovePositionY,
moveFarX,
moveFarY,
startScrollX,
startScrollY,
moveScrollX,
moveScrollY;
jQuery('#divUlFrm').addEventListener("touchstart",touchHandler,false);
jQuery('#divUlFrm').addEventListener("touchmove",touchHandler,false);
function touchHandler(e){
var touch = e.touches[0];
if(e.type == "touchstart"){
touchStartPositionX = touch.pageX;
touchStartPositionY = touch.pageY;
//タッチ前スクロールをとる
startScrollX = box.scrollLeft();
startScrollY = box.scrollTop();
}
if(e.type == "touchmove"){
e.preventDefault();
//現在の座標を取得
touchMovePositionX = touch.pageX;
touchMovePositionY = touch.pageY;
//差をとる
moveFarX = touchStartPositionX - touchMovePositionX;
moveFarY = touchStartPositionY - touchMovePositionY;
//スクロールを動かす
moveScrollX = startScrollX +moveFarX;
moveScrollY = startScrollY +moveFarY;
jQuery('#divUlFrm').scrollLeft(moveScrollX);
jQuery('#divUlFrm').scrollTop(moveScrollY);
}
}
}
・・・でもスクロールしない。
勘を頼りに一部修正。
jQuery('#divUlFrm').addEventListener("touchstart",touchHandler,false);
jQuery('#divUlFrm').addEventListener("touchmove",touchHandler,false);
↓
box.addEventListener("touchstart",touchHandler,false);
box.addEventListener("touchmove",touchHandler,false);
startScrollX = box.scrollLeft();
startScrollY = box.scrollTop();
↓
startScrollX = jQuery('#divUlFrm').scrollLeft();
startScrollY = jQuery('#divUlFrm').scrollTop();
スクロールしました !
参考元ページにもコメントさせてもらったところ、すぐに記事が修正されました。
また、ありがたいことに返信コメントも頂きました。
一部ここにも転載させて頂きます。
変数boxに格納する際に、なぜ配列の0番目をとるのかというのは、
$('#touchbox')というのはjQueryオブジェクトであって、
addEventListenerはjavascriptのメソッドなので、
jQueryオブジェクトにjavascriptのメソッドは使えない。
→jQueryオブジェクトをjavascriptオブジェクトに直す必要がある
→$('#touchbox')[0]とすると、javascriptオブジェクトになる。
→なのでaddEventListenerが使える。
という理屈だと認識してます。
(間違えてたら超はずかしいです。坊主にします)
そのため、ご指摘いただいた2番目の部分も同じ理屈の逆バージョンで、
.scrollLeft() というのはjQueryのメソッドなんですよね。
boxという変数にはjavascriptのオブジェクトが入ってるので
box.scrollLeft()だと、javascriptオブジェクトにjQueryメソッドを使おうとしてエラーになってしまう。
なので、jQueryオブジェクトにjQueryメソッドがつながるようにするために、
$('#touchbox').scrollLeft();
とする必要があるんだと
思います!
(間違えてたら夕飯ぬきにします!)
ありがたいです!
普段は衣料品店の店員で周りにプログラミングの話のできる相手も居らず、ネットの情報を頼りにひたすら独りで体当たりで試していくタイプの私にとって、他の方の認識を直接的に聞ける機会はナカナカないもので。
この場でも御礼申し上げます。
ここからは超蛇足。
jQueryで書ける部分を自分なりに改修。
if (navigator.userAgent.indexOf('Android') > 0) {
var box = jQuery('#divUlFrm'),
touchStartPositionX,
touchStartPositionY,
touchMovePositionX,
touchMovePositionY,
moveFarX,
moveFarY,
startScrollX,
startScrollY,
moveScrollX,
moveScrollY;
box.bind('touchstart', function(e) {
var touch = e.originalEvent.touches[0];
touchStartPositionX = touch.pageX;
touchStartPositionY = touch.pageY;
//タッチ前スクロールをとる
startScrollX = box.scrollLeft();
startScrollY = box.scrollTop();
});
box.bind('touchmove', function(e) {
var touch = e.originalEvent.touches[0];
e.preventDefault();
//現在の座標を取得
touchMovePositionX = touch.pageX;
touchMovePositionY = touch.pageY;
//差をとる
moveFarX = touchStartPositionX - touchMovePositionX;
moveFarY = touchStartPositionY - touchMovePositionY;
//スクロールを動かす
moveScrollX = startScrollX +moveFarX;
moveScrollY = startScrollY +moveFarY;
box.scrollLeft(moveScrollX);
box.scrollTop(moveScrollY);
});
}
javascript の addEventListener でなく jQuery の bind を使うようにしました。
それによって $('#divUlFrm')[0](javascriptオフジェクト)ではなく、最初から jQuery('#divUlFrm') のようにjQueryオブジェクトで取得すれば良いことになり、結果的に一石二鳥になったかと思います。
これで、一応トップページは完成・・・と、思っていたんですが!
ひょんなことから新たな問題が・・・。
ここまでの動きをサンプルページとして載せるつもりで作っていたんですが、動きを確認していたところ画面の左側に配置されている "新規ユーザー登録" が、スマホスタイルの時だけ押せなくなってます。
正確にはマウスオーバーでアイコンが pointer に変わらず、クリックすることが出来なくなっています。(フォーカスが当たっている時に Enter ボタン押下で、クリックイベントに飛ぶようにしており、その動きの方は出来ています。)
何となく、まだ現れていないスライドメニューに邪魔されて押せないような・・・。
悔しいんですが今日は時間切れです。(グググ・・)
次回に続く!
12/3 追記
続きを書きました。
コメント 0