最近用到了很多彈窗和頁面加載效果,之前只是隨調(diào)隨用,也沒去整理,網(wǎng)上大多的插件要不是太冗余,就是樣式風格太呆板,所以今天閑著就整理了一個出來。具備基本的彈窗功能,包括alert、conrirm、tips三種。(三種的區(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);}}
總結
無。