下來(lái)玩玩
Dialog component by native javascript
分析
對(duì)外暴露的方法
- show(options) 顯示dialog
- options 參數(shù)
- title 標(biāo)題,默認(rèn)為“”,不顯示標(biāo)題
- content 主內(nèi)容,默認(rèn)為"兄弟,你好像忘記傳content的值了"
- skin 皮膚,默認(rèn)為"",其實(shí)就是給dialog添加一個(gè)你的類(lèi)名,方便重置樣式
- btns 按鈕組,默認(rèn)為['確認(rèn)'],可選['xx',‘xx’],只取前兩個(gè)作為有效值,第一個(gè)為confirm,第二個(gè)為cancel
- confirm 點(diǎn)擊confirm按鈕的回調(diào),如確認(rèn)
- cancel 點(diǎn)擊cancel按鈕的回調(diào),如取消
- shadeClose 是否開(kāi)啟點(diǎn)擊遮罩關(guān)閉,默認(rèn)true
- animation 過(guò)渡動(dòng)畫(huà),默認(rèn)為1,可選0和2,注意這里的動(dòng)畫(huà)是指內(nèi)容區(qū)的動(dòng)畫(huà),最外層是固定為0
- options 參數(shù)
- hide() 關(guān)閉dialog
過(guò)渡動(dòng)畫(huà)
用css3的animation,具體看下面的css
先寫(xiě)好布局、樣式(后面會(huì)移植到Javascript生成DOM)
html
<!-- 最外層 -->
<div class="dialog-wrapper">
<!-- 居中主要層 -->
<div class="dialog">
<!-- 標(biāo)題 -->
<div class="title">消息提示</div>
<!-- 主要內(nèi)容 -->
<div class="content">兄弟,你好像忘記傳content的值了</div>
<!-- 按鈕組 -->
<div class="buttons">
<div class="btn cancel-btn">取消</div>
<div class="btn confirm-btn">確認(rèn)</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封裝
第一步,基本搭建
使用立即執(zhí)行函數(shù),只對(duì)外暴露兩個(gè)方法,show和hide
let dialog = (function () {
// 節(jié)點(diǎn)類(lèi)型
let elem, dialog, cancelBtn, confirmBtn;
// 動(dòng)畫(huà)函數(shù)數(shù)組
let animaArr = new Array(['fadeIn', 'fadeOut'], ['slideDown', 'slideUp'], ['scaleIn', 'scaleOut']);
// 當(dāng)前動(dòng)畫(huà)類(lèi)型
let currAnimation = '';
/**
* @method getNeedElement 獲取所需要的節(jié)點(diǎn)
*/
let getNeedElement = function () {
}
/**
* @method show 顯示dialog組件
* @param {Object} options 一系列參數(shù)
* @returns {Object} 當(dāng)前dialog節(jié)點(diǎn)
*/
let show = function (options) {
}
/**
* @method hide 關(guān)閉dialog組件
*/
let hide = function (index) {
}
/**
* @method bindEvent 給dialog綁定事件
* @param {Object} confirm 確認(rèn)回調(diào)
* @param {Object} cancel 取消回調(diào)
*/
let bindEvent = function (confirm, cancel, shadeClose) {
}
return {
show,
hide
}
})();
第二步,編寫(xiě)show方法
let show = function (options = {}) {
// 默認(rèn)參數(shù)
let {
title = '', content = '兄弟,你好像忘記傳content值了',
skin = '', btns = ['確定'],
confirm = null,
cancel = null,
shadeClose = true,
animation = 1
} = options;
// 皮膚類(lèi)名
let skinClass = skin ? ` ${skin}` : '';
// 給當(dāng)前動(dòng)畫(huà)類(lèi)型賦值
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;
// 獲取所需要的節(jié)點(diǎn)
getNeedElement();
// 綁定事件
bindEvent(confirm, cancel, shadeClose);
return elem;
}
第三步,編寫(xiě)hide方法
// 最外層加類(lèi)名hide
let hide = function () {
// 最外層執(zhí)行顯示動(dòng)畫(huà)(固定)
elem.classList.add('fadeOut');
// 內(nèi)容層執(zhí)行關(guān)閉動(dòng)畫(huà)
dialog.classList.add(`${animaArr[currAnimation][1]}`);
// 最終移除
setTimeout(() => {
elem.remove();
}, 200);
}
第四步,編寫(xiě)bindEvent方法
let bindEvent = function (confirm, cancel) {
// confirm按鈕的回調(diào)
confirmBtn && confirmBtn.addEventListener('click', e => {
hide();
confirm && confirm();
})
// cancel按鈕的回調(diào)
cancelBtn && cancelBtn.addEventListener('click', e => {
hide();
cancel && cancel();
})
// 是否開(kāi)啟點(diǎn)擊遮罩關(guān)閉
if (shadeClose) {
elem.addEventListener('click', e => {
let target = e.target || e.srcElement;
if (/dialog-wrapper/.test(target.className)) {
hide();
}
})
}
}
第五步,編寫(xiě)getNeedElement方法
let getNeedElement = function () {
// 一家人最重要是整整齊齊
elem = document.querySelector('.dialog-wrapper');
dialog = elem.querySelector('.dialog');
cancelBtn = elem.querySelector('.cancel-btn');
confirmBtn = elem.querySelector('.confirm-btn');
}
調(diào)用以及效果圖
-
無(wú)標(biāo)題
dialog.show({
content: '抱歉,該游戲暫無(wú)Android版本'
})
-
自定義標(biāo)題和按鈕
dialog.show({
title: '版本更新',
content: '檢測(cè)到最新版本為V1.0.2,是否更新',
btns: ['立即更新', '暫不更新']
})
-
動(dòng)畫(huà)效果為2時(shí)(彈性放大)
dialog.show({
title: '消息提示',
content: '此操作將不可逆轉(zhuǎn),確定刪除此項(xiàng)?',
btns: ['確定', '怕了'],
animation: 2
})
說(shuō)明
自己可以擴(kuò)展更多自定義參數(shù),動(dòng)畫(huà)需配合css3的animation
最后
本文到此結(jié)束,希望以上內(nèi)容對(duì)你有些許幫助,如若喜歡請(qǐng)記得點(diǎn)個(gè)贊跟關(guān)注哦 ??
image
微信公眾號(hào)
「前端宇宙情報(bào)局」,將不定時(shí)更新最新、實(shí)用的前端技巧/技術(shù)性文章,歡迎關(guān)注,一起學(xué)習(xí) ??


