原生JavaScript實(shí)現(xiàn)模態(tài)框的示例代碼
原生js封裝模態(tài)框
最近需要一個(gè)模態(tài)框,然后一種是提示類的,一種是確認(rèn)類型,我就想著再網(wǎng)上找一個(gè)然后修改一下,結(jié)果找到了,但是不深特別合適,我再次基礎(chǔ)上在做了修改,對功能有所增強(qiáng),純原生寫的,沒有任何依賴性,適應(yīng)性比較強(qiáng),值copy即可使用。
配置:可以在實(shí)例化時(shí)對options進(jìn)行參數(shù)設(shè)置,達(dá)到自己想要的效果
示例效果

代碼
HTML部分
<head> <meta charset="utf-8"> <title>彈出框</title> </head>
CSS部分
.mask {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
/* 遮罩層顏色 */
background: #bfbfbf;
opacity: 0.5;
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background-color: aliceblue;
border-radius: 5px;
z-index: 99;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.modal .modalTitle {
height: 50px;
box-sizing: content-box;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2px solid #eeeeee;
padding: 0 16px;
}
.modalTitle .closeModal {
width: 20px;
height: 20px;
border-radius: 5px;
line-height: 20px;
text-align: center;
font-size: 14px;
cursor: pointer;
background-image: url('https://typroas.oss-cn-hangzhou.aliyuncs.com/typroaImg/close.png');
background-size: 100% 100%;
}
.modalTitleText {
margin: 0 auto;
font-size: 17px;
}
.modal .main {
box-sizing: border-box;
padding: 16px;
height: calc(100% - 80px);
}
.modal .footer {
height: 50px;
text-align: right;
box-sizing: border-box;
padding-right: 16px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.footer .btnLeft,
.footer .btnRight {
width: 120px;
height: 35px;
text-align: center;
line-height: 30px;
border: none;
border-radius: 0.2rem;
margin-left: 8px;
background-color: #dddddd;
}
.footer .btnOk {
width: 120px;
height: 35px;
text-align: center;
line-height: 30px;
border: none;
border-radius: 0.3rem;
background-color: #1d73d3;
margin: 0 auto;
font-size: 17px;
color: white;
}
.footer .btnLeft:hover,
.footer .btnRight:hover {
background-color: #1D73D3;
color: #FFFFFF;
}JS部分
/**
* 彈出框
* @param {Object} options 彈出框配置項(xiàng)
*/
function Modal(options) {
options = Object.assign({
lateRelease: options.lateRelease ? options.lateRelease : false, //是否開啟延時(shí)關(guān)閉
lateReleaseTime: options.lateReleaseTime ? options.lateReleaseTime : 5000, // 延時(shí)關(guān)閉時(shí)間
isCreateOpen: options.isCreateOpen ? options.isCreateOpen : true, //是否創(chuàng)建完畢后就打開彈出框
type: options.type ? options.type : 'hint', // hint:提示框 confirm:確認(rèn)框
isTopRightcancel: true, // 是否需要右上角小x取消按鈕
modalTitle: options.modalTitle ? options.modalTitle : '溫馨提示',
backgroundColor: options.backgroundColor ? options.backgroundColor : '#fff', // 背景顏色
mask: options.mask ? options.mask : true, //是否顯示遮罩層,
content: options.content ? options.content : '', //彈框內(nèi)容
cancelText: options.cancelText ? options.cancelText : '取消', //取消按鈕文字
okText: options.okText ? options.okText : '確認(rèn)', // 確認(rèn)按鈕文字,
width: options.width ? options.width : 500, //對話框的寬度
onCancel: options.onCancel ? options.onCancel : this.closeModal, //取消按鈕回調(diào),默認(rèn)是關(guān)閉彈框
cancelCallBack: options.cancelCallBack ? options.cancelCallBack : () => {
console.log('你點(diǎn)擊了取消');
}, //取消回調(diào)
onOkCallBack: options.onOkCallBack ? options.onOkCallBack : () => {
console.log('你點(diǎn)擊了確認(rèn)');
}, // 確認(rèn)按鈕回調(diào)
}, options);
this.options = options;
// 創(chuàng)建遮罩層
function createMask() {
let mask = document.createElement('div')
mask.className = 'mask';
document.body.appendChild(mask);
}
// 創(chuàng)建modal彈框
function createModal(type) {
let modal = document.createElement('div');
let modalTitleDom = document.createElement('div');
let main = document.createElement('div');
let footer = document.createElement('div');
let btnLeft;
let btnRight;
let btnOk;
let closeIcon;
if (type == 'hint') {
btnOk = document.createElement('button');
btnOk.className = 'btnOk';
} else if (type == 'confirm') {
btnLeft = document.createElement('button');
btnLeft.className = 'btnLeft';
btnRight = document.createElement('button');
btnRight.className = 'btnRight';
}
let {
modalTitle,
content,
cancelText,
okText,
width,
onCancel,
onOkCallBack,
backgroundColor,
cancelCallBack,
isTopRightcancel,
isCreateOpen
} = this.options;
modal.className = 'modal';
modal.style.width = width + 'px';
modal.style.backgroundColor = backgroundColor;
modalTitleDom.className = 'modalTitle'
modalTitleDom.innerHTML = `<span class="modalTitleText">${modalTitle}</span>`;
if (isTopRightcancel) {
closeIcon = document.createElement('span');
closeIcon.addEventListener('click', closeModal.bind(this));
closeIcon.className = 'closeModal';
modalTitleDom.appendChild(closeIcon);
}
main.className = 'main';
main.innerHTML = content;
footer.className = 'footer';
if (type == 'hint') {
btnOk.innerHTML = '確認(rèn)';
footer.appendChild(btnOk);
onCancel = onCancel ? onCancel : this.closeModal;
btnOk.addEventListener('click', onCancel.bind(this));
} else if (type == 'confirm') {
btnLeft.innerHTML = '取消';
btnRight.innerHTML = '確認(rèn)';
footer.appendChild(btnLeft);
footer.appendChild(btnRight);
onCancel = onCancel ? onCancel : this.closeModal;
btnLeft.addEventListener('click', onCancel.bind(this));
btnRight.addEventListener('click', onOkCallBack);
}
modal.appendChild(modalTitleDom);
modal.appendChild(main);
modal.appendChild(footer);
modal.className = 'modal';
this.options.onCancel = onCancel.bind(this);
document.body.appendChild(modal);
}
// 關(guān)閉彈框
function closeModal(ev) {
options.cancelCallBack();
let target = ev ? ev.path[2] : document.getElementsByClassName('modal')[0];
let {
mask
} = this.options
mask ? document.body.removeChild(document.querySelector('.mask')) : null;
document.body.removeChild(target);
}
/**
* 當(dāng)設(shè)置默認(rèn)打開的時(shí)候可手動(dòng)調(diào)用該方法
*/
function openModal() {
this.init();
}
// 初始化
function init() {
let {
mask
} = this.options
mask ? createMask() : null
this.createModal(this.options.type);
}
Modal.prototype.init = init;
Modal.prototype.createModal = createModal;
Modal.prototype.closeModal = closeModal;
Modal.prototype.openModal = openModal;
// 執(zhí)行初始化方法
if (this.options.isCreateOpen) {
this.init();
if (this.options.lateRelease) {
setTimeout(() => {
let modal = document.getElementsByClassName('modal')[0];
if(modal){
this.options.onCancel();
}
}, this.options.lateReleaseTime);
}
}
}
document.getElementById("btn").addEventListener('click', () => {
let modal = new Modal({
lateRelease: true,
modalTitle: '我是第二個(gè)',
content: `<p>日常開發(fā)中,秒殺下單、搶紅包等等業(yè)務(wù)場景,都需要用到分布式鎖。而Redis非常適合作為分布式鎖使用。本文將分七個(gè)方案展開,跟大家探討Redis分布式鎖的正確使用方式。如果有不正確的地方,歡迎大家指出哈,一起學(xué)習(xí)一起進(jìn)步。</p>`
})
// modal.closeModal();
// modal.openModal();
})完整代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>彈出框</title>
</head>
<style type="text/css">
.mask {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
/* 遮罩層顏色 */
background: #bfbfbf;
opacity: 0.5;
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background-color: aliceblue;
border-radius: 5px;
z-index: 99;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.modal .modalTitle {
height: 50px;
box-sizing: content-box;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2px solid #eeeeee;
padding: 0 16px;
}
.modalTitle .closeModal {
width: 20px;
height: 20px;
border-radius: 5px;
line-height: 20px;
text-align: center;
font-size: 14px;
cursor: pointer;
background-image: url('https://typroas.oss-cn-hangzhou.aliyuncs.com/typroaImg/close.png');
background-size: 100% 100%;
}
.modalTitleText {
margin: 0 auto;
font-size: 17px;
}
.modal .main {
box-sizing: border-box;
padding: 16px;
height: calc(100% - 80px);
}
.modal .footer {
height: 50px;
text-align: right;
box-sizing: border-box;
padding-right: 16px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.footer .btnLeft,
.footer .btnRight {
width: 120px;
height: 35px;
text-align: center;
line-height: 30px;
border: none;
border-radius: 0.2rem;
margin-left: 8px;
background-color: #dddddd;
}
.footer .btnOk {
width: 120px;
height: 35px;
text-align: center;
line-height: 30px;
border: none;
border-radius: 0.3rem;
background-color: #1d73d3;
margin: 0 auto;
font-size: 17px;
color: white;
}
.footer .btnLeft:hover,
.footer .btnRight:hover {
background-color: #1D73D3;
color: #FFFFFF;
}
</style>
<body>
<button type="button" id="btn">彈出</button>
<script type="text/javascript">
/**
* 彈出框
* @param {Object} options 彈出框配置項(xiàng)
*/
function Modal(options) {
options = Object.assign({
lateRelease: options.lateRelease ? options.lateRelease : false, //是否開啟延時(shí)關(guān)閉
lateReleaseTime: options.lateReleaseTime ? options.lateReleaseTime : 5000, // 延時(shí)關(guān)閉時(shí)間
isCreateOpen: options.isCreateOpen ? options.isCreateOpen : true, //是否創(chuàng)建完畢后就打開彈出框
type: options.type ? options.type : 'hint', // hint:提示框 confirm:確認(rèn)框
isTopRightcancel: true, // 是否需要右上角小x取消按鈕
modalTitle: options.modalTitle ? options.modalTitle : '溫馨提示',
backgroundColor: options.backgroundColor ? options.backgroundColor : '#fff', // 背景顏色
mask: options.mask ? options.mask : true, //是否顯示遮罩層,
content: options.content ? options.content : '', //彈框內(nèi)容
cancelText: options.cancelText ? options.cancelText : '取消', //取消按鈕文字
okText: options.okText ? options.okText : '確認(rèn)', // 確認(rèn)按鈕文字,
width: options.width ? options.width : 500, //對話框的寬度
onCancel: options.onCancel ? options.onCancel : this.closeModal, //取消按鈕回調(diào),默認(rèn)是關(guān)閉彈框
cancelCallBack: options.cancelCallBack ? options.cancelCallBack : () => {
console.log('你點(diǎn)擊了取消');
}, //取消回調(diào)
onOkCallBack: options.onOkCallBack ? options.onOkCallBack : () => {
console.log('你點(diǎn)擊了確認(rèn)');
}, // 確認(rèn)按鈕回調(diào)
}, options);
this.options = options;
// 創(chuàng)建遮罩層
function createMask() {
let mask = document.createElement('div')
mask.className = 'mask';
document.body.appendChild(mask);
}
// 創(chuàng)建modal彈框
function createModal(type) {
let modal = document.createElement('div');
let modalTitleDom = document.createElement('div');
let main = document.createElement('div');
let footer = document.createElement('div');
let btnLeft;
let btnRight;
let btnOk;
let closeIcon;
if (type == 'hint') {
btnOk = document.createElement('button');
btnOk.className = 'btnOk';
} else if (type == 'confirm') {
btnLeft = document.createElement('button');
btnLeft.className = 'btnLeft';
btnRight = document.createElement('button');
btnRight.className = 'btnRight';
}
let {
modalTitle,
content,
cancelText,
okText,
width,
onCancel,
onOkCallBack,
backgroundColor,
cancelCallBack,
isTopRightcancel,
isCreateOpen
} = this.options;
modal.className = 'modal';
modal.style.width = width + 'px';
modal.style.backgroundColor = backgroundColor;
modalTitleDom.className = 'modalTitle'
modalTitleDom.innerHTML = `<span class="modalTitleText">${modalTitle}</span>`;
if (isTopRightcancel) {
closeIcon = document.createElement('span');
closeIcon.addEventListener('click', closeModal.bind(this));
closeIcon.className = 'closeModal';
modalTitleDom.appendChild(closeIcon);
}
main.className = 'main';
main.innerHTML = content;
footer.className = 'footer';
if (type == 'hint') {
btnOk.innerHTML = '確認(rèn)';
footer.appendChild(btnOk);
onCancel = onCancel ? onCancel : this.closeModal;
btnOk.addEventListener('click', onCancel.bind(this));
} else if (type == 'confirm') {
btnLeft.innerHTML = '取消';
btnRight.innerHTML = '確認(rèn)';
footer.appendChild(btnLeft);
footer.appendChild(btnRight);
onCancel = onCancel ? onCancel : this.closeModal;
btnLeft.addEventListener('click', onCancel.bind(this));
btnRight.addEventListener('click', onOkCallBack);
}
modal.appendChild(modalTitleDom);
modal.appendChild(main);
modal.appendChild(footer);
modal.className = 'modal';
this.options.onCancel = onCancel.bind(this);
document.body.appendChild(modal);
}
// 關(guān)閉彈框
function closeModal(ev) {
options.cancelCallBack();
let target = ev ? ev.path[2] : document.getElementsByClassName('modal')[0];
let {
mask
} = this.options
mask ? document.body.removeChild(document.querySelector('.mask')) : null;
document.body.removeChild(target);
}
/**
* 當(dāng)設(shè)置默認(rèn)打開的時(shí)候可手動(dòng)調(diào)用該方法
*/
function openModal() {
this.init();
}
// 初始化
function init() {
let {
mask
} = this.options
mask ? createMask() : null
this.createModal(this.options.type);
}
Modal.prototype.init = init;
Modal.prototype.createModal = createModal;
Modal.prototype.closeModal = closeModal;
Modal.prototype.openModal = openModal;
// 執(zhí)行初始化方法
if (this.options.isCreateOpen) {
this.init();
if (this.options.lateRelease) {
setTimeout(() => {
let modal = document.getElementsByClassName('modal')[0];
if(modal){
this.options.onCancel();
}
}, this.options.lateReleaseTime);
}
}
}
document.getElementById("btn").addEventListener('click', () => {
let modal = new Modal({
lateRelease: true,
modalTitle: '我是第二個(gè)',
content: `<p>日常開發(fā)中,秒殺下單、搶紅包等等業(yè)務(wù)場景,都需要用到分布式鎖。而Redis非常適合作為分布式鎖使用。本文將分七個(gè)方案展開,跟大家探討Redis分布式鎖的正確使用方式。如果有不正確的地方,歡迎大家指出哈,一起學(xué)習(xí)一起進(jìn)步。</p>`
})
// modal.closeModal();
// modal.openModal();
})
</script>
</body>
</html>以上就是原生JavaScript實(shí)現(xiàn)模態(tài)框的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于JavaScript模態(tài)框的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript給事件委托批量添加事件監(jiān)聽詳細(xì)流程
事件委托,一般來講,會(huì)把一個(gè)或者一組元素的事件委托到它的父層或者更外層元素上,真正綁定事件的是外層元素,當(dāng)事件響應(yīng)到需要綁定的元素上時(shí),會(huì)通過事件冒泡機(jī)制從而觸發(fā)它的外層元素的綁定事件上,然后在外層元素上去執(zhí)行函數(shù)2021-10-10
Layui數(shù)據(jù)表格跳轉(zhuǎn)到指定頁的實(shí)現(xiàn)方法
今天小編就為大家分享一篇Layui數(shù)據(jù)表格跳轉(zhuǎn)到指定頁的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
網(wǎng)絡(luò)之美 JavaScript中Get和Set訪問器的實(shí)現(xiàn)代碼
前兩天IE9 Beta版發(fā)布了,對于從事Web開發(fā)的朋友們來說真是個(gè)好消息啊,希望將來有一天各個(gè)瀏覽器都能遵循統(tǒng)一的標(biāo)準(zhǔn)。今天要和大家分享的是JavaScript中的Get和Set訪問器,和C#中的訪問器非常相似。2010-09-09
關(guān)于base64編碼和解碼的js工具函數(shù)
這篇文章主要介紹了關(guān)于base64編碼和解碼的js工具函數(shù),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
小程序自定義導(dǎo)航欄兼容適配所有機(jī)型(附完整案例)
這篇文章主要介紹了小程序自定義導(dǎo)航欄兼容適配所有機(jī)型(附完整案例),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04

