dialog.html
<script type="text/template" id="dialog">
<div class="<%=className%>">
<div class="weui-mask"></div>
<div class="weui-dialog">
<% if(title){ %>
<div class="weui-dialog__hd"><strong class="weui-dialog__title"><%=title%></strong></div>
<% } %>
<div class="weui-dialog__bd"><%=content%></div>
<div class="weui-dialog__ft">
<% for(var i = 0; i < buttons.length; i++){ %>
<a href="javascript:;" class="weui-dialog__btn weui-dialog__btn_<%=buttons[i]['type']%>"><%=buttons[i]['label']%></a>
<% } %>
</div>
</div>
</div>
</script>
dialog.less
@weuiDialogLineColor: #DCDCDC;
.setTopLine(@c: #DCDCDC) {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1px solid @c;
color: @c;
transform-origin: 0 0;
transform: scaleY(0.5);
}
.setTapColor(@c:rgba(0,0,0,0)) {
-webkit-tap-highlight-color: @c;
}
.setLeftLine(@c: #DCDCDC) {
content: " ";
position: absolute;
left: 0;
top: 0;
width: 1px;
bottom: 0;
border-left: 1px solid @c;
color: @c;
transform-origin: 0 0;
transform: scaleX(0.5);
}
.ui-dialog {
position: fixed;
z-index: 5000;
width: 72%;
max-width: 300px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #FFFFFF;
text-align: center;
border-radius: 3px;
overflow: hidden;
}
.ui-dialog__title {
font-weight: 400;
font-size: 15px;
padding-top: 21px;
padding-bottom: 21px;
}
.ui-dialog__bd {
padding-top: 21px;
padding-bottom: 21px;
font-size: 13px;
word-wrap: break-word;
word-break: break-all;
color: black;
}
.ui-dialog__title~.ui-dialog__bd{
padding-top: 0;
}
.ui-dialog__ft {
position: relative;
font-size: 15px;
display: flex;
&:after {
content: " ";
.setTopLine(@weuiDialogLineColor);
}
}
.ui-dialog__btn {
display: block;
padding-top: 15px;
padding-bottom: 15px;
flex: 1;
color: #FF8F3B;
text-decoration: none;
.setTapColor();
&:active {
background-color: #EEEEEE;
}
position: relative;
&:after {
content: " ";
.setLeftLine(@weuiDialogLineColor);
}
&:first-child {
&:after {
display: none;
}
}
}
.ui-dialog__btn_default {
color: #FF8F3B;
}
.ui-dialog__btn_primary {
color: #FF8F3B;
}
.ui-mask {
position: fixed;
z-index: 1000;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, .6);
}
.ui-mask_transparent{
position: fixed;
z-index: 1000;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
@-webkit-keyframes fadeIn{
from{
opacity:0;
}
to{
opacity:1;
}
}
@keyframes fadeIn{
from{
opacity:0;
}
to{
opacity:1;
}
}
.ui-animate-fade-in{
-webkit-animation:fadeIn ease .3s forwards;
animation:fadeIn ease .3s forwards;
}
@-webkit-keyframes fadeOut{
from{
opacity:1;
}
to{
opacity:0;
}
}
@keyframes fadeOut{
from{
opacity:1;
}
to{
opacity:0;
}
}
.ui-animate-fade-out{
-webkit-animation:fadeOut ease .3s forwards;
animation:fadeOut ease .3s forwards;
}
@media screen and (min-width: 1024px) {
.ui-dialog {
width: 35%;
}
}
dialog.js
/**
* dialog,弹窗,alert和confirm的父类
*
* @param {object=} options 配置项
* @param {string=} options.title 弹窗的标题
* @param {string=} options.content 弹窗的内容
* @param {string=} options.className 弹窗的自定义类名
* @param {array=} options.buttons 按钮配置项
*
* @param {string} [options.buttons[].label=确定] 按钮的文字
* @param {string} [options.buttons[].type=primary] 按钮的类型 [primary, default]
* @param {function} [options.buttons[].onClick=$.noop] 按钮的回调
*
* @example
* Dialog({
* title: 'dialog标题',
* content: 'dialog内容',
* className: 'custom-classname',
* buttons: [{
* label: '取消',
* type: 'default',
* onClick: function () { alert('取消') }
* }, {
* label: '确定',
* type: 'primary',
* onClick: function () { alert('确定') }
* }]
* });
*
* // 主动关闭
* var $dialog = Dialog({...});
* $dialog.hide(function(){
* console.log('`dialog` has been hidden');
* });
*/
(function(global,factory){
if(typeof define === 'function' && define.amd){
define(function(){
return factory();
});
}else if(typeof module !== 'undefined' && module.exports){
module.exports = factory();
}else{
global.Dialog = factory(global);
}
}(typeof window !== 'undefined' ? window : this,function(win){
var _sington;
var dialog = function(options){
var style = '.ui-dialog{position:fixed;z-index:5000;width:72%;max-width:300px;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#FFFFFF;text-align:center;border-radius:3px;overflow:hidden;}.ui-dialog__title{font-weight:400;font-size:15px;padding-top:21px;padding-bottom:21px;}.ui-dialog__bd{padding-top:21px;padding-bottom:21px;font-size:13px;word-wrap:break-word;word-break:break-all;color:black;}.ui-dialog__title ~ .ui-dialog__bd{padding-top:0;}.ui-dialog__ft{position:relative;font-size:15px;display:flex;}.ui-dialog__ft:after{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #DCDCDC;color:#DCDCDC;transform-origin:0 0;transform:scaleY(0.5);}.ui-dialog__btn{display:block;padding-top:15px;padding-bottom:15px;flex:1;color:#FF8F3B;text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0);position:relative;}.ui-dialog__btn:active{background-color:#EEEEEE;}.ui-dialog__btn:after{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1px solid #DCDCDC;color:#DCDCDC;transform-origin:0 0;transform:scaleX(0.5);}.ui-dialog__btn:first-child:after{display:none;}.ui-dialog__btn_default{color:#FF8F3B;}.ui-dialog__btn_primary{color:#FF8F3B;}.ui-mask{position:fixed;z-index:1000;top:0;right:0;left:0;bottom:0;background:rgba(0,0,0,0.6);}.ui-mask_transparent{position:fixed;z-index:1000;top:0;right:0;left:0;bottom:0;}@-webkit-keyframes fadeIn{from{opacity:0;}to{opacity:1;}}@keyframes fadeIn{from{opacity:0;}to{opacity:1;}}.ui-animate-fade-in{-webkit-animation:fadeIn ease .3s forwards;animation:fadeIn ease .3s forwards;}@-webkit-keyframes fadeOut{from{opacity:1;}to{opacity:0;}}@keyframes fadeOut{from{opacity:1;}to{opacity:0;}}.ui-animate-fade-out{-webkit-animation:fadeOut ease .3s forwards;animation:fadeOut ease .3s forwards;}@media screen and (min-width:1024px){.ui-dialog{width:35%;}}';
$('head').append('<style type="text/css">'+style+'</style>');
if(_sington) return _sington;
options = $.extend({},{
title: '',
content: null,
className: '',
buttons: [{
label: '确定',
type: 'primary',
onClick: function(){}
}]
}, options);
var contentHtml = "";
buttonsHtml = "";
if(options.content){
contentHtml = '<div class="ui-dialog__bd">'+options.content+'</div>';
}
for(var i = 0; i < options.buttons.length; i++){
buttonsHtml += '<a href="javascript:;" class="ui-dialog__btn ui-dialog__btn_'+options.buttons[i]['type']+'">'+options.buttons[i]['label']+'</a>';
}
const dialogWrap = '<div class="'+options.className+'">'+
' <div class="ui-mask"></div>'+
' <div class="ui-dialog">'+
' <div class="ui-dialog__title">'+options.title+'</div>'+
contentHtml+
' <div class="ui-dialog__ft">'+
buttonsHtml+
' </div>'+
' </div>'+
'</div>';
const $dialogWrap = $(dialogWrap);
const $dialog = $dialogWrap.find('.ui-dialog');
const $mask = $dialogWrap.find('.ui-mask');
function _hide(callback){
_hide = function(){}; // 防止二次调用导致报错
$mask.addClass('ui-animate-fade-out');
$dialog
.addClass('ui-animate-fade-out')
.on('animationend webkitAnimationEnd', function () {
$dialogWrap.remove();
_sington = false;
callback && callback();
});
}
function hide(callback){ _hide(callback); }
$('body').append($dialogWrap);
// 不能直接把.ui-animate-fade-in加到$dialog,会导致mask的z-index有问题
$mask.addClass('ui-animate-fade-in');
$dialog.addClass('ui-animate-fade-in');
$dialogWrap.on('click', '.ui-dialog__btn', function (evt) {
const index = getIndex.call($(this));
if (options.buttons[index].onClick) {
if (options.buttons[index].onClick.call(this, evt) !== false) hide();
} else {
hide();
}
});
_sington = $dialogWrap[0];
_sington.hide = hide;
return _sington;
function getIndex() {
const $element = this[0];
const $parent = $element.parentNode;
return Array.prototype.indexOf.call($parent.children, $element);
}
};
return dialog;
}));