簡單實現(xiàn)移動端彈窗及l(fā)oading組件

最近用到了很多彈窗和頁面加載效果,之前只是隨調(diào)隨用,也沒去整理,網(wǎng)上大多的插件要不是太冗余,就是樣式風格太呆板,所以今天閑著就整理了一個出來。具備基本的彈窗功能,包括alert、conrirmtips三種。(三種的區(qū)別是alert彈窗只生成確定按鈕,接受確定回調(diào)。confirm彈窗生成確定和取消按鈕,接受確定和取消回調(diào)。tips不生成按鈕,可以設置自動隱藏或者點擊遮罩層來隱藏)。組件可以更換背景、文字寬高等屬性,也具備選擇是否添加遮罩層回調(diào)函數(shù)等基本功能。此外,也一并引入了頁面loading的效果。

組件用到了css3的動畫庫** animated.min.css,可以自行引入。彈窗組件主要用閉包的形式去寫,支持將整個變量賦值給window,也支持用es6 module exports** 的方法供項目隨處使用。下面貼上popupwin.js的代碼:

!function(){
    var popup = { //css3動畫庫所有動畫效果 任君使用
        EFFECT:["bounce","flash","pulse","rubberBand","shake","swing","tada","wobble","bounceIn","bounceInDown","bounceInLeft","bounceInRight","bounceInUp","bounceOut","bounceOutDown","bounceOutLeft","bounceOutRight","bounceOutUp","fadeIn","fadeInDown","fadeInDownBig","fadeInLeft","fadeInLeftBig","fadeInRight",
"fadeInRightBig","fadeInUp","fadeInUpBig","fadeOut","fadeOutDown","fadeOutDownBig","fadeOutLeft","fadeOutLeftBig","fadeOutRight","fadeOutRightBig","fadeOutUp","fadeOutUpBig","flip","flipInX","flipInY","flipOutX","flipOutY","lightSpeedIn","lightSpeedOut","rotateIn","rotateInDownLeft","rotateInDownRight",
"rotateInUpLeft","rotateInUpRight","rotateOut","rotateOutDownLeft","rotateOutDownRight","rotateOutUpLe",
"rotateOutUpRigt","slideInDown","slideInLeft","slideInRight","slideOutLeft","slideOutRight","slideOutUp","hinge","rollIn","rollOut"],

        defaultOptions:{
            themeColor: {
                bgColor: '#e5004f', //主題背景顏色
                fontColor: '#fff' //主題文字顏色
            },  
            type: 'alert',  //彈框類型 包括 alert、confirm、tips三種
            title: '提示',    //彈框標題
            content: '', //彈框內(nèi)容
            width: '90%', //彈框寬度
            yes: '確定', //確定按鈕 文本
            no: '取消', //取消按鈕 文本
            isHide: false, //是否在彈出后隱藏
            onConfirm: function(){ //點擊確定執(zhí)行的回調(diào)函數(shù)
                var options = {};
                options.effect = 'bounceOut';
                this.showAnimation('bounceOut',true);
                this.removeMask();
            }, 
            onCancel: function(){ //點擊取消執(zhí)行的回調(diào)函數(shù)
                var options = {};
                options.effect = 'bounceOut';
                this.showAnimation('bounceOut',true);
                this.removeMask();
            }, 
            effect: 'bounceIn', //彈框效果
            mask: null //是否有背景遮罩層 傳入透明度和是否可以點擊  如{opacity: 0.8,isClick: true}
        },
        _bindEvent: function(options){
            if(options.onConfirm){
                $(document).off('click','.confirm-btn');
                $(document).on('click','.confirm-btn',options.onConfirm.bind(this));
            }
            if(options.onCancel){
                $(document).off('click','.cancel-btn');
                $(document).on('click','.cancel-btn',options.onCancel.bind(this));
            }
        },
        showAnimation: function(effect,isHide){
            //isHide參數(shù)表示彈窗在彈出后隔一段時間自動隱藏
            if(effect && this.checkEffect(effect)){
                $('.dialog-diy').addClass(' animated '+ effect).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend',function(){
                    $(this).removeClass(' animated '+ effect);
                    if(isHide){
                        $('.dialog-diy').hide();
                    }
                });
            }
        },
        getTemplate: function(options){
            var onConfirm = (options.onConfirm && typeof(options.onConfirm) === 'function' ?'onConfirm' : '');
            var onCancel = (options.onConfirm && typeof(options.onCancel) === 'function' ?'onCancel' : '');
            switch(options.type){
                case 'alert': return $('<div class="popup dialog-diy" style="width:'+options.width+';left:'+getOffsetLeft(options.width)+'%">\
                                <span class="close"></span>\
                                <div class="pop-header" style="background:'+options.themeColor.bgColor+';color:'+options.themeColor.fontColor+'">'+options.title+'</div>\
                                <div class="pop-body">'+options.content+'\
                                </div>\
                                <div class="pop-footer"><a class="confirm-btn '+onConfirm+'" >'+options.yes+'</a></div>\
                                </div>');
                case 'confirm': return $('<div class="popup dialog-diy" style="width:'+options.width+';left:'+getOffsetLeft(options.width)+'%">\
                                <span class="close"></span>\
                                <div class="pop-header" style="background:'+options.themeColor.bgColor+';color:'+options.themeColor.fontColor+'">'+options.title+'</div>\
                                <div class="pop-body">'+options.content+'\
                                </div>\
                                <div class="pop-footer"><a class="cancel-btn '+onCancel+'" href="javascript:void(0)">'+options.no+'</a>\
                                <a class="confirm-btn '+onConfirm+'" href="javascript:void(0)">'+options.yes+'</a>\
                                </div>\
                                </div>');
                case 'tips': return $('<div class="popup dialog-diy" style="width:'+options.width+';left:'+getOffsetLeft(options.width)+'%">\
                                <span class="close"></span>\
                                <div class="pop-header" style="background:'+options.themeColor.bgColor+';color:'+options.themeColor.fontColor+'">'+options.title+'</div>\
                                <div class="pop-body">'+options.content+'\
                                </div>\
                                </div>') ;

            }
            function getOffsetLeft(width){
                var leftRate = 0;
                var widthRate = Number(width.substring(0,width.length-1));
                if(widthRate > 0 && widthRate < 100) {
                    leftRate = (100-widthRate)/2;
                } 
                return leftRate;
            }
        },
        removeDialog: function(){
            if($('.dialog-diy').length){
                $('.dialog-diy').remove();
            }
            if($('#popupMask').length){
                $('#popupMask').remove();
            }
        },
        removeMask: function(){
            if($('#popupMask').length){
                $('#popupMask').fadeOut();
                setTimeout(function(){
                    $('#popupMask').remove();
                },1000);
            }
        },
        checkEffect: function(effect){
            effect = effect || "";
            if(!effect){return false;}
            var tmp = this.EFFECT.join(",");
            if(tmp.indexOf(effect)>=0){return true;}
            return false;
        },
        setMask: function(mask){
            //傳入兩個參數(shù) 透明度和是否可以點擊 isClick為真的情況下可以通過點擊遮罩層關閉彈窗
            var self = this;
            var $mask = $('<div id="popupMask" style="width:100%;height:100%;position:absolute;left:0;top:0;background:#000;opacity:'+mask.opacity+'"></div>');
            $('body').append($mask);
            if(mask.isClick){
                $(document).off('click','#popupMask');
                $(document).on('click','#popupMask',function(){
                    self.showAnimation('bounceOut',true);
                    self.removeMask();
                });
            }
        },
        isDot: function(num){ //判斷是否為大于0小于1的小數(shù)
            if(!isNaN(num) && num < 1){
                return true;
            }
            return false;
        },
        alert: function(title,content,cb){ 
            var opts = this.defaultOptions;
            opts.title = title || this.defaultOptions.title;
            opts.content = content;
            opts.type = 'alert';
            if(cb && typeof cb === 'function'){
                opts.onConfirm = cb;
            }
            var tpl = this.getTemplate(opts);
            $('body').append(tpl);
            this.showAnimation(opts.effect);
            this._bindEvent(opts);
        },
        confirm: function(title,content,cb1,cb2){
            var opts = this.defaultOptions;
            opts.title = title || this.defaultOptions.title;
            opts.content = content;
            opts.type = 'confirm';
            if(cb1 && cb1 === 'function'){
                opts.onConfirm = cb1;
            }
            if(cb2 && cb2 === 'function'){
                opts.onCancel = cb2;
            }
            var tpl = this.getTemplate(opts);
            $('body').append(tpl);
            this.showAnimation(opts.effect);
            this._bindEvent(opts);
        },
        tips: function(title,content){
            var self = this;
            var opts = this.defaultOptions;
            opts.title = title || this.defaultOptions.title;
            opts.content = content || '';
            opts.type = 'tips';
            var tpl = this.getTemplate(opts);
            $('body').append(tpl);
            this.showAnimation(opts.effect);
            setTimeout(function(){
                self.showAnimation('bounceOut',true);
                self.removeMask();
            },3000);
        },
        removeLoading: function(){
            if($('.popup-spinner').length){
                $('.popup-spinner').fadeOut();
                setTimeout(function(){
                    $('.popup-spinner').remove();
                },2000);
            }
            if($('#popupMask').length){
                $('#popupMask').fadeOut();
                setTimeout(function(){
                    $('#popupMask').remove();
                },2000);
            }
        },
        loading: function(opacity,isClick,color){//傳入透明度,是否可以點擊,加載條顏色
            if($('.popup-spinner').length){
                $('.popup-spinner').remove();
            }
            if($('#popupMask').length){
                $('#popupMask').remove();
            }
            var $loading = $('<div class="popup-spinner"><div style="background-color:'+color+'" class="bounce1"></div><div style="background-color:'+color+'" class="bounce2"></div><div style="background-color:'+color+'" class="bounce3"></div></div>');
            $('body').append($loading);
            var mask = {opacity:opacity,isClick:isClick};
            this.setMask(mask);
        },
        _ready: function(options){
            console.log(options);
            var self = this;
            this.removeDialog();
            var tpl = this.getTemplate(options);
            $('body').append(tpl);
            if(options.mask && this.isDot(options.mask.opacity)){
                this.setMask(options.mask);
            }
            this.showAnimation(options.effect);
            if(options.isHide){
                setTimeout(function(){
                    self.showAnimation('bounceOut',true);
                    self.removeMask();
                },3000);
                
            }
        },
        _init: function(options){
            var options = options || this.defaultOptions;
            var self = this;
            for(var key in this.defaultOptions){
                if(options[key] == undefined){
                    options[key] = this.defaultOptions[key];
                }
            }
            $(function(){
                self._ready(options);
            });
            this._bindEvent(options);
        }
    };

    window.popup = popup; //賦值給window下的變量
    module.exports = popup; //es6模塊導出
}();

