百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

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

toyiye 2024-07-03 01:59 18 浏览 0 评论

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

模态框是什么

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

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

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

  • 模态框的蒙层:modal-overlay
  • 模态框头部:modal-header
  • 模态框主体:modal-body
  • 模态框脚部:modal-footer
  • 关闭按钮:modal-close

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

  • 取消按钮
  • 关闭按钮
  • ECS键
  • 点击模态框窗体外的区域关闭模态框

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

构建模态框插件

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

  • CSS的transition或animation相关知识点
  • 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 {}

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

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

  • JavaScript 闭包
  • 学习Javascript闭包
  • 闭包(Closures)
  • 解释 JavaScript 的作用域和闭包
  • JavaScript闭包初探
  • 征服 JavaScript 面试:什么是闭包?
  • 理解JAVASCRIPT的闭包
  • 我从没理解过 JavaScript 闭包
  • 从JavaScript闭包函数的undefined形参说起

选项(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,其结果如下图所示:

为了提供一个公共主法,可以将它附加到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更多的介绍可以阅读下面相关文章:

  • Arguments 对象
  • ES6中Arguments和Parameters用法解析
  • JavaScript 函数参数-Arguments(实参)对象

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

  • 详解JavaScript构造器
  • 构造方法
  • 构造函数的继承
  • 构造函数与 new 命令

核心功能

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

  • 构建一个模态元素并将其添加到页面中
  • 将选项(options)中的className指定一个类名,并将其添加到模态元素中
  • 如果选项中的closeButton为true,则添加关闭按钮
  • 如果选项中的content是 HTML 字符串,则将其设置为模态元素中的内容
  • 如果选项中的content是domNode,则将其内部内容设置为模态元素的内容
  • 分别设置模态的maxWidth和minWidth
  • 如果选项中的overlay为true,则给模态框添加一个蒙层
  • 当模态框显示时,添加一个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值;如果我们的content是domNode,我们通过innerHTML将内容变量设置为它的内部HTML。

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

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

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

  • DocumentFragment
  • Text 节点和 DocumentFragment 节点
  • 如何减少浏览器回流
  • JavaScript 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事件相关知识的扩展可以阅读下面相关文章:

  • DOM事件
  • 事件介绍
  • 事件模型
  • JavaScript事件机制
  • 漫谈JS自定义事件、DOM/伪DOM自定义事件

打开模态框

还记得前面说到过,我们创建过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-anchor和modal-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()三个方法对于前端开发者而言也是很重要的,如查你想扩展这方面的知识,可以阅读下面相关文章:

  • How-to: call() , apply() and bind() in JavaScript
  • Implement your own?—?call(), apply() and bind() method in JavaScript
  • Mastering this in JavaScript: Callbacks and bind(), apply(), call()
  • JavaScript 中至关重要的 Apply, Call 和 Bind
  • 专业JavaScript程序员必须知道的apply(), call(), bind()方法
  • 深入浅出 妙用Javascript中apply、call、bind
  • JavaScript中call,apply,bind以及this的理解

简单的小结

写到这里,我们已经构建了一个属于自己的模态弹出框。加上注释之类的,我们也仅仅用了差不多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;
 }
}

上面的样式代码非常的简单。只是确保模态框和模态框的蒙层默认情况下显示。离开默认状态时有一个1ms的transition效果(即opacity从0到1的一个过渡效果),而这个效果会通过transitionEnd事件来触发。另外通过transform的translate()函数,让模态框在视口中水平垂直居中。如果模态框应用了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打印出来,可以看到像下图这样的一个信息:

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

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

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

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

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

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

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

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

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

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

效果如下:

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

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

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

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

实例

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

总结

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

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

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码