在移动端HTML5页面中,由于confirm()这个原生方法弹出框不太好看,且在各浏览器或WebView的样子不统一,我们一般会自行实现一个模拟该方法的弹出框。而且这个是一个使用频繁的方法,所以可以用JavaScript把它封装起来,便于调用。
以下是我实现代码和demo,样式可根据需要自行修改:
confirm.js
(function(exports, undefined){
'use strict';
var document = exports.document;
function createDiv(class_name){
var div = document.createElement('div');
div.setAttribute('class', class_name);
document.body.appendChild(div);
if(class_name === 'confirm'){
createConfirmDescendants(div);
}
return div;
}
function createConfirmDescendants(context){
var confirm_header = createDiv('confirm-header'),
confirm_main = createDiv('confirm-main'),
confirm_footer = createDiv('confirm-footer'),
btn_close = createDiv('close rounded'),
paragraph = document.createElement('p'),
btn_confirm = createDiv('button'),
btn_cancel = createDiv('button');
btn_close.dataset.action = 'close';
confirm_header.appendChild(btn_close);
confirm_main.appendChild(paragraph);
btn_confirm.textContent = '确定';
btn_confirm.dataset.action = 'confirm';
btn_cancel.textContent = '取消';
btn_cancel.dataset.action = 'close';
confirm_footer.appendChild(btn_confirm);
confirm_footer.appendChild(btn_cancel);
context.appendChild(confirm_header);
context.appendChild(confirm_main);
context.appendChild(confirm_footer);
}
function Confirm(){
if(!(this instanceof Confirm)) return;
return this;
}
Confirm.prototype = {
init: function(){
this.mask = this.mask || createDiv('mask');
this.confirm = this.confirm || createDiv('confirm');
this.initEvents.call(this);
return this;
},
show: function(message, confirm_handler){
this.confirm.querySelector('.confirm-main p').innerHTML = message || '';
if(this.confirmHandler === null){
this.confirmHandler = (confirm_handler && typeof confirm_handler === 'function') ? confirm_handler : null;
}
this.confirm.style.display = this.mask.style.display = 'block';
},
hide: function(){
var _this = this;
this.confirm.style.display = this.mask.style.display = 'none';
if(this.confirmHandler){
setTimeout(function(){
_this.confirmHandler = null;
}, 5e2);
}
exports.event && (exports.event.stopPropagation(), exports.event.preventDefault());
},
initEvents: function(){
this.hideHandler = this.hideHandler || this.hide.bind(this);
this.confirmEventProxyHandler = this.confirmEventProxyHandler || this.confirmEventProxy.bind(this);
this.confirmHandler = null;
this.mask.addEventListener('touchend', this.hideHandler, false);
this.confirm.addEventListener('touchend', this.confirmEventProxyHandler, false);
},
removeEvents: function(){
this.mask.removeEventListener('touchend', this.hideHandler, false);
this.confirm.removeEventListener('touchend', this.confirmEventProxyHandler, false);
this.hideHandler = this.confirmHandler = null;
},
reset: function(){
this.removeEvents.call(this);
this.confirm.style.display = this.mask.style.display = 'none';
},
confirmEventProxy: function(){
var target = exports.event.target;
switch(target.dataset.action){
case 'close':
this.hide.call(this);
break;
case 'confirm':
this.hide.call(this);
if(this.confirmHandler){
this.confirmHandler.call(target);
}
break;
}
}
}
var confirm = new Confirm().init();
exports.showConfirm = confirm.show.bind(confirm);
})(window);
main.css
html, body{
width: 100%;
margin: 0;
padding: 0;
}
html{
overflow-x: hidden;
overflow-y: auto;
}
ul{
list-style: none;
margin: 0;
padding: 0;
}
p{
padding: 0;
margin: 0;
}
a{
text-decoration: none;
}
/* close button */
.close{
width: 20px;
height: 20px;
position: relative;
display: inline-block;
overflow: hidden;
border-radius: 50%;
}
.close:active::before, .close:active::after{
background: #f4f4f4;
}
.close::before, .close::after{
content: '';
width: 80%;
height: 2px;
top: 9px;
left: 0;
right: 0;
position: absolute;
margin: auto;
background: #999;
}
.close::before{
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.close::after{
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.close.big{
-webkit-transform: scale(2);
transform: scale(2);
}
.close.hairline::before, .close.hairline::after{
height: 1px;
margin-top: -1px;
}
.close.thick::before, .close.thick::after{
height: 4px;
margin-top: -2px;
}
.close.heavy::before, .close.heavy::after{
height: 6px;
margin-top: -3px;
}
.close.pointy::before, .close.pointy::after{
width: 160%;
left: -30%;
}
.close.rounded::before, .close.rounded::after{
border-radius: 5px;
}
.close.blades::before, .close.blades::after{
border-radius: 5px 0;
}
.close.warp::before, .close.warp::after{
border-radius: 120% 0;
}
.close.fat::before, .close.fat::after{
border-radius: 100%;
}
/* mask */
.mask{
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, .7);
display: none;
}
/* confirm */
.confirm{
box-sizing: border-box;
width: 80%;
max-height: 40%;
position: fixed;
top: 50%;
left: 0;
right: 0;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
margin: 0 auto;
background-color: #fcfcfc;
border-radius: 4px;
box-shadow: 0 0 4px;
text-align: center;
font-size: 11pt;
font-weight: normal;
word-wrap: break-word;
overflow-x: hidden;
overflow-y: auto;
display: none;
}
.confirm-header{
box-sizing: border-box;
text-align: right;
}
.confirm-header .close{
width: 20px;
height: 20px;
}
.confirm-main{
box-sizing: border-box;
padding: 10px;
word-wrap: break-word;
}
.confirm-footer{
box-sizing: border-box;
padding: 10px;
text-align: center;
}
.confirm-footer .button{
height: 24px;
line-height: 24px;
margin: 0 5%;
padding: 0 20px;
background-color: #428bca;
color: #fff;
border-radius: 4px;
font-size: 11pt;
font-weight: bold;
display: inline-block;
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>confirm</title>
<link rel="stylesheet" href="./css/main.css">
<style>
#btn_showConfirm{
width: 200px;
height: 30px;
line-height: 30px;
margin: 100px auto 0;
border-radius: 4px;
background-color: #428bca;
color: #fff;
font-weight: bold;
text-align: center;
}
</style>
</head>
<body>
<div id="btn_showConfirm">show a message.</div>
<!-- javascript -->
<script src="./js/confirm.min.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function(){
initEvents();
}, false);
function initEvents(){
// btn_showConfirm
document.querySelector('#btn_showConfirm').addEventListener('touchend', function(){
showConfirm('This is a message.', function(){
console.log('This is a confirm callback.');
});
}, false);
}
</script>
</body>
</html>