實例
可以相容於安卓4.0.4+:
#設計結構如下:
<header class="header"></header> <p class="wrap-page"> <section class="page"></section> ... </p> <footer class="footer"></footer> <p class="overlay"> <section class="modal"> <p class="modal-hd"></p> <p class="modal-bd"></p> <p class="modal-ft"></p> </section> </p>
這個overlay遮罩層的問題,現在這裡說明下為什麼這麼設計。
一般來說看到的overlay都與modal是兄弟元素,而不是嵌套關係。本來我也是這麼設計的,這就是習慣。後來由於modal居中的問題,重新審視了下這個問題:
為什麼遮罩層的overlay與彈窗內容是兄弟元素?
說實話真想不出什麼理由,非得搞成兄弟元素。後來突然意識到以前的遮罩層如果不採用半透明圖片的話,就得使用opacity(ie6-8不支持,透過濾鏡模擬),而這個屬性會對整個子元素都起作用,而且還沒辦法透過子元素覆寫這個值。這是我能想到的一條最佳理由,如果還有其他理由歡迎交流。
對於高上大的行動端來說,都是rgba時代了,所以opacity回家吃飯先。既然這個對子元素的影響已經不是問題,那麼嵌套關係就可以成立,而且嵌套還有一個非常好的理由,水平垂直居中,flex小指一動即可。而兄弟元素的水平垂直居中就得設定modal的top和left的值為50%,然後再設定translate的x和y方向都-50%
所以果斷拋棄兄弟元素設計換成嵌套關係。
因為overlay採用了flex佈局來控制子元素居中,所以不難呢過採用display為none/block來顯示隱藏遮罩層overlay,而是透過z-index的層級來控制,而modal部分透過新增刪除modal-in這個class來控制顯示隱藏
scss程式碼如下:
.overlay{ position: fixed; top: 0; rightright: 0; bottombottom: 0; left: 0; z-index: -1; background-color: rgba(0,0,0,.8); @include flex-center; // flex水平垂直居中 } .overlay.active { z-index: 980; } $modalBarHeight: 40px !default; $modalBdPadding: 15px; .modal{ background-color: #fff; border-radius: 5px; margin: 0 10px; overflow: hidden; opacity: 0; @include transform(translate3d(0,0,0) scale(0.815)); @extend %all-transition; @include transition-property(transform, opacity); &.modal-in{ opacity: 1; @include transform(translate3d(0,0,0) scale(1)); } .modal-hd{ text-align: center; line-height: $modalBarHeight; background-color: $primary; color: #fff; } .modal-bd{ padding: $modalBdPadding; } .modal-ft{ border-top: 1px solid $gray; @extend %display-flex; .btn-modal{ @include flex(1); background-color: #fefefe; text-align: center; line-height: $modalBarHeight; color: $primary; &:first-child{ border-right: 1px solid $gray; } &:last-child{ border-right: none; } &:hover,&:active{ background-color: #d9d9d9; } } } }
常見問題解決
移動端模擬彈跳窗時,遇到一些問題,現總結如下,以加深記憶。
情況一:
當body高度大於viewport高度時,在彈窗上滑動時,會遇到body也跟著滑動的現象。
解決想法:
禁止touchmove,及overflow:hidden來實現,參考下面程式碼:
/** * 初始化弹窗 */ var initDialog = (function() { var _tmpl = baidu.template('dialog-tpl', {}); return { tmpl : $(_tmpl), /** * [create 创建弹窗] * @return {[type]} [description] */ create: function() { var me = this, _tmpl = me.tmpl; $('body') // 禁用鼠标滚轮滚动 .css('overflow', 'hidden') .append(_tmpl) // 禁止touchmove,阻止body滑动 .on('touchmove', function(e) { e.preventDefault(); }) // 关闭动作 .on('tap', 'dialog-close', function() { me.destroy(); }) }, /** * [destroy 销毁弹窗] * @return {[type]} [description] */ destroy: function() { this.tmpl.remove(); // 解除touchmove绑定、启用滚动 $('body').off().css('overflow', 'auto'); } } })();
情況二:
軟鍵盤彈起時,自定彈窗不能鋪滿全螢幕
解決想法:
打開彈窗前,透過javascript的blur事件來收起軟鍵盤。
$(“:focus”).blur();
情況三:
實作toast元件時,如果toast使用
position: fixed;bottom:-3rem;即離底部比較近時,按照我們正常想法應該是鍵盤把頁面往上推,但是在IOS及Andriod UC瀏覽器中會出現toast被鍵盤覆蓋,即使我們設置z-index也無濟於事,因為鍵盤在整個瀏覽器的上層。
解決想法:
出現toast的時候,監聽所有控制項的事件,當focus時,動態計算目前位置,重新計算。但是有個問題,不同機型鍵盤的高度不統一。 M端部分參考程式碼:
<style type="text/css"> body { text-align: center; } input[type=text] { width: 80%; height: .8rem; margin-top: .3rem; } .toast { position: fixed; bottombottom: .3rem; left: 50%; margin-left: -1rem; width: 2rem; height: 1rem; background-color: #f00; border-radius: 10px; color: #fff; } </style> <input type="text"> <p class="toast">Toast</p>
以上是SCSS行動端頁遮罩層效果的實作及常見問題的解決方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!