スクロールを無効にするCSS
html,body{
overflow: hidden
}
しかしこれではiOSでスクロールを無効にできない.
ページ全体を無効にする方法
// スクロールを無効にする
$(window).on('touchmove.noScroll', function(e) {
e.preventDefault();
});
// スクロール無効を解除する
$(window).off('.noScroll');
スマホの独自イベントのtouchmoveイベントを切ってスクロールを止める。
解除したい時はoffする。
イベント名に、.noScroll
と名前を付けることで、他の部分でtouchmoveイベントを使っていたとしても、そのtouchmoveイベントまでイベントをoff()してしまうこともなく、.noScroll
の名前のイベントのみをoff()することができる。
参考
特定のエリアのみスクロールを無効にする方法
ドロワーメニューを左側に表示するときにコンテンツ側を固定するときなど
// スクロールを無効にする
$('.content').on('touchmove.noScroll', function(e) {
e.preventDefault();
});
// スクロール無効を解除する
$('.content').off('.noScroll');
としても、うまく動くときとうまく動かないときがあった。
しょうがないのでfixして対応した。
// スクロールを無効にする
var scrollTop = $(window).scrollTop();
$('.content').css({'position':'fixed','top':-scrollTop});
// スクロール無効を解除する
$('.content').css({'position':'static','top':'0'});
$('html,body').scrollTop(scrollTop);
私が引っかかってしまったのは、
$('.content').css({'position':'static','top':'0'}).scrollTop(scrollTop);
としてしまったこと。
おまけ
ちなみに作業していたサイトは、
- レスポンシブでPC,スマホ対応
- 左ドロワー、コンテンツが右にずれるタイプ
- スワイプでも操作できる
- ドロワーをホバーしたらスクロールバーを表示したい・慣性的な動きにしたい
- ヘッダー固定
- ドロワーを開いているとき、ドロワー以外をクリック(タップ)したら閉じる
- ドロワーを開いているときコンテンツはスクロールできない
という仕様だった。(いや、最初は違ったんだ・・・)
当初、sidrというプラグインを使っていた。
途中でヘッダー固定になり、いろいろ書き加えたところ、iPad,Androidタブレットでうまく動かなくなった。
ドロワーを閉じると、Chromeは上へ、Safariは下へ、Firefoxは下へ少しずれる。。。iPhoneも発生するものと発生しないものが・・・(/-\ )
右ドロワーなら問題なかった。
それがプラグインの仕様のようだったので、違うプラグインを探した。
いろいろ検証した結果slideoutというのが一番理想に近いことができそうだったので、これで頑張ることにした。
他にも、
iOSでページトップで上にスクロールしようとするとドロワーメニューが見えてしまう。
ページが全て読み込まれる前にスクロールするとヘッダーの上に隙間ができる。(これは対応していない)
ドロワーメニューのスクロール位置が次開いたときにも引き継がれている。
IE11だけドロワーを開いたときヘッダーが右に移動しない。
などなどいろいろありました。
また、このプラグインは、touchstart
がうまく動かないようで、/
に遷移してしまう症状もありました。
var _touch = ('ontouchstart' in document) ? 'touchstart' : 'click';
$('.menu').on(_touch,function(){});
こんな感じの使い方はできませんでした。
最終的に、ざっくりとですがこんな感じで実装しました〜
<script src="/js/slideout.min.js"></script>
<script>
$(function(){
var ua = navigator.userAgent.toLowerCase(),
isIE11 = (ua.indexOf('trident/7') > -1);
var slideout = new Slideout({
'panel': document.getElementById('panel'),
'menu': document.getElementById('menu'),
'padding': 260,
'duration' : 200
});
var scrollTop = $(window).scrollTop(),
header = $('header'),
panel = $('#panel'),
drawer = $('#menu'),
close = $('.drawer-close'),
fadeSpeed = 100;
$('.js-slideout-toggle').on('click',function(){
slideout.toggle();
});
slideout.on('beforeopen', function() {
if(isIE11){
header.css({'top':'0'});
header.animate({'left':'280px'},200);
}else{
scrollTop = $(window).scrollTop();
header.css({'top':scrollTop});
panel.css({'position':'fixed','top':-scrollTop});
}
drawer.show();
});
slideout.on('open', function() {
header.css({'top':scrollTop});
close.css({
'z-index':'999999',
'display':'block'
});
});
slideout.on('beforeclose', function() {
if(isIE11) {
header.animate({'left':'0'},200);
}
});
slideout.on('close', function() {
header.css({'top':'0'});
panel.css({'position':'static','top':'0'});
$('html,body').scrollTop(scrollTop);
close.css({
'z-index':'1',
'display':'none'
});
drawer.hide();
$('html').removeClass('slideout-open');
});
});
</script>
<nav id="menu" class="slideout-menu">
<div class="js-slideout-toggle">x</div>
<div>
メニュー
</div>
</nav>
<main id="panel" class="slideout-panel">
<header>
<div class="js-slideout-toggle">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</div>
<h2>Panel</h2>
</header>
<div>
コンテンツ
</div>
<div class="drawer-close js-slideout-toggle"></div>
</main>
.slideout-menu{
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 0;
width: 280px;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
display: none;
}
.slideout-panel{
position: relative;
background-color: #fff;
z-index: 2;
}
.slideout-open,
.slideout-open body,
.slideout-open .slideout-panel {
overflow: hidden;
}
.slideout-open .slideout-menu {
display: block;
}
.drawer-close {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
そういえば、初回アクセス時はドロワーが表示されていて、しばらくしたら閉じるという仕様だったな・・・
他にも案を出したが採用されず、cookieを使ってプラグインの仕様に合わせるためにゴリゴリしたら、やっぱりいらないってなったなぁー・・・w(でしょうねw)
他にもいろいろゴリゴリした。
なんだかんだ久しぶりにがっつりで楽しかったな〜