可以通過 _init 函數(shù)初始化彈窗,也可以簡潔調(diào)用alert、confirm、tips。代碼如下:

//導入相關 js css
import '../../common/css/popupwin.css'
import '../../common/css/animated.css'
import $ from 'expose-loader?!jquery'
import popup from '../../common/js/lib/popupwin.js'

//沒有傳遞的參數(shù)將會使用組件的默認參數(shù),參看defaultOptions
var options = {
    themeColor: {
        bgColor: 'yellow',
        fontColor: '#000'
    }, 
    type: 'confirm',  
    title: '溫馨提示',  
    content: 'hellowrod!!!', 
    width: '90%', 
    yes: '確定',
    no: '取消', 
    isHide: false, 
        onConfirm: function(){alert('just do it');},
    onCancel: null, 
    effect: 'bounceIn',
    mask: {
          opacity: 0.8,
          isClick: true
        }
};

popup._init(options); //通用方式調(diào)用

//alert簡潔調(diào)用
popup.alert('提示','helloworld come from alert'); 

//confirm簡潔調(diào)用
popup.confirm('提示','helloworld come from confirm',function(){
   alert('just do it'); 
});

//tips簡潔調(diào)用
popup.tips('提示','helloworld come from tips');

//loading加載
popup.loading(0.8,true,'#fff');

