jQuery

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

androidでも速いハンバーガーメニュー(開閉メニュー)をつくる

スマホといえば、もう最近はほぼハンバーガーメニューだよね。
タップで上から降りてくる。
バツボタンをタップでまたあがっていく、というような。

普通につくると、以下のようにやりたくなる。

$('header nav').css({"top":"-1000px"});
$('#openMenu').click(function(ev){
ev.stopPropagation();//①
$('header nav').height($(window).height());//②
$('header nav').animate({top:0});//③
$('body,html').css({"overflow":"hidden","height":"100%"});//④
}); 

あらかじめ上のほうにメニューをふっとばしておいて、
#openMenuボタンをクリックしたらanimateでtop:0まで降りてくる。 

細かく説明すると、
①android対策等で親要素にクリックが伝搬しないようにする
②降りてくるメニューはウィンドウと同じ高さにセット(必要に応じて使う)
③メニューをtop:0の一までおろしてくる
④メニュー内をスワイプしてるときに背景がスクロールしちゃうのを防ぐ

わりとシンプル。
iphoneだけならこれでも全然いい。

※閉じるの処理はちょっと割愛してます。


でもandroidだと

「なんか遅いんですけど」
とか言われたりする。

そういうときは、めんどくさいけど、css3でアニメーションさせることになる。

んで作ったのが以下の様な感じ。

css

header nav{
width:100%;
top:-1000px;
overflow:scroll;
transform:translate(0px,0px);
-webkit-transform:translate(0px,0px);
transition: transform 0.3s ease-out;
}

