欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

H5 pc端,移动端自定义弹窗模块思路

程序员文章站 2023-12-28 21:48:58
...

再一次项目中要求 在提交时 要让客户核对下信息 并且要去输入密码  然而再用模块时发现没有合适的 安卓的我们可以写 可是没人写ios  最后只有走H5 JS这条路线 因为这个不论是安卓还是ios都可用 当时我就想如果我弄一个模块 以后想用时直接引入文件就行了 不用每次都去写弹窗 那么就模块化 而且这个应该很简单 用不到什么高科技 咱们就用js就能写吧

编写前先想一想 自己需要什么 需要怎么做 首先做什么 然后怎么做 因为我只是个小码农 一个代码的搬运工

第一步: 我需要有个参考 我要做成什么样子 我得有一个静态页面 好的 那就先写个静态的弹窗样式 以下是css 和html 

 html部分

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0" />
		<meta name="format-detection" content="telephone=no">
		<title></title>
	</head>
	<body>
		<div class="alert_box">
			<div class="small_win">
				<div class="alert_box_title">
					<p class="alert_title_text">title</p>
				</div>
				<div class="alert_box_content">
					<ul class="alert_box_content_ul">
						<li>信息1:1</li>
						<li>信息2:2</li>
					</ul>
					<div class="alert_box_input"><input type="text" placeholder="请输入密码" class="alert_input" /></div>
					<div class="alert_box_sure">
						<button class="alert_box_btn">btn1</button>
						<button class="alert_box_btn">btn2</button>
					</div>
				</div>
			</div>
		</div>
	</body>
</html>

    css部分

* {
	padding: 0;
	margin: 0;
	list-style: none;
}

.alert_box {
	width: 100%;
	height: 100%;
	position: fixed;
	top: 0;
	left: 0;
	background: rgba(0, 0, 0, 0.5);
}

.alert_box .small_win {
	background: #fff;
	width: 80%;
	position: absolute;
	top: 50%;
	left: 50%;
	padding-bottom: 15px;
	-webkit-transform: translate(-50%, -50%);
	-ms-transform: translate(-50%, -50%);
	transform: translate(-50%, -50%);
	border-radius: 10px;
	overflow: hidden;
}

.alert_box .small_win .alert_box_title {
	background: #ff0000;
	padding: 10px 0;
	text-align: center;
	font-size: 16px;
}

.alert_box .small_win .alert_box_content {
	width: 90%;
	margin: 0 auto;
	margin-top: 10px;
}

.alert_box .small_win .alert_box_content ul li {
	padding: 5px 0;
}

.alert_box_input input {
	width: 100%;
	border: none;
	font-size: 16px;
	border-bottom: 1px solid #ddd;
	padding: 10px 0;
	outline: none;
}

.alert_box_sure {
	text-align: center;
	margin-top: 15px;
}

.alert_box_sure .alert_box_btn {
	border: none;
	width: 40%;
	padding: 6px;
	margin-right: 5px;
	outline: none;
}

静态页面完成 pc上看着有点丑 在移动端还可以 这个可以根据自己需求调整 

第二步 :看一下都有什么是需要动态写入的然后找对象

    1.顶部提示信息也就是(.alert_title_text)这里面的内容  

    2.需要确认的信息(.alert_box_content_ul)在这里面

    3.如果不用输入内容 我们的input就可以不要了 说以input也是可选的 

    4.按钮的话有时候一个就够了 所以这个也是可选的

    5.开始找对象(比说的多了一点 因为后面要用到 一会再解释)

              //box
		var alertBox = document.getElementsByClassName('alert_box')[0];
		var smallWin = document.getElementsByClassName('small_win')[0];
		//title
		var titleBox = document.getElementsByClassName("alert_box_title")[0];
		var title = titleBox.getElementsByClassName("alert_title_text")[0];
		//content
		var cUl = document.getElementsByClassName("alert_box_content_ul")[0];
		//input
		var putBox = document.getElementsByClassName("alert_box_input")[0];
		var put = putBox.getElementsByClassName("alert_input")[0];
		//btn
		var btnBox = document.getElementsByClassName("alert_box_sure")[0];

