qfile 从头开始
在本教程中,我们将学习如何在不使用Bootstrap之类的框架或第三方库的情况下构建JavaScript弹出模式(弹出窗口)。 我们将从头开始构建整个过程,使我们可以完全控制它的工作方式和外观。
这是我们将创建的演示:
1.从页面标记开始
首先,我们将创建一个模式。 为此,我们将.modal
类和唯一ID添加到容器中。 接下来,我们将通过设置指定对话框.modal-dialog
元素作为直接子.modal
。 该对话框将包含模式内容。 这可以是任何类型的内容,例如文本,图像,灯箱,用户通知/警报等。
“弹出式窗口(或模式窗口)是一个很小的UI元素,将出现在网站的前台,通常是作为提示用户执行某些操作的提示而触发” – Adi Purdila
要打开模式,我们需要具有data-open
属性的任何元素(通常是button
)。 此属性的值应为所需模态的ID。
默认情况下,如果我们在其边界之外单击或按Esc
键,则模式将关闭。 但是,如果我们单击具有data-close
属性的任何元素(通常是button
),也可以将其data-close
。
最初,模态将以淡入淡出效果出现/消失。 但是我们可以通过data-animation
属性调整对话框的动画效果。 必须添加到.modal
的此属性的值可以是以下任意值:
-
slideInOutDown
-
slideInOutTop
-
slideInOutLeft
-
slideInOutRight
-
zoomInOut
-
rotateInOutDown
-
mixInAnimations
在下一部分中,我们将仔细研究这些值。
现在,让我们熟悉表示一个模态所需的标记:
<button type="button" class="open-modal" data-open="modal1">...</button>
<div class="modal" id="modal1">
<div class="modal-dialog">
<header class="modal-header">
...
<button class="close-modal" aria-label="close modal" data-close>✕</button>
</header>
<section class="modal-content">...</section>
<footer class="modal-footer">...</footer>
</div>
</div>
2.定义一些基本样式
准备好标记后,我们将设置一些CSS变量并重置样式:
:root {
--lightgray: #efefef;
--blue: steelblue;
--white: #fff;
--black: rgba(0, 0, 0, 0.8);
--bounceEasing: cubic-bezier(0.51, 0.92, 0.24, 1.15);
}
* {
padding: 0;
margin: 0;
}
button {
cursor: pointer;
background: transparent;
border: none;
outline: none;
font-size: inherit;
}
接下来,我们将水平和垂直居中页面内容。 另外,我们将为负责打开模式的按钮提供一些样式:
/*CUSTOM VARIABLES HERE*/
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
font: 16px/1.5 sans-serif;
}
.btn-group {
text-align: center;
}
.open-modal {
font-weight: bold;
background: var(--blue);
color: var(--white);
padding: .75rem 1.75rem;
margin-bottom: 1rem;
border-radius: 5px;
}
在这一点上,我们将注意力集中在模态样式上。
每个模态将具有以下特征:
- 它将以固定位置全屏显示。 也就是说,它将看起来像覆盖整个窗口的宽度和高度的覆盖层。
- 它将具有深色背景色。
- 默认情况下它将被隐藏。
- 对话框将水平和垂直居中。
/*CUSTOM VARIABLES HERE*/
.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
background: var(--black);
cursor: pointer;
visibility: hidden;
opacity: 0;
transition: all 0.35s ease-in;
}
对话框将具有最大宽度和最大高度。 它的高度将是窗口高度的80%。 如果其高度超过该值,则会出现一个垂直滚动条:
/*CUSTOM VARIABLES HERE*/
.modal-dialog {
position: relative;
max-width: 800px;
max-height: 80vh;
border-radius: 5px;
background: var(--white);
overflow: auto;
cursor: default;
}
最后,我们将为各个内容部分定义一些简单的样式:
/*CUSTOM VARIABLES HERE*/
.modal-dialog > * {
padding: 1rem;
}
.modal-header,
.modal-footer {
background: var(--lightgray);
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.modal-header .modal-close {
font-size: 1.5rem;
}
.modal p + p {
margin-top: 1rem;
}
3.切换模态
一页可以有多个模式。 但是,正如前面已经讨论的那样,所有模态最初都会被隐藏。
开放模式
同样,一个页面可以有多个打开触发器(具有data-open
属性的元素)。 每次单击触发器时,相关的模态应通过淡入动画变得可见。 请记住, data-open
属性值必须与模式ID匹配。
这是揭示模态的脚本:
const openEls = document.querySelectorAll("[data-open]");
const isVisible = "is-visible";
for(const el of openEls) {
el.addEventListener("click", function() {
const modalId = this.dataset.open;
document.getElementById(modalId).classList.add(isVisible);
});
}
和相关CSS类:
.modal {
visibility: hidden;
opacity: 0;
transition: all 0.35s ease-in;
}
.modal.is-visible {
visibility: visible;
opacity: 1;
}
封闭模态
在我们的实现中,一次只能显示一个模态(此代码不支持嵌套模态)。 如上面标记部分所述,有三种方法可以用淡出效果将其隐藏。
让我们回顾一下。
首先,单击位于模态内部的自定义[data-close]
元素:
const closeEls = document.querySelectorAll("[data-close]");
const isVisible = "is-visible";
for (const el of closeEls) {
el.addEventListener("click", function() {
this.parentElement.parentElement.parentElement.classList.remove(isVisible);
});
}
其次,单击模式之外的所有内容:
const isVisible = "is-visible";
document.addEventListener("click", e => {
if (e.target == document.querySelector(".modal.is-visible")) {
document.querySelector(".modal.is-visible").classList.remove(isVisible);
}
});
在这种情况下,模式(叠加)的行为就像一个巨大的关闭按钮。 因此,我们给它指定了cursor: pointer
。
最后,按Esc
键:
const isVisible = "is-visible";
document.addEventListener("keyup", e => {
if (e.key == "Escape" && document.querySelector(".modal.is-visible")) {
document.querySelector(".modal.is-visible").classList.remove(isVisible);
}
});
现在是查看我们到目前为止创建的内容的好时机:
模态看起来不错! 注意,每次我们单击打开的触发器时,只有相应的模态载荷。
让我们更进一步,研究一些动画对话框的想法。
4.添加对话框动画
就像我们之前说的,模态的默认行为是淡入和淡出。 但是可以选择调整弹出窗口的动画效果。
我已经创建了许多动画效果,您可以将它们用作淡入淡出效果的替代方法。 为此,只需将data-animation="yourDesiredAnimation"
属性传递给.modal
。
例如,如果您希望对话框以从左到右的slideInOutLeft
显示幻灯片动画,则需要slideInOutLeft
效果。
在幕后,有两个规则可以实现所需的动画:
/*CUSTOM VARIABLES HERE*/
[data-animation="slideInOutLeft"] .modal-dialog {
opacity: 0;
transform: translateX(-100%);
transition: all 0.5s var(--bounceEasing);
}
[data-animation="slideInOutLeft"].is-visible .modal-dialog {
opacity: 1;
transform: none;
transition-delay: 0.2s;
}
在此处检查这种动画类型的模态:
您可以通过查看最终演示项目的CSS选项卡来检查其余动画。 根据动画的复杂性,我使用CSS过渡或动画来构建它们。
我还利用了cubic-bezier()
函数来设置所有转换的计时函数。 如果您不喜欢所产生的反弹效果,请随时通过--bounceEasing
CSS变量将其更改为更平滑的--bounceEasing
。
看一下所有动画效果的最终演示:
结论
就是这样,伙计们! 在本教程中,我们学习了如何在不依赖任何前端框架的情况下构建自定义的动画模式对话框。
我希望您喜欢最终的结果,并建立它有助于提高您的前端技能。
请记住,我们尚未考虑可访问性,因此,如果您想增强此演示,则可以肯定是下一步。
一如既往,感谢您的阅读!
qfile 从头开始