2013年05月

マークアップエンジニアとかWEBディレクターとかをやってる僕が、自分が詰まって、解決したことをここに残しておきますよ。

androidでoverflow:scrollがきかないのをjavascript(jQuery)で解決する

※一部ソースが間違えていたので修正しました[20131028]


サイトをつくっていて、特定の領域だけスクロールさせたいとき、
要素をdivでかこんで

overflow:scroll;

などとします。

スマホ用サイトでも、使うことはちょくちょくあるのですが、なんとandroidでは、overflow:scrollがきかずに、強制的にoverflow:hidden;になってしまうというバグが。

それを解決するライブラリも半日探したけれど見つからず、、
しょうがないのでjavascriptを自分で書いて解決してみたら、
思いの外簡単だったので、共有しときます。

基本的にはコピペでいけると思います。

javascript部分(というかjQuery) 

$(function(){
var box = $('#touchbox')[0];
var touchStartPositionX;
var touchStartPositionY;
var touchMovePositionX;
var touchMovePositionY;
var moveFarX;
var moveFarY;
var startScrollX;
var startScrollY;
var moveScrollX;
var moveScrollY;

box.addEventListener("touchstart",touchHandler,false);
box.addEventListener("touchmove",touchHandler,false);

function touchHandler(e){
var touch = e.touches[0];
if(e.type == "touchstart"){
touchStartPositionX = touch.pageX;
touchStartPositionY = touch.pageY;
//タッチ前スクロールをとる
startScrollX = $('#touchbox').scrollLeft();
startScrollY = $('#touchbox').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;
$('#touchbox').scrollLeft(moveScrollX);
$('#touchbox').scrollTop(moveScrollY);
}
}
});


HTMLは以下のような形

<div id="touchbox">
スクロールさせたいボックスの中身が入る
</div> 


利用するときは、javascriptの中の2行目の#touchboxを好きな名前に変更してください。


やっていることとしては、

①touchstartで触った瞬間の座標をとる
②touchmoveで動かすたびに動かした量分、座標を変更する

の2つです。

androidだけで動かしたい場合は、ユーザーエージェントでandroidだけに読ませてもいいかもです。

if(navigator.userAgent.indexOf('Android') > 0){
上記のjavascriptを入れる
}




touchイベントの取り方などについては、こちらのサイト様を参考にしました!
http://www.webcyou.com/?p=3121



 タッチして動かしているときにブラウザ自体が動いちゃうのを防ぐために
preventDefault();をいれているのですが、touchした動作すべてにperventDefaultを入れると、div内にはいっているaタグが無効になっちゃうという弊害があるので、

上記の例では、touchmoveのときにだけpreventDevaultをすることでaタグがあってもちゃんとリンクがとぶようにしています。


これをもとに、超簡易なjQueryライブラリをつくってみようかと思ってるんですが、時間がないのでまた別の機会に。 

iPhone(Android)サイトで縦向き横向きを判定する2つの方法(javascript)

スマホサイトを作っていて、縦向きのときにしか見れないようにしたい、ということがあり、縦横を判定するjavascriptを探していたら2つの方法がありました。


①window.orientationを使う方法

以下のようにします。

var isLandscape = function(){
if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') == -1) || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0) {
var orientation = window.orientation;
if(orientation == 0){
$("body").addClass("portrait");
$("body").removeClass("landscape");
}else{
$("body").addClass("landscape");
$("body").removeClass("portrait");
}
}
}
$(window).resize(function(){
isLandscape();
});
isLandscape();



navigator.userAgentなんちゃらーというところは、ユーザーエージェントを見て、iphoneなのかandroidなのかを判別してるだけです。

肝心なのは、var orientation = window.orientationから先。

window.orientationというのは、傾き度数を取得するもので、iphoneを横にしたり縦にしたりすると、0とか90とかの数字が入ってきます。

なので0が入ってきたときは、bodyタグにclass="portrait" とつけて、それ以外が入ったときは
<body class="landscape">になるようにします。

あとは、css側で

.landscape #content{display:none;}

とかなんとかやっちゃうなどします。

しかし、このほうほう、たまに縦横が逆転しちゃうバグがおきます。
僕の書き方が悪いのかもしれません。

そこでもっとシンプルなのが次の方法




②縦横サイズから判断しちゃう方法

var isLandscape = function(){
if (window.innerHeight > window.innerWidth) {
$("body").addClass("portrait");
$("body").removeClass("landscape");
}else{
$("body").addClass("landscape");
$("body").removeClass("portrait");
}
}
$(window).resize(function(){
isLandscape();
});
isLandscape(); 


これはわかりやすいです。
windowのサイズを取得して、縦幅が横幅よりも大きかったらportrait(縦向き)
横幅が縦幅よりも大きかったらlandscape(横向き)
という判別。

こっちのほうが間違いないかもです。

 
記事検索


手ぶらで通話 - bluetoothヘッドセット

1時間1円で暖かい。電気毛布。

夏のPC仕事のおともに冷えピタ。クールヘッドで脳のスピードがあがります。

お仕事のご依頼・お問い合わせはこちら

コーディングのお仕事が得意です。

info(あっと)tacshock.com
タグクラウド
QRコード
QRコード
  • ライブドアブログ