第三步:写一个方法把 需要的数据动态写进去 

    因为我们需要一些数据来写入(json格式)

var msg = {
	title: 提示, //这里是title需要显示的信息
	content: [{ // 设置提示内容不传 则不显示 写个数组比较好调用
		text: "提示1"
	}, {
		text: "提示2"
	}, {
		text: "提示3"
	}],
	btn: ["确认", "取消"], //   设置button按钮 最多传两个 一样是数组 方便写入
}

   现在开始写一个方法并且把数据放进去  因为我们有点事件 所以我们这里需要两个参数 一个是配置的信息 一个是回调函数

 

		pushSmgInit(msg)

		function pushSmgInit(msg,fn) {
			//title
			var titleBox = document.getElementsByClassName("alert_box_title")[0];
			var title = titleBox.getElementsByClassName("alert_title_text")[0];
			//content
			var cUl = document.getElementsByClassName("alert_box_content_ul")[0];
			//input
			var putBox = document.getElementsByClassName("alert_box_input")[0];
			var put = putBox.getElementsByClassName("alert_input")[0];
			//btn
			var btnBox = document.getElementsByClassName("alert_box_sure")[0];
			if(msg.title) { //title这里加一些判断 万一要是不传的话 让他有个默认的
				title.innerHTML = msg.title;
			} else {
				title.innerHTML = "标题";
			}
			if(msg.content) { //内容这里也加一些判断  如果不传如何显示
				var liStr = ""
				for(var i in msg.content) {
					liStr += '<li><span class="key">' + msg.content[i].text + '</span></li>'
				}
				cUl.innerHTML = liStr
			}
			if(!msg.isInput) { //这里获取input是否显示  默认是隐藏的
				putBox.style.display = "none"
			}
			put.setAttribute("type", "type") //设置一下input的type值
			if(msg.inputType) { //这里判断一下有没有设置input的type值 type值只能为type和password 如果不传默认为type
				if(msg.inputType != "type") {
					if(msg.inputType != "password") {
						putBox.style.display = "none"
					}
				}
				put.setAttribute("type", msg.inputType)    
			}
			if(msg.inputVal) {   //设置input的placeholder 不传则默认为"请输入点什么"
				put.setAttribute("placeholder", msg.inputVal)
			} else {
				put.setAttribute("placeholder", "请输入点什么")
			}
			if(msg.btn) {   //设置按钮信息 不传则不显示按钮
				var btnStr = ""
				if(msg.btn.length < 1) {     
					btnStr += '<button class="alert_box_btn">确认</button>'
				}
				for(var i in msg.btn) {
					if(i >= 2) {       //这里判断一下如果超过两个参数 则最多显示两个
						return
					}
					btnStr += '<button class="alert_box_btn">' + msg.btn[i] + '</button>'
				}
				btnBox.innerHTML = btnStr
			}
		}

到这里 已经差不多了 但是不怎么好看

第四步  美化一下这个弹窗 让我们可以调用时自己修改一下样式 我们可以用js来设置元素的属性 那么我也可以把想要的样式放在            上面的假数据里面 像动态添加数据一样 用js获取并添加样式 下面是修改后的数据

