レスポンシブの時はオーバーレイでのアラートが微妙な気がしたけど・・・ [公開アプリ]
■ (タイトル変わっちゃったけど)前回の続きです
前回、この回からの堂々巡り気味な問題を私なりに整理しました。
- オーバーレイは(前面の)全面に表示させることでメッセージも届きやすい(と思う)
- オーバーレイは背面のコンテンツとは独立しており、position: fixed; で固定してしまうのが楽
- 楽だが、position: fixed; にすると、オーバーレイの中身をブラウザの枠内に収めるしかない
- 中身を削りたくなくて、position: absolute; にすると、今度はオーバーレイで常に全面を覆うのが難しい
- レスポンシブなダイアログの方が融通が利くかと思って alertify.js を試したが、結局高さに関しては同じ問題が残る
レスポンシブなダイアログの alertify.js を組み込んで満足していたけど、
absolute のオーバーレイで問題だったのは高さの方であり、
問題を正確に把握した上で、正しく対処
という意味では、出来てなかったってことが分かったのでした。
■ で、どうするか
そもそも最初の回に
実はこのオーバーレイだけは制御しきれていません。
(オーバーレイが表示された後にブラウザの幅 を縦横グリグリ変えてると、最初の挿絵のように覆いきれてない部分が出来ることが分かるかと ^^; "リサイズするウィンドウ内の最大コンテンツの幅と高さに合わせて伸縮して、逆にオーバーレイ自身の方が大きい時はそのまま" みたいな動きをさせることが出来ません・・。)
としていた時には、position: absolute; ありきで考えちゃっていました。
でも、前回いろいろ整理して考えるうちに、オッサンの固い頭もちょっとほぐれてきました。
ブラウザの高さよりも中身の高さの方が大きく
なってしまった際のはみ出た部分を救うために
position: absolute; を採用して上記の制御しきれない状態に陥りました。
私が感じたのブラウザの幅・高さと中身の大きさ(量)が変わる中で表面を常に覆うことを実現するには、
position: fixed;(+ width: 100%; + height: 100%;)
は、jQuery 等で実現するよりも簡単で強力だということです。
だからそれは残したまま、何とかならないでしょうか。
最初の回 の挿絵でもお分かりのように、
jQueryでオーバーレイ(#overlay)の width や height を調整しようとして失敗しています。
しかし、中身の方(#overlay 直下の div)はというと、当たり前ですが高さを保っています。
つまり、表面を常に覆う要素と、量が多くてスクロールが必要な要素は分けて考えれば良い。
<div id="overlay"> ←表面を常に覆う要素(position: fixed;)
<div> ←量が多くてスクロールが必要な要素(overflow-y: scroll;)
</div>
</div>
私はそれを一緒くたにして同時に実現しようとしたからこんがらがったのです。
■ ざっくり環境
OS:Windows 7 Home Premium
ブラウザ:IE 11.0
Android:2.3.3(HTC Desire HD 001HT)
■ 体当たり開始
最初の回と同様に、スタート地点は サンプルページ2 とします。
overlay.css の修正
修正前
#overlay{
display: none;
width: 100%;
height:auto;
text-align: left;
position: absolute;
top: 0;
z-index: 801;
background: rgba(0,0,0,0.7);
}
#overlay div {
max-width: 90%;
margin-left: auto;
margin-right: auto;
}
#text{
font-size: 30px;
color: #eee;
padding-top: 100px;
padding-bottom: 1em;
font-weight: bold;
}
#close{
background: #eeeeee;
color: #717171;
width: 70px;
margin: auto;
text-align: center;
font-size: 15px;
padding:5px;
border-radius: 3px;
cursor: pointer;
}
修正後
#overlay{
display: none;
width: 100%;
height: 100%;
text-align: left;
position: fixed;
top: 0;
z-index: 801;
background: rgba(0,0,0,0.7);
}
#overlay div {
max-width: 90%;
margin-left: auto;
margin-right: auto;
height: 100%;
overflow-y: scroll;
}
一応機能的には満たしてしまいましたね・・・。
最初の回以前の苦労はなんだったんだ・・orz
まあ、見た目が微妙なんで調整を続けます。
スクロールバーが2つになっちゃってるのと、
内側のスクロールバーの位置を何とかしたいですね。
あと、閉じるボタンの下にちょっと余白も欲しい。
閉じるボタンの下の余白と内側のスクロールバーの位置の調整。
overlay.css の修正
修正後
#overlay div {
/* ← max-width: 90%; を削除 */
/* ← margin-left: auto; を削除 */
/* ← margin-right: auto; を削除 */
height: 100%;
overflow-y: scroll;
}#text{
font-size: 30px;
color: #eee;
padding-top: 100px;
padding-bottom: 1em;
font-weight: bold;
max-width: 90%;
margin-left: auto;
margin-right: auto;
}
#close{
background: #eeeeee;
color: #717171;
width: 70px;
margin: auto auto 1em auto;
text-align: center;
font-size: 15px;
padding:5px;
border-radius: 3px;
cursor: pointer;
}
2つの問題は解消しました。
外側のスクロールバーですが、Parllet(個人で作成・公開しているアルファ版のWeb家計簿)では中身の量に関わらずに表示させています。
(ちなみにその目的は、スクロールバーの有無によるセンターの位置のずれを無くすことです。)
なので、オーバーレイ表示の時だけ消すには流石に jQuery さんが良いかと。
ついでに、最初の回以前にオーバーレイを無理やり制御しようとした部分を消します。
html ファイル内の jQuery の修正
修正前
<script type="text/javascript">
<!--
jQuery(function(){
if (jQuery('#overlay').height() < jQuery('#container').height())
jQuery('#overlay').height(jQuery('#container').height());
if (jQuery('#overlay').width() < jQuery('#container').width())
jQuery('#overlay').width(jQuery('#container').width());
jQuery('a.clickOverlay').click(function() {
jQuery('#pageTop').click();
jQuery('#overlay').fadeIn();
return false;
});
jQuery("#close").click(function() {
jQuery("#overlay").fadeOut();
});
jQuery(window).resize(function() {
if (jQuery('#overlay').height() < jQuery('#container').height())
jQuery('#overlay').height(jQuery('#container').height());
if (jQuery('#overlay').width() < jQuery('#container').width())
jQuery('#overlay').width(jQuery('#container').width());
});
});
// -->
</script>
修正後
<script type="text/javascript">
<!--
jQuery(function(){
/* ← 削除 */
/* ← 削除 */
/* ← 削除 */
/* ← 削除 */
jQuery('a.clickOverlay').click(function() {
jQuery('body').css('overflow-y', 'hidden');
jQuery('#pageTop').click();
jQuery('#overlay').fadeIn();
return false;
});
jQuery("#close").click(function() {
jQuery('body').css('overflow-y', 'scroll');
jQuery("#overlay").fadeOut();
});
/* ← 削除 */
/* ← 削除 */
/* ← 削除 */
/* ← 削除 */
/* ← 削除 */
/* ← 削除 */
});
// -->
</script>
ほぼ、オッケーですね。
Android でも確認。
あ~、はいはい! Android 2.3 なのでスクロールしません。
この回の手法で回避します。
html ファイル内の jQuery に追加
追加後
jQuery(function(){
jQuery('a.clickOverlay').click(function() {
jQuery('body').css('overflow-y', 'hidden');
jQuery('#pageTop').click();
jQuery('#overlay').fadeIn();
return false;
});
jQuery("#close").click(function() {
jQuery('body').css('overflow-y', 'scroll');
jQuery("#overlay").fadeOut();
});
// Android 2.3 でスクロールしないバグへの対応
if (navigator.userAgent.indexOf('Android') > 0) {
var box = jQuery('#overlay div'),
touchStartPositionX,
touchStartPositionY,
touchMovePositionX,
touchMovePositionY,
moveFarX,
moveFarY,
startScrollX,
startScrollY,
moveScrollX,
moveScrollY;
box.bind('touchstart', function(e) {
var touch = e.originalEvent.touches[0];
touchStartPositionX = touch.pageX;
touchStartPositionY = touch.pageY;
//タッチ前スクロールをとる
startScrollX = box.scrollLeft();
startScrollY = box.scrollTop();
});
box.bind('touchmove', function(e) {
var touch = e.originalEvent.touches[0];
e.preventDefault();
//現在の座標を取得
touchMovePositionX = touch.pageX;
touchMovePositionY = touch.pageY;
//差をとる
moveFarX = touchStartPositionX - touchMovePositionX;
moveFarY = touchStartPositionY - touchMovePositionY;
//スクロールを動かす
moveScrollX = startScrollX +moveFarX;
moveScrollY = startScrollY +moveFarY;
box.scrollLeft(moveScrollX);
box.scrollTop(moveScrollY);
});
}
});
オッケーで~す!
対応後のサンプルページです。(PCブラウザからの方は幅をいろいろ変えてみて下さい)
一応念のため。あくまでもローカル開発版を元にしたサンプルページなので、公開している Parllet(パレット) は相変わらずスマホ・タブレットからは使えません。
こんどこそ、これにて完了です!
結局、レスポンシブの時もオーバーレイのアラートができた というオチでした m(__)m
コメント 0