“Lightbox” effects have been an established UI pattern for a decade, but the vast majority of implementations have been framework-dependent. In previous articles I’ve shown how to create a Lightbox UI using only CSS, although that version lacked controls. By adding the <dialog> element
and a dozen lines of vanilla JavaScript, we can recreate a traditional lightbox perfectly:
十年来,“灯箱”效果已经成为一种既定的UI模式,但是绝大多数实现方式都依赖于框架。 在之前的文章中,我展示了如何仅使用CSS创建灯箱UI ,尽管该版本缺少控件。 通过添加<dialog> element
和十几行香草JavaScript ,我们可以完美地重新创建传统的灯箱:
标记 (The Markup)
<nav id="thumbs">
<a href="elephant.jpg"><img src="elephant-thumb.jpg" alt></a>
<a href="taj-mahal.jpg"><img src="taj-mahal-thumb.jpg" alt></a>
<a href="wise-man.jpg"><img src="wise-man-thumb.jpg" alt></a>
</nav>
<dialog id="cover">
<button id="closecover">Close</button>
<img src="" alt>
</dialog>
The linked images follow the pattern used in my previous “Accessible Image Gallery with Progressive JavaScript” article; the large image inside the <dialog>
element is a placeholder that we’ll change later using JavaScript. (alt
values have been left blank for the sake of brevity).
链接的图像遵循我以前的“ 带有渐进式JavaScript的可访问图像库 ”文章中使用的模式; <dialog>
元素中的大图像是一个占位符,稍后我们将使用JavaScript对其进行更改。 (为简洁起见, alt
值保留为空白)。
CSS (The CSS)
@keyframes fadeToNearBlack {
to { background: rgba(0,0,0,0.9); }
}
@keyframes goBig {
to { opacity: 1; }
}
nav {
display: flex;
}
nav a {
display: block; flex: 1;
}
nav a img,
dialog img {
width: 100%; height: auto;
}
dialog { border: none; opacity: 0; }
dialog button {
border: none; background: none; font-size: 1.2rem;
}
dialog[open] {
animation: goBig 1s .4s forwards;
width: 70%; margin: auto;
position: absolute; max-width: 700px;
}
dialog[open]::backdrop {
animation: fadeToNearBlack 1s forwards;
}
.backdrop {
animation: fadeToNearBlack 1s forwards;
}
The animations will fade in the <dialog>
element; the <nav>
links are displayed using flexbox to divide them evenly across the page. When visible, the <dialog>
element is positioned using a variation on one of the established methods of centering elements when the height of the parent (the <body>
, in this case) is unknown. (Vendor prefixes have been dropped for the purpose of clarity).
动画将在<dialog>
元素中消失; <nav>
链接使用flexbox进行显示,以在页面上平均分配它们。 当可见时,当父对象(在这种情况下为<body>
)的高度未知时, 使用对中元素的一种既定方法对 <dialog>
元素进行定位。 (为了清楚起见,已删除了供应商前缀 )。
JavaScript (The JavaScript)
The script goes at the end of the document; other browsers will require an additional polyfill to support the <dialog>
element.
该脚本位于文档末尾; 其他浏览器将需要附加的polyfill来支持<dialog>
元素。
function showImage(e) {
e.preventDefault();
coverimage.setAttribute("src", this.getAttribute("href"));
coverimage.setAttribute("alt", this.querySelector("img").getAttribute("alt"));
cover.showModal();
}
document.getElementById("closecover").onclick = function() {
coverimage.setAttribute("src", "");
cover.close();
}
var imglinks = document.getElementById("thumbs").getElementsByTagName('a'),
cover = document.getElementById("cover"),
coverimage = cover.getElementsByTagName("img")[0];
testdialog=document.createElement("dialog");
testdialog.setAttribute("open", "");
if (!testdialog.open) {
dialogPolyfill.registerDialog(cover);
}
for (var i=0; i<imglinks.length; i++) {
imglinks[i].onclick = showImage;
}
The script attaches a function to each of the links; when the user clicks on one, it sets the src
attribute of the large image in the <dialog>
element to the value of the link and shows the modal window; the elements animate due to the CSS we applied earlier. Clicking on the altered <button>
element closes the modal. Because the thumbnail images are links, they are also progressive and accessible.
该脚本将函数附加到每个链接。 当用户单击一个时,它将<dialog>
元素中大图像的src
属性设置为链接的值并显示模式窗口; 由于我们之前应用了CSS,因此这些元素会动画 。 单击更改的<button>
元素将关闭模式。 由于缩略图是链接,因此它们也是渐进的且可访问的 。
结论与改进 (Conclusion & Improvements)
There are a few things that could be better; obviously, being able to drop the polyfill once all browsers support the <dialog>
element would be good, and the element itself could be animated like the version in my CSS-only example. Centering the element perfectly across different platforms could also be improved: right now, things move around a little more than I would like. I’ll leave that and further enhancements for a future article.
有些事情可能会更好。 显然,一旦所有浏览器都支持<dialog>
元素,便能够删除polyfill会很好,并且该元素本身也可以像我的纯CSS示例中的版本那样进行动画处理。 还可以改善将元素完美地放在不同平台上的中心位置:现在,事情的移动幅度超出了我的期望。 在以后的文章中,我将保留该内容和进一步的增强功能。
翻译自: https://thenewcode.com/962/A-Modern-HTML5-Lightbox-in-12-Lines-of-JavaScript