var msg = {
	title: { //设置顶部提示信息
		bg: '#ff0000', //设置顶部提示信息背景
		context: "确认信息", //设置顶部提示信息内容   不传默认提示 "标题"
		color: "#fff" //设置顶部提示信息的文字颜色
	},
	context: [{ // 设置提示内容不传 则不显示 写个数组比较好调用
		text: "提示1"
	}, {
		text: "提示2"
	}, {
		text: "提示3"
	}],
	isInput: true, // 设置是否显示input框
	inputType: "type", //  设置input框的type值 只能为password或type
	inputVal: "请输入点什么", //设置input的value值
	btn: ["确认", "取消"], //   设置button按钮 最多传两个 
	btnLeft: { // 设置左边按钮样式 若按钮只有一个则取这里面的样式
		bg: "#ddd", //设置设置左边按钮背景
		color: "#000", //设置设置左边按钮文字颜色
		fontSize: 16 //设置设置左边按钮字体大小
	},
	btnRight: { // 设置右边按钮样式 若按钮只有一个则忽略此配置
		bg: "#ff0000", //设置设置右边按钮背景
		color: "#fff", //设置设置右边按钮背景
		fontSize: 16 //设置设置右边按钮字体大小
	}
}

     下面我们就要在我们上面的方法里添加一些东西 获取样式 并添加进去

		function pushSmgInit(msg,fn) { //title
			var titleBox = document.getElementsByClassName("alert_box_title")[0];
			var title = titleBox.getElementsByClassName("alert_title_text")[0];
			//content
			var cUl = document.getElementsByClassName("alert_box_content_ul")[0];
			//input
			var putBox = document.getElementsByClassName("alert_box_input")[0];
			var put = putBox.getElementsByClassName("alert_input")[0];
			//btn
			var btnBox = document.getElementsByClassName("alert_box_sure")[0];
			if(msg.title) { //title这里加一些判断 万一要是不传的话 让他有个默认的
				if(msg.title.context) {
					title.innerHTML = msg.title.context;
				} else {
					title.innerHTML = "标题";
				}
				if(msg.title.bg) {    //设置背景
					titleBox.style.background = msg.title.bg;
				}
				if(msg.title.color) {   //设置颜色
					title.style.color = msg.title.color;
				}
			} else {
				title.innerHTML = "标题";
			}
			if(msg.content) { //内容这里也加一些判断  如果不传如何显示
				var liStr = ""
				for(var i in msg.content) {
					liStr += '<li><span class="key">' + msg.content[i].text + '</span></li>'
				}
				cUl.innerHTML = liStr
			}
			if(!msg.isInput) { //这里获取input是否显示  默认是隐藏的
				putBox.style.display = "none"
			}
			put.setAttribute("type", "type") //设置一下input的type值
			if(msg.inputType) { //这里判断一下有没有设置input的type值 type值只能为type和password 如果不传默认为type
				if(msg.inputType != "type") {
					if(msg.inputType != "password") {
						putBox.style.display = "none"
					}
				}
				put.setAttribute("type", msg.inputType)
			}
			if(msg.inputVal) { //设置input的placeholder 不传则默认为"请输入点什么"
				put.setAttribute("placeholder", msg.inputVal)
			} else {
				put.setAttribute("placeholder", "请输入点什么")
			}
			if(msg.btn) { //设置按钮信息 不传则不显示按钮
				var btnStr = ""
				if(msg.btn.length < 1) {
					btnStr += '<button class="alert_box_btn">确认</button>'
				}
				for(var i in msg.btn) {
					if(i >= 2) { //这里判断一下如果超过两个参数 则最多显示两个
						return
					}
					btnStr += '<button class="alert_box_btn">' + msg.btn[i] + '</button>'
				}
				btnBox.innerHTML = btnStr
			}
			var alertBtn = document.getElementsByClassName("alert_box_btn")  //找到所有的btn
			if(msg.btn.length >= 1 && msg.btnLeft) {  //判断有几个按钮 应该获取哪个配置 不多解释
				var btnL = alertBtn[0]
				btnL.setAttribute("style", "background:" + msg.btnLeft.bg + ";color:" + msg.btnLeft.color + ";font-size:" + msg.btnLeft.fontSize + "px")
			}
			if(msg.btn.length >= 2 && msg.btnRight) {
				var btnR = alertBtn[1];
				btnR.setAttribute("style", "background:" + msg.btnRight.bg + ";color:" + msg.btnRight.color + ";font-size:" + msg.btnRight.fontSize + "px")
			}
		}  

        好了现在应该能看到效果了 当然我们还可配置更多属性比如 弹窗的圆角 内容的行高等等 因为就是个思路 就不写这么多了

