美文网首页
弹窗封装(二)/闭包,this指向

弹窗封装(二)/闭包,this指向

作者: Raral | 来源:发表于2021-03-04 18:02 被阅读0次

封装

  1. 原生js封装弹窗效果
    主要目的呈现思路,动态创建样式,下面一些其它参数还没有处理;
    通过实现过程可以更深刻理解闭包,this指向,oop,业务拆分,
(function(window){
    function Popup(options) {
        // 把用户的参数和默认的参数合并
        var opts = Object.assign({},Popup.defaultOptions, options);
        this.opts = opts;
        this.w = window.innerWidth;
        this.h = window.innerHeight;
        this.mask = null;
        this.view = null;
        this.first = null;
        this.init();
    }
    Popup.prototype = {
        contructor: Popup,
        init: function() {
            this.initDom();
            // this.renderView();
            this.mask = document.body.querySelector(".mask");
            this.view = document.body.querySelector(".view");
            this.bindEvent(this.mask,"click", this.close)
            this.initCss(this.mask);
            this.initCss(this.view);
            this.first = true;
            
        },
        //创建弹出层的dom结构
        initDom() {
            var strHtml = `
                <div class="popup">
                    <div class="mask"></div>
                    <div class="view">
                       
                    </div>
                </div>
            `
             var popupDom = new DOMParser().parseFromString(strHtml,'text/html').body.childNodes[0];
             document.body.appendChild(popupDom);
        },
        //删除节点
        destoryDom() {
            var popupNode = document.body.querySelectorAll(".popup");
            if(popupNode.length <= 0) return;
            Array.prototype.forEach.call(popupNode, (node) => {
                document.body.removeChild(node);
            })
        },
        //初始化节点样式
        initCss(node) {
            if(node.className == "mask") {
                node.style.cssText = `
                    width: 100%;
                    height: 100vh;
                    background-color: black;
                    position: absolute;
                    top: 0;
                    left: 0;
                    right: 0;
                    bottom: 0;
                    z-index: 1;
                    opacity: 0;
                    visibility: hidden;
                    transition: all 2s linear;
                `
            }else if(node.className == "view") {
                node.style.cssText = `
                    background-color: #fff;
                    position: absolute;
                    z-index: 1000;
                    display: block;
                    transition: all 2s linear;
                `
                node.style.cssText += this.initViewPosition();
            }
        },
        open: function() {
            if(this.first) {
                this.changeStatus()
            }else {
                this.init();
                setTimeout(() => {
                   this.changeStatus()
                })
            }
        },
        close: function() {
            var mask = document.body.querySelector(".mask");
            var view = document.body.querySelector(".view");
            this.mask.style.opacity = 0;
            this.mask.style.visibility = "hidden";
            this.viewInitEnd("init");
            this.first = false;
            setTimeout(() => {
                this.destoryDom();
            }, 2000);// 这个时间和你过渡动画时间一致
        },
        //这里可以用es6语法优化,但是为了理解this指向问题,用es5语法改变this
        bindEvent: function(node,event,cb) {
            // 要达到效果:回调函数中的this指向,永远指向实例
            node.addEventListener(event, function() {
                cb && cb.call(this);
            }.bind(this), false)
        },
         //控制显示层dom结构
         renderView: function() {
            this.view.append(this.opts.viewDom);
        },
        //控制显示层的方向
        initViewPosition: function() {
            console.log(this)
            switch (this.opts.position) {
                case "bottom":
                    return  `
                        width: ${this.w}px;
                        height: 0;
                        left: 0;
                        bottom: 0;
                    `
                    break;
                case "top":
                    return  `
                        width: ${this.w}px;
                        height: 0;
                        left: 0;
                        top: 0;
                    `
                    break;
                case "left":
                    return  `
                        width: 0;
                        height: ${this.h}px;
                        left: 0;
                        top: 0;
                    `
                    break;
                 case "right":
                    return  `
                        width: 0;
                        height: ${this.h}px;
                        right: 0;
                        top: 0;  
                    `
                    break
            }
        },
        //显示层的初始状态和关闭状态
        viewInitEnd: function(type) {
            if(type == "end") {
                if(this.opts.position == ("top" || "bottom")) {
                    this.view.style.height = "200px"
                }else {
                    this.view.style.width = "100px"
                }
            }else if(type == "init") {
                if(this.opts.position == ("top" || "bottom")) {
                    this.view.style.height = 0
                }else {
                    this.view.style.width = 0
                }
            }
        },
        //控制显示层动画时间
        initViewTime: function() {
            // 。。。
        },
        //改变后的样式状态
        changeStatus() {
            this.mask.style.opacity = .6;
            this.mask.style.visibility = "visible";
            this.viewInitEnd("end");
        }
    }
    // 默认参数就是说明该插件具备的功能有哪些
    Popup.defaultOptions = {
        viewDom:null,
        position:"bottom",//显示层的从那个方向出来,可选值为 top bottom right left
        overlay_class:"",//自定义遮罩层类名
        duration:300,//动画时长,单位毫秒
        round:false,//是否显示圆角
        lock_scroll: true,//是否锁定背景滚动
        lazy_render: true,//是否在显示弹层时才渲染节点
        close_on_click_overlay:true,//是否在点击遮罩层后关闭
        closeable:false,//是否显示关闭图标
        close_icon:"",//关闭图标名称或图片链接
        close_icon_position:"top-right",//关闭图标位置,可选值为top-leftbottom-left bottom-right
        get_container: "body",//弹窗挂在位置
        
    }

    return window.Popup = Popup
    
})(window)
  1. jquery 封装
    下次更新

相关文章

  • 弹窗封装(二)/闭包,this指向

    封装 原生js封装弹窗效果主要目的呈现思路,动态创建样式,下面一些其它参数还没有处理;通过实现过程可以更深刻理解闭...

  • iOS开发 毛玻璃背景弹窗 SXAlertView

    简单封装了毛玻璃背景弹窗视图,并用闭包判断点击事件 SXAlertView.swift 使用例子:ViewCont...

  • 学习JS笔记(第七章-闭包,作用域)

    闭包的概念## 闭包实例## 数据传递更加灵活### 常见错误之循环闭包### 封装变量### 闭包小结## 作用...

  • 闭包

    一、 闭包是什么 函数 和 函数内部能访问到的变量(也叫环境)的总和,就是一个闭包。 二、闭包的作用 封装数据 暂...

  • PHP闭包实现

    闭包是指在创建时封装周围状态的函数。即使闭包所在的环境不在了,闭包中封装的状态依旧存在。注意在php中匿名函数=闭...

  • PHP 闭包

    闭包和匿名函数在php5.3中引入,闭包是指的创建时封装周围状态的函数,即便闭包所在的环境不存在了,闭包中封装的状...

  • 闭包与this指向

    1. 闭包 1.1 闭包的形成条件: 1.2 作用:变相的外面使用里面的变量 1.3 闭包的优点也是缺点:...

  • 闭包和匿名函数

    概念 闭包是指在创建时封装周围状态的函数.即便闭包所在的环境不存在了,闭包中封装的状态依然存在. 匿名函数其实就是...

  • JavaScript - 闭包

    理解 关于闭包 答案: 用arguments.callee和闭包实现的函数封装 应用 利用闭包实现自动递增计数

  • PHP闭包函数

    1.概念 闭包是指在创建时封装周围状态的函数。即使闭包所在的环境不存在了,闭包中封装的状态依然存在。匿名函数就是没...

网友评论

      本文标题:弹窗封装(二)/闭包,this指向

      本文链接:https://www.haomeiwen.com/subject/dwbkqltx.html