如何使用JavaScript构建模态框插件

栏目: JavaScript · 发布时间: 5年前

内容简介:作为一位Web开发人员而言,模态框(模态框在前端组件中是一个非常常见的组件。其位于Web应用程序主窗口之上的一个元素。他创建了一个新的模式,该模式禁止用户操作应用程序的主窗口,但它以弹窗的模式在应用程序主窗口之上显示。用户可以在返回应用程序主窗口之前与弹框进行交互操作。模态框的设计,如果设计或执行不好将会影响主链路的操作,防碍任务的完成。为了确保不影响主链路的操作,一个模态框至少应该包括下面内容:

作为一位Web开发人员而言,模态框( Modal )并不会陌生。就我个人而言,我更为熟悉的是怎么通过CSS来编写一个模态框以及怎么通过CSS给模态框添加一些动效。正好最近工作中也和Modal框杠上了。另外想更好的设计一个模态框用来满足业务需求的普遍性和实用性,甚至是达到可配置性。所以一直在探究模态框相关的知识,同时正好看到了 @Ken Wheeler的教程 ,对于我这样的菜鸟,能很好的了角如何使用原生的JavaScript来构建一个可用的模态框插件,另外为以后如何使用Vue构建更为灵活的模态框组件打下坚实的基础。如果你对该文章感兴趣,或者你也正在加强JavaScript的学习和实战,欢迎继续往下阅读,或许对你有所帮助。

模态框是什么

模态框在前端组件中是一个非常常见的组件。其位于Web应用程序主窗口之上的一个元素。他创建了一个新的模式,该模式禁止用户操作应用程序的主窗口,但它以弹窗的模式在应用程序主窗口之上显示。用户可以在返回应用程序主窗口之前与弹框进行交互操作。

模态框的设计,如果设计或执行不好将会影响主链路的操作,防碍任务的完成。为了确保不影响主链路的操作,一个模态框至少应该包括下面内容:

如何使用JavaScript构建模态框插件

一个优秀的Modal框主要包含的部分有:

modal-overlay
modal-header
modal-body
modal-footer
modal-close

刚才也提到过,模态框毕竟是在应用程序主窗口上显示,所以需要给用户提供关闭模态框的途径。常见的方式有:

ECS

因此,我们要设计一个模态框,也需要考虑这些因素。

构建模态框插件

接下来,我们来看看怎么使用原生的JavaScript来构建一个模态框插件。通过这个学习你将掌握或需要掌握以下几个知识点:

  • CSS的 transitionanimation 相关知识点
  • JavaScript DOM操作相关知识点
  • JavaScript 构造器和构造函数
  • JavaScript 事件监听
  • JavaScript 函数

如果你是一个初学者,还是值得花一点时间阅读该文,如果你是位JS大神,欢迎您拍正文章中的不足。

选择设计模式

首先要确定设计模态弹出框的结构并选择一个设计模式。我们的目的是要创建一个模态弹出框,并且可以真正的运用于我们的项目中。这里将会用到 闭包相关的知识 ,因为闭包可以用来创建一个私有域,可以在其中控制提供哪些数据:

// 创建一个立即调用的函数表达式来包装我们的代码
(function() {
    var privateVar = "在控制台中console.log找不到我"
}());

我们想为插件添加一个构造函数方法,并将其公开。 IIFE 是全局的,因此 this 的关键词指向的是 window 。让我们使用 this 将构造函数附加到全局作用域:

// 创建一个立即调用的函数表达式来包装我们的代码
(function(){
    // 定义构造器
    this.Modal = function () {

    }
}())

我们将 Modal 变量指向一个函数,从而创建一个函数对象,现在我们可以用 new 关键词实例化它,如下所示:

var myModal = new Modal()

console.log(myModal) // => Object {}

上面的代码创建了一个对象的新实例。不幸的是,我们的对象在这一点上并没有做什么,所以接下来给这个对象加点其他的东西。

有关于闭包更多的知识点可以阅读下面相关文章:

选项(Options)

回顾一下我们的需求,我们首要的任务是允许用户自定义选项( options )。实现这一点的方法就是创建一组默认的选项,然后将其与用户提供的对象合并。

(function(){
    // 定义构造函数
    this.Modal = function () {
        // 创建引用的全局元素
        this.closeButton = null; // 关闭按钮
        this.modal = null; // 模态弹出框
        this.overlay = null; //模态弹出框蒙层

        // 自定义默认选项
        var defaults = {
            className: 'fade-and-drop',
            closeButton: true,
            content: '',
            maxWidth: 600,
            minWidth: 280,
            overlay: true
        }

        // 通过扩展arguments中传递的缺省值来创建选项
        if (arguments[0] && typeof arguments[0] === 'object') {
            this.options = extendDefaults(defaults, arguments[0])
        }
    }

    // 使用用户选扩展默认值的方法
    function extendDefaults(source, properties) {
        var property;
        for (property in properties) {
            if (properties.hasOwnProperty(property)) {
                source[property] = properties[property]
            }
        }
        return source
    }
}())

首先,创建了被引用的全局元素。这些都很重要,这样一来就可以在插件的任何地方引用 Modal 。接下来,我们添加了一个默认( defaults )选项对象。如果用户不提供选项( options ),就会使用默认选项;如果用户提供了就会覆盖默认选项。那么我们怎么知道用户有没有提供选项呢?这里的关键是 arguments 对象。这是每个函数内部的一个神奇对象,它包含通过参数传递给它的所有东西的数组。因为我们只期望一个参数,一个包含插件设置的对象,所以我们检查以确保 arguments[0] ,并且它确实是一个对象。

如果条件达得到,就会使用 extendDefaults 私有域的方法合并这两个对象。 extendDefaults 接受一个对象,将会遍历它的属性( properties ),如果不是其内部属性( hasOwnProperty ),就将它分配给源对象( source )。我们现在可以配置我们插件和选项对象。

var myModal = new Modal({
    content: 'Howdy',
    maxWidth: 600
})

这个时候在控制台中打印出 myModal ,其结果如下图所示:

如何使用JavaScript构建模态框插件

为了提供一个公共主法,可以将它附加到 Modal 对象的原型上( prototype )。当你向对象的原型中添加方法时,每个新实例共享相同的方法,而不是为每个实例创建新方法。这在性能上也具有较大的优势,除非有多级子类化,不然在这种子类化中,遍历原型链会抵消性能提升。我们还添加了注释,并对组件进行了结构化。这样我们就有三个部分: 构造函数公共方法私有方法

// 创建一个立即调用的函数表达式来包装我们的代码
(function(){
    // 定义构造函数
    this.Modal = function () {
        // 创建引用的全局元素
        this.closeButton = null; // 关闭按钮
        this.modal = null; // 模态弹出框
        this.overlay = null; //模态弹出框蒙层

        // 自定义默认选项
        var defaults = {
            className: 'fade-and-drop',
            closeButton: true,
            content: '',
            maxWidth: 600,
            minWidth: 280,
            overlay: true
        }

        // 通过扩展arguments中传递的缺省值来创建选项
        if (arguments[0] && typeof arguments[0] === 'object') {
            this.options = extendDefaults(defaults, arguments[0])
        }

        // 公用方法
        Modal.prototype.open = function() {
            // open方法的对应的代码
        }

        // 私有方法

    }

    // 使用用户选扩展默认值的方法
    function extendDefaults(source, properties) {
        var property;
        for (property in properties) {
            if (properties.hasOwnProperty(property)) {
                source[property] = properties[property]
            }
        }
        return source
    }
}());

var myModal = new Modal({
    content: 'Howdy',
    maxWidth: 600
})

console.log(myModal)

它不做任何功能性的工作,但是它保持了所有内容的组织性和可读性。

有关于函数中的 arguments 更多的介绍可以阅读下面相关文章:

有关于构造函数相关的知识可以阅读下面相关文章:

核心功能

现在我们对模态框的插件架构有了一定的了解,它包括了: 构造函数选项公共方法 。但它还不能做什么?接下来我们就要给他们添加相应的核心功能。所以我们再来看看,一个模态框应该做什么:

  • 构建一个模态元素并将其添加到页面中
  • 将选项( options )中的 className 指定一个类名,并将其添加到模态元素中
  • 如果选项中的 closeButtontrue ,则添加关闭按钮
  • 如果选项中的 content 是 HTML 字符串,则将其设置为模态元素中的内容
  • 如果选项中的 contentdomNode ,则将其内部内容设置为模态元素的内容
  • 分别设置模态的 maxWidthminWidth
  • 如果选项中的 overlaytrue ,则给模态框添加一个蒙层
  • 当模态框显示时,添加一个 scotch-open 类名,可以在 CSS 中使用它来定义一个 open 状态
  • 当模态框关闭时,删除 scotch-open 类名
  • 如果模态框的高度超过视窗的高度,还可以添加一个 scotch-anchored 类,这样就可以处理这个场景的样式展示

构建自己的模态框

接下来,我们创建一个私人的方法,使用我们自己定义的选项来构建一个模态框:

function buildOut() {
    var content, contentHolder, docFrag;

    // 如果内容是HTML是字符串,则追加HTML字符串;如果内容是domNode,则追加其内容

    if (typeof this.options.content === 'string') {
        content = this.options.content
    } else {
        content = this.options.content.innerHTML
    }

    // 创建一个DocumentFragment
    docFrag = document.createDocumentFragment()

    // 创建modal元素
    this.modal = document.createElement('div')
    this.modal.className = 'modal' + this.options.className
    this.modal.style.minWidth = this.options.minWidth + 'px'
    this.modal.style.maxWidth = this.options.maxWidth + 'px'

    // 如果closeButton的值为true,添加close按钮
    if (this.options.closeButton === true) {
        this.closeButton = document.createElement('button')
        this.closeButton.className = 'modal-close close-button'
        this.closeButton.innerHTML = 'x'
        this.modal.appendChild(this.closeButton)
    }

    // 如果overlay的值为true,添加蒙层
    if (this.options.overlay === true) {
        this.overlay = document.createElement('div')
        this.overlay.className = 'modal-overlay' + this.options.className
        docFrag.appendChild(this.overlay)
    }

    // 创建内容区域,并添加到modal中
    contentHolder = document.createElement('div')
    contentHolder.className = 'modal-content'
    contentHolder.innerHTML = content
    this.modal.appendChild(contentHolder)

    // 把modal插到DocumentFragment中
    docFrag.appendChild(this.modal)

    // 把DocumentFragment插到body中
    document.body.appendChild(docFrag)
}

首先获取目标内容并创建一个 DcoumentFragment (文档片段)。文档片段用于构造DOM外部的DOM元素集合,并用于累计地向DOM添加我们构建的内容。如果 content 是字符串,则将内容变量设置为 options 值;如果我们的 contentdomNode ,我们通过 innerHTML 将内容变量设置为它的内部HTML。

接下来,我们创建 modal 元素,并向其添加 classNameminWidthmaxWidth 样式。同时使用默认的 modal 类来创建模态框的初始样式。然后,基于 options 的值,有条件地以相同的方式创建关闭按钮和模态框的蒙层。

最后,我们将 content 添加到一个变量为 contentHolderdiv 元素中,并将其插入到 modal 元素中。再把 modal 元素添加到 DocumentFragment 中,然后把 DocumentFragment 插入到 body 中(插入到 </body> 标签前)。这样一来,我们就在页面上创建了一个模态框。

有关于 DocumentFragment 和DOM操作相关的知识,可以阅读下面文章进行扩展:

事件

这个模态框不会自动关闭,这也是我们希望的效果。为了能让用户关闭模态框,我们需要一个关闭按钮,并在关闭按钮上添加事件,让用户能点击按钮来关闭模态框。或者在模态框的蒙层上绑定相应的事件,让用户点击蒙层也能关闭模态框。接下来,我们创建一个函数,来实现这个功能:

function initializeEvents() {
    if (this.closeButton) {
        this.closeButton.addEventListener('click', this.close.bind(this))
    }

    if (this.overlay) {
        this.overlay.addEventListener('click', this.close.bind(this))
    }
}

上面的代码中使用 addEventListener 方法绑定 click 事件,将回调传递给尚未创建的 close 方法。注意,我们不只是调用 close ,而是使用 bind 方法并把 this 传递给它,它引用了我们的 Modal 对象。这确保我们的方法在使用 this 关键词时具有正确的上下文。

有关于JavaScript事件相关知识的扩展可以阅读下面相关文章:

打开模态框

还记得前面说到过,我们创建过 open 的公共方法,接下来给它添加相应的功能:

Modal.prototype.open = function() {
    // 创建Modal
    buildOut.call(this)

    // 初始化事件侦听器
    initializeEvents.call(this)

    // 向DOM中添加元素之后,使用getComputedStyle强制浏览器重新计算并识别刚刚添加的元素,这样CSS动画就有了一个起点
    window.getComputedStyle(this.modal).height

    // 检查Modal的高度是否比窗口高,如果是则添加modal-open 和 modal-anchored类名,否则添加modal-open类
    this.modal.className = this.modal.className + (this.modal.offsetHeight > window.innerHeight ? ' modal-open modal-anchored' : ' modal-open')

    this.overlay.className = this.overlay.className + ' modal-open'
}

在打开我们的模态框之前首先要创建它。这里使用 call() 方法来调用 buildOut() 方法,类似使用 bind() 进行事件绑定时的方法。只需要把 this 值传递给 call() 方法。然后调用 initializeEvents() ,以确保适用的事件都得到了绑定。

模态框的显示和隐藏是基于类名来实现的。当你向DOM中添加一个元素,然后添加一个类名时,浏览器可能不会干预初始样式,因此你永远不会看到模态框从初始状态过渡的效果。这也就是 window.getComputedStyle 的作用之处。调用该函数将迫使浏览器重新计算,从而识别模态框的初始状态,让我们模态框的过渡效果看起来较为逼真。最后给模态框添加 modal-open 类名。

但这并不是全部。我们希望模态框在浏览器窗口中能水平垂直居中,但如果模态框的高度超过了视口(浏览器窗口),那么模态框就会看起来很奇怪。这里使用三元运算符来检查高度,如果模态框高度大于视口高度时,我们会给模态框同时添加 modal-anchormodal-open 类名,反之则只添加 modal-open 类名。其中 modal-anchor 类名就是来处理模态框高度大于视口高度的样式。

关闭模态框

前面也提到过了,我们需要有一个功能,让用户可以关闭模态框。因此我们需要创建另一个公用方法 close()

Modal.prototype.close = function(){
    // 存储this
    var $this = this

    // 移除打开模态框时添加的类名
    this.modal.className = this.modal.className.replace(' modal-open', '')
    this.overlay.className = this.overlay.className.replace(' modal-open', '')

    // 监听CSS的transitionEnd事件,然后从DOM中删除节点
    this.modal.addEventListener(this.transitionEnd, function(){
        $this.modal.parentNode.removeChild($this.modal)
    })

    this.overlay.addEventListener(this.transitionEnd, function(){
        if ($this.overlay.parentNode) {
            $this.overlay.parentNode.removeChild($this.overlay)
        }
    })
}

为了让模态框移出有一个过渡效果,我们可以删除 modal-open 类名。这个同样适用于模态框的蒙层。但我们还没有结束。我们必须将模态框从DOM中删除,但如果不等动画完成就把它删除,效果上看上去会非常的奇怪。可以通过监听 this.transitionEnd 事件来监听过渡什么时候完成。浏览器对于过渡结束有不同的事件名称,因此编写了一个方法来检测使用哪一个,并在构造函数中调用它。如下所示:

function transitionSelect() {
    var el = document.createElement('div')

    if (el.style.WebkitTransition) {
        return 'webkitTransitionEnd'
    }

    return 'transitionEnd'
}

在JavaScript中 call()apply()bind() 三个方法对于前端开发者而言也是很重要的,如查你想扩展这方面的知识,可以阅读下面相关文章:

简单的小结

写到这里,我们已经构建了一个属于自己的模态弹出框。加上注释之类的,我们也仅仅用了差不多100行JavaScript代码就实现了。下面是整个模态框的所有代码:

// 创建一个立即调用的函数表达式来包装我们的代码
(function(){
    // 定义构造器
    this.Modal = function() {

        // 创建引用的全局元素
        this.closeButton = null // 创建关闭按钮
        this.modal = null       // 创建模态框元素
        this.overlay = null     // 创建模态框蒙层

        // 确定正确的前缀(浏览器私有前缀)
        this.transitionEnd = transitionSelect()

        // 定义默认的options
        var defaults = {
            className: 'fade-and-drop',
            closeButton: true,
            content: '',
            maxWidth: 600,
            minWidth: 280,
            overlay: true
        }

        // 通过扩展arugments中传递的缺省值来创建选项
        if (arguments[0] && typeof arguments[0] === 'object') {
            this.options = extendDefaults(defaults, arguments[0])
        }
    }

    // 公有方法

    // 关闭模态弹出框
    Modal.prototype.close = function() {
        // 存储this
        var $this = this

        // 移除打开模态框时添加的类名
        this.modal.className = this.modal.className.replace(' modal-open', '')
        this.overlay.className = this.overlay.className.replace(' modal-open', '')

        // 监听CSS的transitionEnd事件,然后从DOM中删除节点
        this.modal.addEventListener(this.transitionEnd, function(){
            $this.modal.parentNode.removeChild($this.modal)
        })

        this.overlay.addEventListener(this.transitionEnd, function(){
            if ($this.overlay.parentNode) {
                $this.overlay.parentNode.removeChild($this.overlay)
            }
        })
    }

    // 打开模态框
    Modal.prototype.open = function() {
        // 创建模态框
        buildOut.call(this)

        // 初始化事件侦听器
        initializeEvents.call(this)

        // 向DOM中添加元素之后,使用getComputedStyle强制浏览器重新计算并识别刚刚添加的元素,这样CSS动画就有了一个起点
        window.getComputedStyle(this.modal).height

        // 检查Modal的高度是否比窗口高,如果是则添加modal-open 和 modal-anchored类名,否则添加modal-open类
        this.modal.className = this.modal.className + (this.modal.offsetHeight > window.innerHeight ? ' modal-open modal-anchored' : ' modal-open')

        this.overlay.className = this.overlay.className + ' modal-open'
    }

    // 私有方法
    function buildOut() {
        var content, contentHolder, docFrag;

        // 如果content是HTML字符串,则追回HTML字符串
        // 如果content是domNode,则追回其内容
        if (typeof this.options.content === 'string') {
            content = this.options.content
        } else {
            content = this.options.content.innerHTML
        }

        // 创建一个DocumentFragment
        docFrag = document.createDocumentFragment()

        // 创建modal元素
        this.modal = document.createElement('div')
        // 设置模态框元素的类名
        this.modal.className = 'modal ' + this.options.className
        // 设置模态框样式(尺寸)
        this.modal.style.minWidth = this.options.minWidth + 'px'
        this.modal.style.maxWidth = this.options.maxWidth + 'px'

        // 如果options中的closeButton值为true,则创建关闭按钮
        if (this.options.closeButton === true) {
            this.closeButton = document.createElement('button')
            this.closeButton.className = 'modal-close close-button'
            this.closeButton.innerHTML = '×'
            this.modal.appendChild(this.closeButton)
        }

        // 如果options中的overlay值为true,则给模态框添加一个蒙层
        if (this.options.overlay === true) {
            this.overlay = document.createElement('div')
            this.overlay.className = 'modal-overlay ' + this.options.className
            docFrag.appendChild(this.overlay)
        }

        // 创建模态框内容区域,并插入到模态框中
        contentHolder = document.createElement('div')
        contentHolder.className = 'modal-content'
        contentHolder.innerHTML = content
        this.modal.appendChild(contentHolder)

        // 把模态框插入到 DocumentFragment中
        docFrag.appendChild(this.modal)

        // 把DocumentFragment插入到body中
        document.body.appendChild(docFrag)
    }

    // 使用用户选扩展默认值的方法
    function extendDefaults(source, properties) {
        var property
        for (property in properties) {
            if (properties.hasOwnProperty(property)) {
                source[property] = properties[property]
            }
        }
        return source
    }

    // 初始化事件监听器
    function initializeEvents() {
        // 给关闭按钮添加click事件,点击关闭模态框
        if (this.closeButton) {
            this.closeButton.addEventListener('click', this.close.bind(this))
        }

        // 给蒙层添加click事件,点击关闭模态框
        if (this.overlay) {
            this.overlay.addEventListener('click', this.close.bind(this))
        }
    }

    // 选择正确的浏览器私有前缀
    function transitionSelect() {
        var el = document.createElement('div')
        if (el.style.WebkitTransition) {
            return 'webkitTransitionEnd'
        }

        return 'transitionend'
    }
}())

模态框基本样式

接着给模态框添加一些基本样式:

.modal-overlay {
    position: fixed;
    will-change: transform;
    z-index: 9999;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;

    opacity: 0
    background-color: rgba(0,0,0,.65);

    transition: 1ms opacity ease;

    &.modal-open {
        opacity: 1;
    }
}

.modal {
    position: absolute;
    z-index: 10000;
    top: 50%;
    left: 50%
    transform: translate(-50%,-50%);

    max-width: 80vw;
    padding: 30px 20px;

    transition: 1ms opacity ease;
    opacity: 0;

    border-radius: 4px;
    background-color: #fff;

    &.modal-anchored {
        top: 2vh;
        transform: translate(-50%, 0);
    }

    &.modal-open {
        opacity: 1;
    }
}

.modal-close {
    font-family: Helvetica,Arial,sans-serif;
    font-size: 24px;
    font-weight: 700;
    line-height: 12px;

    position: absolute;
    top: 5px;
    right: 5px;

    padding: 5px 7px 7px;

    cursor: pointer;

    color: #fff;
    border: 0;
    outline: none;
    background: #e74c3c;

    &:hover {
        background: #c0392b;
    }
}

上面的样式代码非常的简单。只是确保模态框和模态框的蒙层默认情况下显示。离开默认状态时有一个 1mstransition 效果(即 opacity01 的一个过渡效果),而这个效果会通过 transitionEnd 事件来触发。另外通过 transformtranslate() 函数,让模态框在视口中水平垂直居中。如果模态框应用了 modal-anchored 类名,那么模态框只水平居中,且距离视口顶部 2vh

除此这外,还可以通过 options 中的 className 给模态框添加自定义动画,因此我们可以使用 options 选项中 className 的默认值 fade-and-drop 来定义这个动画:

// 默认动画效果
.modal-overlay.fade-and-drop {
    display: block;
    opacity: 0;
    transition: 500ms opacity 500ms ease;

    &.modal-open {
        top: 0;
        transition: 500ms opacity ease;
        opacity: 1;
    }
}

.modal.fade-and-drop {
    top: -300vh;
    opacity: 1;
    display: block;
    transition: 500ms top ease;

    &.modal-open {
        top: 50%;
        transition: 500ms top 500ms ease;

        &.modal-anchored {
            transition: 500ms top 500ms ease;
        }
    }
}

上面的代码实现了一个淡入淡出的过渡效果。

创建模态框

到目前为止,我们已经创建了一个模态框插件,也为该插件添加了一些默认的CSS。但在Web页面上并看不到模态框的身影。那是因为我们还没有通地模态框插件来创建自己的模态框。接下来,我们来看看怎么创建一个模态框。

创建一个模态框很简单,只需要使用 new 关键词就可以创建一个模态框,然后把这个新创建的模态框对象赋值给一个变量,比如 myModal

var myModal = new Modal()

如果我们把 myModal 打印出来,可以看到像下图这样的一个信息:

如何使用JavaScript构建模态框插件

我们在 Modal 插件中创建了两个公共方法, open()close() 。如果我们要调用这两个方法,可以使用 myModal.open() 。但这样会报错:

如何使用JavaScript构建模态框插件

Modal 插件中提供了 options (一些有关于模态框插件的默认选项),另外我们也可以给模态框传一些参数,比如:

var myModal = new Modal({
    content: `<p>我是一个模态框</p>`,
    maxWidth: 600
})

myModal.open()

这个时候,模态框就出来了,而且打印出来的 myModal 相关的信息也变了:

如何使用JavaScript构建模态框插件

另外,新创建的模态框有一个默认的动画效果,这个动画效果就是 fade-and-drop 类名中设置的效果:

如何使用JavaScript构建模态框插件

如果我们想要一个属于自己的模态框动效。方法也很简单,只需要在 Modal 插件的 optionsclassName 选项中添加一个类名,我们可以像下面这样使用:

var myModal = new Modal({
    className: 'custom-animation',
    content: `通过className自定义一个类名,创建模态框动效`,
    maxWidth: 600
})

myModal.open()

这个时候,默认的 fade-and-drop 的类名变成了 custom-animation ,如下图所示:

如何使用JavaScript构建模态框插件

接下来,要给 custom-animation 添加一些样式,用来设置实现自己动效的一些样式代码:

.modal.custom-animation {
    transition: 500ms transform ease;
    transform:translate(-50%, -50%) scale(0);

    &.modal-open{
        transform: translate(-50%, -50%)  scale(1);
    }
}

效果如下:

如何使用JavaScript构建模态框插件

到此为止,我们主要学习的是如何通过JavaScript来创建一个模态框插件,并没有聊怎么编写模态框。如果我们想插件在实例化时就能自动打开,那么就需要在 options 中添加新的一个选项 autoOpen 。该值在默认状态中是 false

var defaults = {
    //... 以前的选项
    autoOpen: false
}

接下来,只要在插件中检测 autoOpen 是否为 true ,如果为 true ,则启动 open() 方法来打开模态框:

if(this.options.autoOpen === true) this.open()

实例

估计大家都清楚模态框的使用场景,一般情况,模态框是不会显示的,只有用户触发了,比如点击了某个按钮,才显示模态框。接下来,我们来看看自己写的模态框插件的使用:

总结

文章中的主要内容是介绍如何使用原生的JavaScript来构建一个模态框。其实这里主要介绍的是介绍模态框插件的构建,而不是怎么写一个模态框。另外,这篇文章对于一些初学JavaScript或者更想深入的学习JavaScript的同学而言应该是有所帮助的。好比我自己,在这里就获取了不少的知识点,所以我也希望你也能从该文中得到你自己想要学习的知识点。

虽然该文介绍的是如何构建一个模态框插件,但最终也可以让创建一个模态框,并且还可以根据模态框提供的选项,让你实现自己想要的模态框,另外还可以配上一些CSS动效,让你的模态框效果可以变得更佳。当然,模态框插件的构建只是其中的一个示例,而该文中最终的目的是希望你能从这篇文章中学到如何使用JavaScript来构建插件,构建你自己任何想要的插件。如果你感兴趣的话,不仿 根据该文提供的思路和技巧,尝试着去构建你的插件。如果你构建出来了,欢迎在下面的评论中与我们一起共享。

最后要说的是,整篇文章的思路以及代码来自@Ken Wheeler的《 Building Your Own JavaScript Modal Plugin 》一文。这里特感谢@Ken Wheeler为我们初学JavaScript的同学提供这么优秀的教程和源码。


以上所述就是小编给大家介绍的《如何使用JavaScript构建模态框插件》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Math Adventures with Python

Math Adventures with Python

Peter Farrell / No Starch Press / 2018-11-13 / GBP 24.99

Learn math by getting creative with code! Use the Python programming language to transform learning high school-level math topics like algebra, geometry, trigonometry, and calculus! In Math Adventu......一起来看看 《Math Adventures with Python》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具