第五步  下面我们就该点击按钮了 

  

 for(var a = 0; a < alertBtn.length; a++) { //这里就是点击按钮 我们要判断点击的是哪个按钮
				alertBtn[a].index = a
				alertBtn[a].onclick = function() {
					var data = {}
					if(putBox.style.display === 'none') { //这里判断一下 是否存在输入框 如果不存在我们就把所点击按钮的下标传递出去
						fn && fn({
							eventType: this.index
						})
						return
					}
					fn && fn({ //输入框如果存在 就弹出输入框的的内容 和当前按钮的下标
						eventType: this.index,
						msg: put.value
					})
				}
			}

第六步  这是一个弹窗 所以就需要关闭 关闭方式有很多 这里就写两个 第一关闭周围的遮罩层 第二 点击按钮 

    我们先说点遮罩层 这个可选项 我们可以在上面json数据里面配置一下  把下面这个放到配置文件里面就好了

tapClose: true // (可选项)是否点击遮罩层关闭该对话框  默认为false

    关闭的话 我们来写个方法

function closeAlert(el) {   //这里传递一个参数 方便扩展
		if(el) {
			al = el
		} else {
			al = newNode
		}
		alertBox.style.display=“none”
	}

下面就是点击遮罩层关闭弹窗了  这里要注意事件冒泡 

if(info.tapClose) {   //读取配置文件 判断点击遮罩层是否关闭 
			alertBox.onclick = function() {
				closeAlert()
			}
		}
smallWin.onclick = function(event) {  //阻止事件冒泡
			cancelBubble(event)
		}
//阻止事件冒泡的方法
	function cancelBubble(e) {
		var evt = e ? e : window.event;
		if(evt.stopPropagation) {
			//W3C 
			evt.stopPropagation();
		} else {
			//IE 
			evt.cancelBubble = true;
		}
	}

 点击按钮关闭弹窗就是调用这个模块时的事了 只要调用closeAlert(el) 这方法就好了  

做到这里基本上就成型了 因为是做个模块 所以就不希望我们再去写html 我们直接用js动态添加html到页面里面 这样就不用在调用时在写很多html标签了

var newNode = document.createElement("div");  //这里设置一个全局变量 因为要用到

	function addlast() {    
		newNode.innerHTML = '<div class="alert_box"><div class="small_win"><div class="alert_box_title"><p class="alert_title_text"></p></div><div class="alert_box_content"><ul class="alert_box_content_ul"></ul><div class="alert_box_input"><input type="text" placeholder="请输入密码" class="alert_input" /></div><div class="alert_box_sure"></div></div></div></div>'
		document.body.appendChild(newNode)   //上面是动态创建的文件 这里添加进去 pushSmgInit()这个方法里面调用就行
	}

当我在使用时发现有问题 当关闭再打开时里面的数据不对了 后来发现我们关闭时 只是让他隐藏了 上次的属性还在 第二次添加就不好使了 所以我们要改一下关闭的方法 我们直接移除他

function closeAlert (el) {
		if(el) {
			al = el
		} else {
			al = newNode
		}
		document.body.removeChild(newNode)
	}

ok 现在就可以了  我们来把它封装一下  当然我改了一些命名 把下面这些代码粘贴复制一下就可以用  也可以和上面对照一下 自己去修改 开始已经说明了 我说的是一个思路  以下就是完整代码了

  js部分(封装后的)创建一个名为alertBox.js的文件