//移除loading
popup.removeLoading();


附上popupwin.css的樣式代碼

/**彈窗樣式*/
.popup{width: 90%;max-width: 500px;margin: 30px auto 0 auto;position: absolute;background: #fff;border-radius: .1rem;top: 20%;left: 5%;z-index: 999;}
.popup .pop-header{color:#fff;padding:.08rem 0;background:#e5004f;text-align:center;font-size:.16rem;border-radius:.1rem .1rem 0 0;}
.popup .pop-body{padding:.15rem .15rem .15rem;min-height:1rem;color:#000;font-size:.16rem;}
.popup .pop-body.large{padding:.15rem;min-height:1rem;max-height:3rem;overflow:auto;}
.popup .pop-footer{text-align:center;padding-bottom:.2rem}
.popup .pop-footer .btn{width:60%;}


/**loading動畫樣式**/
.popup-spinner {width: 1rem;height: .3rem;position: absolute;top:50%;left:50%;margin-left: -.5rem;margin-top: -.15rem;line-height: .3rem;z-index: 1000;}
 
.popup-spinner > div {width: .15rem;height: .15rem;background-color: #67CF22;margin-left: .05rem;margin-right: .05rem;border-radius: 100%;display: inline-block;-webkit-animation: bouncedelay 1.4s infinite ease-in-out;animation: bouncedelay 1.4s infinite ease-in-out;-webkit-animation-fill-mode: both;animation-fill-mode: both;}
 
.popup-spinner .bounce1 {-webkit-animation-delay: -0.32s;animation-delay: -0.32s;}
 
.popup-spinner .bounce2 {-webkit-animation-delay: -0.16s;animation-delay: -0.16s;}
 
@-webkit-keyframes bouncedelay {0%, 80%, 100% { -webkit-transform: scale(0.0) }40% { -webkit-transform: scale(1.0) }}
 
@keyframes bouncedelay {0%, 80%, 100% {transform: scale(0.0);-webkit-transform: scale(0.0);} 40% {transform: scale(1.0);-webkit-transform: scale(1.0);}}

總結

無。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評論 25 708
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 15,650評論 4 61
  • 移動端dialog組件 dialogView是滿足移動端下,用戶自定義的dialog組件,API可擴展性強,使用便...
    小興nice閱讀 4,151評論 2 11
  • 調(diào)試android設備時輸入adb devices出現(xiàn)提示error,經(jīng)過一番折騰后終于解決了,首先重啟設備,再在...
    雪花曬干閱讀 852評論 0 1
  • 小夭說什么樣的鎧甲也沒有用,內(nèi)里還不是一碰就碎。大實話是這個世界上最沒有營養(yǎng)的補品。撇嘴。 男人和女人生下來的時候...
    愚蠢的狐貍大叔閱讀 343評論 2 0

友情鏈接更多精彩內(nèi)容