header nav.on{
transform:translate(0px,1000px);
-webkit-transform:translate(0px,1000px);

js

$('#openMenu').on('click',function(ev){
ev.stopPropagation();
$('header nav').height($(window).height());
$('header nav').addClass('on');//⑤
$('body,html').css({"overflow":"hidden","height":"100%"});
}); 

jsはもともとのとほとんど同じだけど、animateで動かしてたのを消して、addClassだけになった。
⑤class="on"をnavタグにつける。

そしてアニメーション処理をやらせてるのは、cssのほう。

transitionでアニメーションで動くようにして、
.onがついてるのとついてないので、transform:translate(x,y)の位置を変えるという処理。

※閉じるの処理は割愛


 androidでtransformが効かなくて30分ほどロスしたけれども、ただ-webkit-プレフィクスをつけるだけだったという。

注意ですわね。 

スマホでメニューを開いた時に後ろはスクロールしないようにする

地味にはまってしまった。

スマホサイトのメニューって大体ハンバーガーメニューだよね。最近は。

38
(ハンバーガーメニューというやつ)

これをタップすると、ズルーっとグローバルメニューがかぶさるようにおりてくる、というのが一般的。

さて、そのメニュー内をスワイプしていると、後ろ側の ページが動いてしまうという現象に悩まされた。
タップでスクロールを禁止させるというのも見つけたが、
メニュー内はスクロールできるようにしたいため、背景だけスクロールを不可にしたい。


んで、しらべてみたら、htmlとbodyに対して、height:100%とoverflow:hiddenを割り当てればよいということがわかった。

実際に書くとこんな感じ。
閉じるときは解除も忘れずに。

$('#openMenu').click(function(){
$('header').fadeIn();
$('body,html').css({"overflow":"hidden","height":"100%"});
});
$('#closeMenu').click(function(){
$('body,html').css({"overflow":"visible","height":"auto"});
$('header').fadeOut();
});

手持ちのiphone6ではうまくいっている様子。

-------------追記-------------------

htmlも見たいというコメントをいただいたのでサンプルのhtmlのせますね。

<header>
<div class="headerInner">
<div class="headerLogo">
<h1><img src="img/logo.png" alt="ロゴ"></h1>
</div>
<a href="#" id="openMenu"><img src="img/icon_menu_sp.png" alt="menu"></a>
</div>
<nav class="gnav">
<ul>
<li><a href="#">メニュー</a></li>
<li><a href="#">メニュー</a></li>
<li><a href="#">メニュー</a></li>
<li><a href="#">メニュー</a></li>
<li><a href="#">メニュー</a></li>
</ul>
<a href="#" id="closeMenu"><img src="img/icon_menu_sp.png" alt="menu"></a>
</nav>
</header>

 今回のサンプルだとこんな感じ。

開くボタンと閉じるボタンがわかれてるパターン。
(開くも閉じるも1つのボタンっていうパターンも多いのでそれはまた別の記事で)


レスポンシブで動的に高さ変更したときの解除

レスポンシブでの要素の高さ変更などは、普通はcssで行うよね?

pcではheader{height:90px}

で、

spではheader{height:200px}のように。 


でもspではメニューが上からズルっと降りてきたりして、その際に、hightが動的に書き換える処理になったりする。

var winH = $(window).height();
$('height').height(winH);

のように。


すると、html側では、headerにstyle属性がつく。


その状態でウィンドウサイズをpcに戻したりすると、cssで指定したheight{90px}よりもstyleで書かれた動的な高さが適用されてしまう。

そういう場合にどうしたらいいのかなって考えてたんだけど、

いったん今のところの解決は、

pcになったらstyleをカラにしちゃうってことかな。と。


if(winsize > hogehoge){ // pcになったら
$('header').attr('style','');
}


って感じで。


※removeAttr()なるjQueryメソッドもあるらしいんだけどこれをやると、今度はsp側で動的に変更ができなくなるので使えなかった。
 

videoタグで設置した動画が再生された回数をアナリティクスでカウントする

サイト内にvideoタグで設置した動画が再生された回数をgoogle analyticsでカウントする。

 gaのトラッキングをonplayで呼び出せばOKらしい。

こんな感じ。

<video id="video" onclick="this.play()" onplay="ga('send','event','category','action')">
<source src="video.mp4" type="video/mp4">
</video> 

ga()の中身については、前回の記事で書いた。
グーグルアナリティクスのイベント計測

 

ただ、これだと再生のたびにカウントされちゃう。

再生→一時停止→再開→一時停止→再開

ってやると3カウントされちゃう。

なので、最初の1回だけしか再生しないようにしちゃうという手っ取り早い方法

<HTML>
<video id="video" onclick="this.play()" onplay="trackMoviePlay()">
<source src="video.mp4" type="video/mp4">
</video>
<js>
var isPlay = false;

function trackMoviePlay(){
if(isPlay == false){
ga('send','event','category','action');
isPlay = true;
}



ただ、ページを更新するまで、ほんとに何度再生してもカウントは1しか進まないという問題はあるけど。


※あれ、endイベントでisPlay = falseに戻せばいいかな?だれか教えて。
 

onclickでgoogle アナリティクスのイベント計測する

普段あまりアナリティクス関連やらないので調べた。
詳しいことは他のサイトにも載ってるので、最短でコピペできるようにしておく。

呼び出すのはこれ

ga('send','event','category','action')

sendとeventまでは決まり文句でこのまんま書かなきゃだめ。
categoryとactionは計測されるときの集計につかうので好きな文字列をいれる。

ga('send','event','link','click')
 
とかいう風にね。
ほんとはもっと引数あるけど最低限でいいので必須以外は省略。


呼び出し方はこう。

<a href="#" onclick="ga('send','event','link','click')">こちら</a> 

aタグに直で書くときはonclick内に記載しちゃう。

クリックイベントをjs側で制御してる場合はこう。

$('.btn').click(function(){
ga('send','event','link','click');
}) ;


どこをクリックしたのか分けて取得したいよね。
って時はidをつけておいてそのidを送っちゃうのもあり。

こう。


<html側>
<a href="#" class="btn" id="btn1">にゃん</a> 
<a href="#" class="btn" id="btn2">みぃみぃ</a> 
<a href="#" class="btn" id="btn3">フギャー</a> 
<a href="#" class="btn" id="btn4">ゴロゴロ</a>


<js側> 
$('.btn').click(function(){
var btnName = $(this).attr('id');
ga('send','event',btnName,'click');
}) ; 


こんな風にすれば別々で計測できる。


ところで調べていると
_gaq.push([xxxxxxxxxxxxx])
みたいな書き方が出てきて混乱するけど、これは古い方の書き方らしいので今は

ga('send','event',,,,,)のほうね。


 
記事検索


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

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

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

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

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

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