(function(window) {
	var u = {}

	u.alertBox = function(info, fn) {
		u.addlast()
		//box
		var alertBox = document.getElementsByClassName('alert_box')[0];
		var smallWin = document.getElementsByClassName('small_win')[0];
		//title
		var titleBox = document.getElementsByClassName("alert_box_title")[0];
		var title = titleBox.getElementsByClassName("alert_title_text")[0];
		//content
		var cUl = document.getElementsByClassName("alert_box_content_ul")[0];
		//input
		var putBox = document.getElementsByClassName("alert_box_input")[0];
		var put = putBox.getElementsByClassName("alert_input")[0];
		//btn
		var btnBox = document.getElementsByClassName("alert_box_sure")[0];
		if(info.title) {
			titleBox.style.background = info.title.bg;
			title.innerHTML = info.title.context;
			title.style.color = info.title.color;
		} else {
			title.innerHTML = "标题";
		}

		if(info.context) {
			var liStr = ""
			for(var i in info.context) {
				liStr += '<li><span class="key">' + info.context[i].text + '</span></li>'
			}
			cUl.innerHTML = liStr
		}

		if(!info.isInput) {
			putBox.style.display = "none"
		}

		put.setAttribute("type", "type")
		if(info.inputType) {
			if(info.inputType != "type") {
				if(info.inputType != "password") {
					putBox.style.display = "none"
				}
			}
			put.setAttribute("type", info.inputType)
		}
		if(info.btn) {
			var btnStr = ""
			if(info.btn.length < 1) {
				btnStr += '<button class="alert_box_btn">确认</button>'
			}
			for(var i in info.btn) {
				if(i >= 2) {
					return
				}
				btnStr += '<button class="alert_box_btn">' + info.btn[i] + '</button>'
			}
			btnBox.innerHTML = btnStr
		}
		var alertBtn = document.getElementsByClassName("alert_box_btn")
		if(info.btn.length >= 1 && info.btnLeft) {
			var btnL = alertBtn[0]
			btnL.setAttribute("style", "background:" + info.btnLeft.bg + ";color:" + info.btnLeft.color + ";font-size:" + info.btnLeft.fontSize + "px")
		}
		if(info.btn.length >= 2 && info.btnRight) {
			var btnR = alertBtn[1];
			btnR.setAttribute("style", "background:" + info.btnRight.bg + ";color:" + info.btnRight.color + ";font-size:" + info.btnRight.fontSize + "px")
		}
		for(var a = 0; a < alertBtn.length; a++) {
			alertBtn[a].index = a
			alertBtn[a].onclick = function() {
				var data = {}
				if(putBox.style.display === 'none') {
					fn && fn({
						eventType: this.index
					})
					return
				}
				fn && fn({
					eventType: this.index,
					msg: put.value
				})
			}
		}

		if(info.tapClose) {
			alertBox.onclick = function() {
				u.closeAlert(this)
			}
		}

		smallWin.onclick = function(event) {
			cancelBubble(event)
		}
	}
	//关闭弹窗
	u.closeAlert = function(el) {
		if(el) {
			al = el
		} else {
			al = newNode
		}
		document.body.removeChild(newNode)
	}

	//阻止事件冒泡
	function cancelBubble(e) {
		var evt = e ? e : window.event;
		if(evt.stopPropagation) {
			//W3C 
			evt.stopPropagation();
		} else {
			//IE 
			evt.cancelBubble = true;
		}
	}

	var newNode = document.createElement("div");
	u.addlast = function() {
		newNode.innerHTML = '<div class="alert_box"><div class="small_win"><div class="alert_box_title"><p class="alert_title_text"></p></div><div class="alert_box_content"><ul class="alert_box_content_ul"></ul><div class="alert_box_input"><input type="text" placeholder="请输入密码" class="alert_input" /></div><div class="alert_box_sure"></div></div></div></div>'
		document.body.appendChild(newNode)
	}

	window.$alert = u;
})(window);
css文件(和上面的没有什么变化)创建一个名为alertBox.css的文件

  

