@TOC
预览效果
单例模式
定义:
单体模式,规定一个类只有一个实例,并且提供可全局访问点
实例:
全局缓存、弹窗
缺点:
频繁的创建和销毁
资源浪费
优化:
标记:创建变量标记(使用闭包)
实现:
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对象中