js_单例模式制作无限弹窗(3s内销毁)

87 阅读2分钟

单例模式制作无限弹窗

预览效果

链接:yongma16.xyz/static/Cssl…

在这里插入图片描述

在这里插入图片描述

单例模式

定义:
单体模式,规定一个类只有一个实例,并且提供可全局访问点
实例:
全局缓存、弹窗
缺点:
频繁的创建和销毁
资源浪费
优化:
标记:创建变量标记(使用闭包)
实现:
call() 方法分别接受参数。
apply() 方法接受数组形式的参数。
实现:
绑定到window全局

// 单例模式
function getSingle(fn) {
	var result;
	return function() {
		return result || (result = fn.apply(this, arguments))
	}
}

无限弹窗与销毁

思路:
创建弹窗div函数,传入定义的全局函数(单例模式实现),将创建的dom加入body实现弹窗的弹出(dispaly的属性控制none->block)
销毁:
将创建的dom加入数组,从前往后销毁,应用数组的splice对数组进行切割

创建弹窗函数

将style拆分出来,便以后期修改,最后返回div窗口

var createLayer = function() {
	// 随机位置
	var div = document.createElement('div')
	var left = "50%",
		top = "50%";
	if (countFlag != 0) {
		left = Math.round(Math.random() * 100) + "%";
		top = Math.round(Math.random() * 100) + "%";
	}
	let page = {
		position: "absolute",
		display: 'none',
		background: "url(pop.jpeg)",
		width: "400px",
		height: "400px",
		boxSizing: "border-box",
		left: left,
		top: top,
		margingTop: "20px",
		margingBottom: "20px",
		border: "1px solid red"
	}
	for (let key in page) {
		div.style[key] = page[key]
	}
	// 关闭按钮
	let pageCloseBtn = document.createElement('button')
	let pageClose = {
		position: "relative",
		float: "right",
		margin: "2px",
		padding: "2px",
		background: "bisque",
		border: "1px",
		color: "dark",
		cursor: "pointer"
	}
	for (let key in pageClose) {
		pageCloseBtn.style[key] = pageClose[key]
	}
	pageCloseBtn.innerText = '关闭'
	// 问题
	let pageQuestionDom = document.createElement('p')
	let pageQuestion = {
		position: "relative",
		left: "3%",
		top: "50%",
		fontSize: "2em",
		fontWeight: "bolder",
		color: "rgb(80,87,133)",
		transform: "translateY(-50%)",
		textAlign: "center"
	}
	for (let key in pageQuestion) {
		pageQuestionDom.style[key] = pageQuestion[key]
	}
	// 回答div
	pageQuestionDom.innerText = "闭包单例模式是否明白"
	let answerDiv = document.createElement('div')
	let btnYes = document.createElement('button')
	btnYes.style.margin = '10px'
	btnYes.innerText = '是'
	let btnNo = document.createElement('button')
	btnNo.innerText = '否'
	btnNo.style.margin = '10px'
	let pageAnswer = {
		position: "relative",
		top: "40%",
		transform: "translateY(-50%)",
		textAlign: "center"
	}
	for (let key in pageAnswer) {
		answerDiv.style[key] = pageAnswer[key]
	}
	// 添加绑定事件
	btnYes.addEventListener('click', initPage)
	btnNo.addEventListener('click', initPage)
	pageCloseBtn.addEventListener('click', initPage)
	answerDiv.appendChild(btnYes) //是
	answerDiv.appendChild(btnNo) //否
	div.appendChild(pageCloseBtn) //关闭的按钮
	div.appendChild(pageQuestionDom) //问题
	div.appendChild(answerDiv) //窗口
	return div
}

初始化与销毁实现

// 初始化完成
window.onload = initPage
// object添加监听事件

var count = {
	value: 0
}
Object.defineProperty(count, 'value', {
	value: {
		configurable: true,
		get: function() {
			return data
		},
		set: function(newValue) {
			data = newValue; //更新
			// 触发删除函数
			console.log('触发删除函数')
			deletePagePop();
		}
	}
})
var countFlag = 0
// 单链表存储dom
var createDomList = []

function initPage() {
	count.value = 1; //初始化
	if (countFlag > 0) {
		console.log('开始销毁')

		function deletPageDom() {
			return new Promise(resolve => {
				setTimeout(function() {
					let headPage = createDomList[0]
					console.log('移出的dom', headPage)
					document.body.removeChild(headPage)
					createDomList = createDomList.splice(1, createDomList.length - 1)
						--count.value
				}, 3000)
				resolve('delete')
			})
		}
		async function doDelete() {
			await deletPageDom()
		}
		doDelete();
	}
	console.log('create page')
	var getSingleLogin = getSingle(createLayer)
	let CreateLoginDom = getSingleLogin()
	console.log(CreateLoginDom)
	CreateLoginDom.style.display = 'block'
	// 先进先出
	document.body.appendChild(CreateLoginDom) //加入渲染dom
	count.value = count.value + 1
		++countFlag
	console.log('count.value=', count.value)
	createDomList.push(CreateLoginDom)

}

function deletePagePop() {
	// 删除第一个出现的

}

getSingle函数已经注册到全局window对象中
在这里插入图片描述

仓库代码

链接:codechina.csdn.net/qq_38870145…
在这里插入图片描述