彈出層提示信息,這是移動前端開發中最多見的需求,你可能會想到一些流行的彈框插件,好比 經典的artDialog 炫酷的Sweetalert等等..javascript
可是慢慢地你其實會發現一般狀況下需求定製化要求較高,通常的彈框插件可能只知足大部分要求,自定義花的時間還不如手動本身封裝一個符合本身開發習慣的彈框組件,這樣後續開發效率將大大提升。css
首先整理一下思路,原生javascript實際上是有實現alert()方法的,可是那個會暫時性中斷程序運行,而且足以讓你醜拒!那麼拋開這些細細一想,其實彈框就是兩個div層,一個浮在底下的蒙層(遮罩層),將全部的元素遮起來,而且最好是半透明。另外一個就是彈框主體部分了,通常狀況須要水平垂直居中,而且一般包含標題,主體內容須要可定製,若是是模態框一般還有確認/取消按鈕。最後就是彈出、關閉的時候一些動效。html
因此說徹底能夠本身封裝一個,而後放在項目中公共js中去。能本身手寫的儘可能不用插件....前端
經過一個foreach循環,相似於傳入的opts繼承了defaultOpts屬性,在調用彈框以前執行的before()方法,至關於一些準備工做java
var defaultOpts = { title: '',//標題 content: '',//內容 文字 || html height: 50,//默認屏幕(父級)的50% width: 80,//默認屏幕(父級)的80% type: 'alert-default',//彈框類型 effect: 'fadeIn',//出現效果,默認下跌落 delayTime: 500,//效果延時時間,默認.5s autoClose: false,//自動關閉 autoTime: 2000, //自動關閉時間默認2s autoEffect: 'default',//關閉效果 ok: '肯定', okCallback: function(){},//肯定回調 cancel: '取消', cancelCallback: function(){},//取消回調 before : function() { console.log('before') }, close: function() { console.log('close') }, blankclose: false//空白處點擊關閉 } for (i in defaultOpts) { if (opts[i] === undefined) { opts[i] = defaultOpts[i] } }
opts.before && opts.before()
定義一個數組對象,裏面放彈框的dom元素,alert-mask爲全屏的遮罩層,alert-content爲彈框的主要內容區,最後經過.join(‘’)函數將數組轉換爲html ,再用jquery的append()方法追加在body節點最後。jquery
var alertHtml = [ '<section class="alert-main" id="alertMain">', '<div class="alert-mask li-opacity" id="alertMask"></div>', '<div class="alert-content '+ opts.type +'" id="alertContent">', opts.content +'</div>', '</section>' ] $('body').append(alertHtml.join(''))
我這裏是採用fixed定位,而後height是傳進來的高(百分比),top距離屏幕頂端距離百分比爲 100-傳進來的高 /2 ,這樣就實現了垂直居中,同理寬度也同樣。這種水平垂直居中的辦法也是本身長期實踐總結出來本身認爲最簡單最實用的,兼容各類屏幕大小,固然還有不少方法,能夠自行嘗試git
var $alertContent = $('#alertContent'), $alertMain = $('#alertMain'); $alertContent.css({ 'height': opts.height + '%', 'top': (100 - opts.height)/2 + '%', 'width': opts.width + '%', 'left': (100 - opts.width)/2 + '%' }) $('.li-opacity').css({ '-webkit-animation-duration' : opts.delayTime/1000 + 's' })
最後一句是給遮罩層賦一個動畫執行時間,實現淡入效果。詳情見下面的CSS @-webkit-keyframes opacitygithub
我這裏實現了四個效果,分別是fadeIn跌落,sideLeft從左側飛入,scale放大,info提示信息。能夠看到,我是定義了一個集合對象,分別放置了對應的css屬性,而後經過兩個setTimeout函數統一賦值web
var effect = { 'fadeIn': 'top', 'fadeInStart': '-100%', 'fadeInValue': (100 - opts.height)/2 + '%', 'sideLeft': 'left', 'sideLeftStart': '-100%', 'sideLeftValue': (100 - opts.width)/2 + '%', 'scale': '-webkit-transform', 'scaleStart': 'scale(0)', 'scaleValue': 'scale(1)', 'info': '-webkit-transform', 'infoStart': 'scale(1.2)', 'infoValue': 'scale(1)' } setTimeout(function(){ $alertContent.css(effect[opts.effect],effect[opts.effect + 'Start']).addClass('alert-show') setTimeout(function(){ $alertContent.css(effect[opts.effect], effect[opts.effect + 'Value']) opts.close && opts.close() },10) },opts.delayTime)
一般狀況下的需求,都會是要點擊彈框空白處關閉彈框,一個點擊事件搞定,重點是前面的選擇器,jquery給了咱們太多方便.... 固然最後爲了防止點擊到頁面其餘元素,阻止事件冒泡,組件默認行爲..數組
if(opts.blankclose) { $('.alert-main :not(.alert-content)').on('click',function(event){ $alertMain.remove() opts.close && opts.close() event.stopPropagation() event.preventDefault() }) }
當autoClose爲true,而且autoTime大於零時,用一個延時事件自動關閉彈框
if(opts.autoClose && opts.autoTime > 0) { setTimeout(function(){$alertMain.remove()},opts.autoTime) opts.close && opts.close() }
@-webkit-keyframes opacity { 0% { opacity: 0; /*初始狀態 透明度爲0*/ } 50% { opacity: 0; /*中間狀態 透明度爲0*/ } 100% { opacity: 1; /*結尾狀態 透明度爲1*/ } } .li-opacity { -webkit-animation-name: opacity; /*動畫名稱*/ -webkit-animation-iteration-count: 1; /*動畫次數*/ -webkit-animation-delay: 0s; /*延遲時間*/ } .alert-mask { position: fixed; height: 100%; width: 100%; left: 0%; top: 0%; z-index: 9998; background-color: rgba(0,0,0,.7); } .alert-content { position: fixed; box-sizing: border-box; border-radius: 4px; z-index: 9999; -webkit-transition: .4s; -moz-transition: .4s; transition: .4s; display: none; } .alert-show { display: block; } .alert-default { background-color: white; }
<p class="alert" data-flag="fadeIn">fadeIn</p> <p class="alert" data-flag="sideLeft">sideLeft</p> <p class="alert" data-flag="scale">scale</p> <p class="alert" data-flag="info">info</p>
require.config({ jquery:'component/jquery/jquery-3.1.0.min', liAlert: 'li/li-alert',//經常使用彈框組件 }) require(['jquery'],function($){ require(['liAlert'],function(){ $('.alert').on('click',function(event){ $.alert({ content: '<h1 style="display:flex;justify-content:center;">我是彈框</h1>', effect: $(event.currentTarget).attr('data-flag'), blankclose: true, //autoClose: true }) }) }) })
完整的代碼已上傳github: https://github.com/helijun/component/tree/master/alert