分析
对外暴露的方法
show(options) 显示dialog
title 标题,默认为“”,不显示标题
content 主内容,默认为"兄弟,你好像忘记传content的值了"
skin 皮肤,默认为"",其实就是给dialog添加一个你的类名,方便重置样式
btns 按钮组,默认为['确认'],可选['xx',‘xx’],只取前两个作为有效值,第一个为confirm,第二个为cancel
confirm 点击confirm按钮的回调,如确认
cancel 点击cancel按钮的回调,如取消
shadeClose 是否开启点击遮罩关闭,默认true
animation 过渡动画,默认为1,可选0和2,注意这里的动画是指内容区的动画,最外层是固定为0
options 参数
hide() 关闭dialog
过渡动画
用css3的animation,具体看下面的css
先写好布局、样式(后面会移植到Javascript生成DOM)
html
<!-- 最外层 --><div class="dialog-wrapper"> <!-- 居中主要层 --> <div class="dialog"> <!-- 标题 --> <div class="title">消息提示</div> <!-- 主要内容 --> <div class="content">兄弟,你好像忘记传content的值了</div> <!-- 按钮组 --> <div class="buttons"> <div class="btn cancel-btn">取消</div> <div class="btn confirm-btn">确认</div> </div> </div></div>
css(可先跳过)
body,html { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; }.dialog-wrapper { position: fixed; display: flex; justify-content: center; align-items: center; top: 0; left: 0; width: 100vw; height: 100vh; background-color: rgba(49, 49, 49, 0.5); color: #313131; font-size: 10px; -webkit-tap-highlight-color: transparent; }.dialog-wrapper.fadeIn { animation: fadeIn .2s ease; }.dialog-wrapper.fadeOut { animation: fadeOut .2s ease forwards; }.dialog-wrapper .dialog { position: relative; width: 85vw; max-width: 30em; border-radius: .4em; background-color: #fff; box-sizing: border-box; overflow: hidden; box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.1); }.dialog-wrapper .dialog.slideDown { animation: slideDown .2s ease; }.dialog-wrapper .dialog.slideUp { animation: slideUp .2s ease forwards; }.dialog-wrapper .dialog.scaleIn { animation: scaleIn 0.2s cubic-bezier(0.07, 0.89, 0.95, 1.4); }.dialog-wrapper .dialog.scaleOut { animation: scaleOut 0.2s cubic-bezier(0.07, 0.89, 0.95, 1.4) forwards; }.dialog-wrapper .dialog .btn { cursor: pointer; }.dialog-wrapper .dialog .btn:active { background-color: #f4f4f4; }.dialog-wrapper .dialog .close-btn { position: absolute; top: 0; right: 0; padding: 10px; font-size: 1.8em; }.dialog-wrapper .dialog .title { font-size: 1.8em; padding: 15px; text-align: center; background-color: #f4f4f4; }.dialog-wrapper .dialog .title:empty { display: none; }.dialog-wrapper .dialog .content { padding: 40px 20px; font-size: 1.6em; text-align: center; }.dialog-wrapper .dialog .buttons { font-size: 1.6em; display: flex; flex-flow: row-reverse; }.dialog-wrapper .dialog .buttons .btn { flex: 1; padding: 15px; text-align: center; border-top: 1px solid #ebebeb; }.dialog-wrapper .dialog .buttons .btn.confirm-btn { color: #f2d985; }.dialog-wrapper .dialog .buttons .btn.cancel-btn { color: #313131; border-right: 1px solid #ebebeb; } @keyframes slideDown { from { transform: translateY(-3em); } to { transform: translateY(0); } } @keyframes slideUp { from { transform: translateY(0); } to { transform: translateY(-3em); } } @keyframes fadeIn { from { opacity: .5; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } @keyframes scaleIn { from { transform: scale(0.8); } to { transform: scale(1); } } @keyframes scaleOut { from { transform: scale(1); } to { transform: scale(0.8); } }
Javascript封装
第一步,基本搭建
使用立即执行函数,只对外暴露两个方法,show和hide
let dialog = (function () { // 节点类型 let elem, dialog, cancelBtn, confirmBtn; // 动画函数数组 let animaArr = new Array(['fadeIn', 'fadeOut'], ['slideDown', 'slideUp'], ['scaleIn', 'scaleOut']); // 当前动画类型 let currAnimation = ''; /** * @method getNeedElement 获取所需要的节点 */ let getNeedElement = function () { } /** * @method show 显示dialog组件 * @param {Object} options 一系列参数 * @returns {Object} 当前dialog节点 */ let show = function (options) { } /** * @method hide 关闭dialog组件 */ let hide = function (index) { } /** * @method bindEvent 给dialog绑定事件 * @param {Object} confirm 确认回调 * @param {Object} cancel 取消回调 */ let bindEvent = function (confirm, cancel, shadeClose) { } return { show, hide } })();
第二步,编写show方法
let show = function (options = {}) { // 默认参数 let { title = '', content = '兄弟,你好像忘记传content值了', skin = '', btns = ['确定'], confirm = null, cancel = null, shadeClose = true, animation = 1 } = options; // 皮肤类名 let skinClass = skin ? ` ${skin}` : ''; // 给当前动画类型赋值 currAnimation = animation; // 生成按钮 let btnTemp = ''; btns.forEach((item, index) => { if (index == 2) return; let btnClass = index == 0 ? 'confirm-btn' : 'cancel-btn'; let temp = `<div class="btn ${btnClass}">${item}</div>` btnTemp += temp }) // 最终生成的HTML let html = ` <div class="dialog-wrapper fadeIn"> <div class="dialog${skinClass} ${animaArr[currAnimation][0]}"> <div class="title">${title}</div> <div class="content">${content}</div> <div class="buttons">${btnTemp}</div> </div> </div> `; // 添加到Body document.body.innerHTML += html; // 获取所需要的节点 getNeedElement(); // 绑定事件 bindEvent(confirm, cancel, shadeClose); return elem; }
第三步,编写hide方法
// 最外层加类名hidelet hide = function () { // 最外层执行显示动画(固定) elem.classList.add('fadeOut'); // 内容层执行关闭动画 dialog.classList.add(`${animaArr[currAnimation][1]}`); // 最终移除 setTimeout(() => { elem.remove(); }, 200); }
第四步,编写bindEvent方法
let bindEvent = function (confirm, cancel) { // confirm按钮的回调 confirmBtn && confirmBtn.addEventListener('click', e => { hide(); confirm && confirm(); }) // cancel按钮的回调 cancelBtn && cancelBtn.addEventListener('click', e => { hide(); cancel && confirm(); }) // 是否开启点击遮罩关闭 if (shadeClose) { elem.addEventListener('click', e => { let target = e.target || e.srcElement; if (/dialog-wrapper/.test(target.className)) { hide(); } }) } }
第五步,编写getNeedElement方法
let getNeedElement = function () { // 一家人最重要是整整齐齐 elem = document.querySelector('.dialog-wrapper'); dialog = elem.querySelector('.dialog'); cancelBtn = elem.querySelector('.cancel-btn'); confirmBtn = elem.querySelector('.confirm-btn'); }
调用以及效果图
无标题
dialog.show({ content: '抱歉,该游戏暂无Android版本'})
自定义标题和按钮
dialog.show({ title: '版本更新', content: '检测到最新版本为V1.0.2,是否更新', btns: ['立即更新', '暂不更新'] })
动画效果为2时(弹性放大)
dialog.show({ title: '消息提示', content: '此操作将不可逆转,确定删除此项?', btns: ['确定', '怕了'], animation: 2})
说明
自己可以扩展更多自定义参数,动画需配合css3的animation
作者:daydreammoon
链接:https://www.jianshu.com/p/ffc5e41d4d0f