* {
	padding: 0;
	margin: 0;
	list-style: none;
}

.alert_box {
	width: 100%;
	height: 100%;
	position: fixed;
	top: 0;
	left: 0;
	background: rgba(0, 0, 0, 0.5);
}

.alert_box .small_win {
	background: #fff;
	width: 80%;
	position: absolute;
	top: 50%;
	left: 50%;
	padding-bottom: 15px;
	-webkit-transform: translate(-50%, -50%);
	-ms-transform: translate(-50%, -50%);
	transform: translate(-50%, -50%);
	border-radius: 10px;
	overflow: hidden;
}

.alert_box .small_win .alert_box_title {
	background: #fff;
	padding: 10px 0;
	text-align: center;
	font-size: 16px;
}

.alert_box .small_win .alert_box_content {
	width: 90%;
	margin: 0 auto;
	margin-top: 10px;
}

.alert_box .small_win .alert_box_content ul li {
	padding: 5px 0;
}

.alert_box_input input {
	width: 100%;
	border: none;
	font-size: 16px;
	border-bottom: 1px solid #ddd;
	padding: 10px 0;
	outline: none;
}

.alert_box_sure {
	text-align: center;
	margin-top: 15px;
}

.alert_box_sure .alert_box_btn {
	border: none;
	width: 40%;
	padding: 6px;
	margin-right: 5px;
	outline: none;
}

html文件

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0" />
		<meta name="format-detection" content="telephone=no">
		<title></title>
		<link rel="stylesheet" type="text/css" href="alertBox.css" /><!--css写在这里面-->
		<style type="text/css">
			.click{
				width: 80px;
				height: 50px;
				margin: 40px auto;
				background: red;
				line-height: 50px;
				text-align: center;
			}
		</style>
	</head>

	<body>
		<div class="click">点击我</div>
	</body>
	<script type="text/javascript" src="alertBox.js"></script><!--封装好的js写在这里面-->
	<script type="text/javascript">
		document.getElementsByClassName("click")[0].onclick = function() {
			//代码调用示范
			$alert.alertBox({ //调用方法
				title: { //设置顶部提示信息
					bg: '#ff0000', //设置顶部提示信息背景
					context: "确认信息", //设置顶部提示信息内容   不传默认提示 "标题"
					color: "#fff" //设置顶部提示信息的文字颜色
				},
				context: [{ // 设置提示内容不传 则不显示
					text: "提示的内容1:"
				}, {
					text: '提示的内容2'
				}, {
					text: '提示的内容3'
				}],
				isInput: true, // 设置是否显示input框
				inputType: "type", //  设置input框的type值 只能为password或type
				btn: ["确认", "取消"], //   设置button按钮 最多传两个 
				btnLeft: { // 设置左边按钮样式 若按钮只有一个则取这里面的样式
					bg: "#ddd", //设置设置左边按钮背景
					color: "#000", //设置设置左边按钮文字颜色
					fontSize: 16 //设置设置左边按钮字体大小
				},
				btnRight: { // 设置右边按钮样式 若按钮只有一个则忽略此配置
					bg: "#ff0000", //设置设置右边按钮背景
					color: "#fff", //设置设置右边按钮背景
					fontSize: 16 //设置设置右边按钮字体大小
				},
				tapClose: true // (可选项)是否点击遮罩层关闭该对话框  默认为false
			}, function(ret) {
				console.log(ret) //回调函数 如果isInput为false 则返回{eventType: 1}   如果isInput为true 则返回{eventType: 1, msg: ""}
				if(ret.eventType == 1) {
					$alert.closeAlert()
				}
			})
		}
	</script>

</html>

说明下 这个我是用在移动端的 所以在pc上有点丑 不过用的时候可以自己调节以下 希望对大家有所帮助


     


  

上一篇:

下一篇: