前回から
一度実装したbackdrop機能。
サイドバーやドロップダウンメニューがそれぞれ有効時に、それぞれのすぐ下のスタックにページ全体を覆う要素(黒色、オパシティ0.8)を表示すると言うものを自作。
http://bootstrap3.cyberlab.info/javascript/modals-options-backdrop.html#
↑ bootstrap3ではオプションで設置可能。
前回の記事の時点でフッダーが触れる、裏の裏(本文container)がスクロール可能、下手したらリンクも飛べる等粗だらけだったので改良を目指した。
出来上がった結果は一番下に書くのでそれだけ知りたい人は飛ばして下さい
position: fixed;
先ず手を付けたのがcontainerのポジションを帰るもの。
「後ろの要素 動く」だったりで一番に出て来る。
実装したら本文がスクロール可能問題は解決したがまた別問題発生。そんなもん。
今回の自分の場合layoout/applicationで
1ヘッダー
2コンテナ
3フッダー
4navバー
で構成されていた。
navバーにはトップリンク、マイページリンクなど5つの重要リンクをもっていて、コンテナのスクロールと共にスマホ最下部にピタッと付いてくる仕様にしていた。
結果position:absolute , bottom:0 で配置していたフッダーが、fixedになったコンテナに呼応して画面の最下部(navバーの直ぐ上)までせり上がってきてしまう。
と、いうか、例え一番下であってもbackdrop有効になった瞬間にページが一番上まであがってきてしまうのだ。
↑参考画https://webkikaku.co.jp/blog/htmlcss/footer-bottom/
記事自体はあまり関係ないです
(濃いピンク→navバー、薄ピンク→フッダー、 緑点線→backdrop あくまでもイメージ)
overflow: hidden
じゃbootstrap3のbackdropオプションはどう処理が走ってhttp://bootstrap3.cyberlab.info/javascript/modals-options-backdrop.html#
このモーダルのような挙動をしているのか、このサイトでデベロッパーツールで弄り回した所、
bodyタグにcss: overflow が働いている事を発見、似たような動きを自分のアプリに落とし込みました。
すると前の工程で発生した問題が解決するのと入れ替わりでiphoneでうしろが触れてしまった。androidでは素晴らしい挙動を示したのですが、なんでやねん。
歴戦の情報
https://qiita.com/mimoe/items/f5f668cebb697d073553
↑iphoneではoverflowが効かない問題
結果他にも2つほど処理を掛けたりしましたが完璧な物にはならず、ggってみるとこの記事を発見。
非常に読みやすく、更に全く同じことをやっては改善を繰り返しておりましたのでこちらのブログさんのソースコードから自分の欲しい処理を自分のアプリに落とし込む形をとりました。
ソースコード
var scrollTop = 0;
// バックドロップ有効時処理
backdropActive = function(){
$('.backdrop').css('display' , 'block');
$('.fixed-bottom').css('z-index',' 989');
element = document.getElementById('footer')
clientRect = element.getBoundingClientRect();
fTop = clientRect.top
$('.sidebar_toggle').css('display','none');
$('.footer').css({
'position':'fixed',
'top': fTop
});
scrollTop = $(window).scrollTop();
$('body').css({
'position':'fixed',
'top': -scrollTop
});
}
// バックドロップ無効時
backdropNegative = function(){
$('.backdrop').css('display' , 'none');
$('.fixed-bottom').css('z-index',' 1030');
$('body').removeClass('backdrop-active');
$('body').css('position','static');
$('.sidebar_toggle').css('display','block');
$(window).scrollTop(scrollTop);
$('.footer').css({
'position':'absolute',
'top':''
});
}
$(document).ready(function(){
// ドロップバーが表示された時
$('.dropdown').on('show.bs.dropdown',function(event){
backdropActive()
});
// ドロップバーが閉じた時
$('.dropdown').on('hidden.bs.dropdown',function(event){
backdropNegative();
});
//sidebarメニューが開いたらsidebar-activeクラスを付与する
var sidebar = $("#sidebar");
$('.sidebar_toggle').click(function(){
sidebar.toggleClass('sidebar--active');
event.stopPropagation();
});
// sidebarのメニューが開いた時sidebar-activeをクラスに持っていたらbackdropをディスプレイさせる
$('.sidebar_toggle').click(function(){
if($('.sidebar').hasClass("sidebar--active")){
backdropActive()
$('.fixed-top').css('z-index','989');
}
});
// backdropをクリックしたらsidebar-activeを無効、同時にbackdropも無効
$('.backdrop').click(function(e) {
if (!sidebar.is(e.target) && sidebar.hasClass('sidebar--active')) {
sidebar.removeClass('sidebar--active');
event.preventDefault();
backdropNegative();
$('.fixed-top').css('z-index','1030');
}
});
# body内
<div class="backdrop" style="display: none;"></div>
.backdrop {
background-color: rgba(0,0,0,0.8);
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 990;
}
1030はbootsrapの元の数値です。
990は自分のなかで何となく決めた数値です。わかりづらくてすみません。
追記 5/14
iosでinput他にfocusすると、position:fixedによる弊害でいくつか問題が発見された。
修正を行った
// スクロール禁止(ios用)
no_scroll = function(){
$(window).on('touchmove.noScroll', function(e) {
e.preventDefault();
});
}
// スクロール禁止 解除
on_scroll = function(){ $(window).off('.noScroll');}
var scrollTop = 0;
backdropActive = function(){
$('.backdrop').css('display' , 'block');
$('.fixed-bottom').css('z-index',' 989');
element = document.getElementById('footer')
clientRect = element.getBoundingClientRect();
fTop = clientRect.top
$('.footer').css({
'position':'fixed',
'top': fTop
});
$('.sidebar_toggle').css('display','none');
scrollTop = $(window).scrollTop();
$('body').css({
'top': (-scrollTop-100) + 'px',
'overflow':'hidden'
})
no_scroll();
}
backdropNegative = function(){
$('.backdrop').css('display' , 'none');
$('.fixed-bottom').css('z-index',' 1030');
$('body').removeClass('backdrop-active');
$('body').css('overflow','');
$('.sidebar_toggle').css('display','block');
$(window).scrollTop(scrollTop);
$('.footer').css({
'position':'absolute',
'top':''
});
on_scroll();
}
textarea {
font-size: 16px;
transform: scale(0.8);
}
<%= f.text_area :body, id:'no-pinch' , class:'frame-none text-white submit-form px-4', placeholder:"入力してください" %>
、
、
、
<script>
$(document).ready(function(){
inputElem = document.querySelector('#no-pinch')
inputElem.addEventListener('focus', function() {
scrollTop = $(window).scrollTop();
$('#bottom-nav').hide();
});
inputElem.addEventListener('blur', function() {
setTimeout(function() {
$('#bottom-nav').show();
}, 200);
});
});
</script>
iosでは16px以下で設定しているとピンチインしてしまうのでこのCSSとjsで対応