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

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

预览效果

链接:http://yongma16.xyz/static/Csslearn/css_study/day36/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E4%B9%8B%E6%97%A0%E9%99%90%E5%BC%B9%E7%AA%97.html

单例模式

定义:

单体模式,规定一个类只有一个实例,并且提供可全局访问点

实例:

全局缓存、弹窗

缺点:

频繁的创建和销毁

资源浪费

优化:

标记:创建变量标记(使用闭包

实现:

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对象中

仓库代码

链接:https://codechina.csdn.net/qq_38870145/css_study


目录
相关文章
|
1月前
|
机器学习/深度学习 JavaScript 前端开发
JavaScript 弹窗
JavaScript 弹窗
40 1
|
8天前
|
设计模式 JavaScript 前端开发
一文理解JavaScript中的单例模式
js 单例模式是一种常用的设计模式,它可以保证一个类只有一个实例。这种模式主要用于管理全局变量,避免命名冲突和重复加载,同时也可以减少内存占用,提高代码的可维护性和可扩展性。
19 1
|
1月前
|
JavaScript
js学习--开屏弹窗
js学习--开屏弹窗
35 1
|
3月前
|
前端开发 JavaScript 开发者
前端JS按钮点击事件、跳出弹窗、遮罩的实战示例
本文提供了一个前端JS按钮点击事件、弹出式窗口和遮罩层的实战示例,包括HTML、CSS和JavaScript的具体实现代码,以及功能解析,演示了如何实现按钮点击后触发弹窗显示和遮罩层,并在2秒后自动关闭或点击遮罩层关闭弹窗的效果。
前端JS按钮点击事件、跳出弹窗、遮罩的实战示例
|
3月前
|
设计模式 存储 JavaScript
JS:单例模式 —— 百度考题 (二)
JS:单例模式 —— 百度考题 (二)
|
3月前
|
设计模式 JavaScript 前端开发
JS:单例模式 —— 百度考题 (一)
JS:单例模式 —— 百度考题 (一)
|
3月前
|
存储 JavaScript
js如何实现开屏弹窗
js如何实现开屏弹窗
17 0
|
4月前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 单例模式
js设计模式【详解】—— 单例模式
28 1
|
5月前
|
JavaScript 前端开发
JavaScript弹窗事件
JavaScript弹窗事件
49 0
|
6月前
|
JavaScript 前端开发
js和css以及js制作弹窗
js和css以及js制作弹窗
49 1