jQuery

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

slickでasNavForでサムネイルを設定したがスライダーが動いている途中に次のスライダーをクリックしても効かない

便利なslick

asNavForというオプションをつかえば、スライダーと連動するサムネイルも作れるよね。

ただ困ったことがあって、たとえば4秒でスライダーが切り替わるように設定している場合、その4秒間の間に別のサムネイルをクリックしても動いてくれないことがある。

お客さんがサムネを連打したりすると「なんかちゃんと動いてません」という修正指示がくる。

slick asNavFor moving bugとかで検索したけど出なくて、よくやく自力で解決。

なんとオプションがありました。

waitForAnimate:true

このwaitForAnimateというのはアニメーションしてある間は他の操作をうけつけずに待機する、という機能で、デフォルトではtrueになっている。

これのおかげで遷移中にサムネイルをクリックしたり矢印(arrows)をクリックしたりしてもうまく動かなかったというわけだった。

この機能はもちろんあっていいんだけど、デフォルトはfalseにしておかないと不便だよね。まったく。


というわけでオプションはこんな感じになったよ。


$('.slider').slick({
asNavFor: '.slider-nav',
infinite: true,
autoplay: true,
autoplaySpeed: 4000,
dots:true,
arrows:true,
pauseOnHover: false,
fade:true,
waitForAnimate:false,
speed: 1000
})

$(".slider-nav").slick({
asNavFor: '.slider',
slidesToShow: 5,
waitForAnimate:false,
focusOnSelect: true
});



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に戻せばいいかな?だれか教えて。
 
記事検索


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

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

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

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

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

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