Snackbar 是 Material Design 中的一种弹出式交互控件,可以在屏幕底部或顶部弹出一条消息,类似于 Toast,但具有更加复杂的 UI 和交互特性。Snackbar 通常用于提示用户操作的状态或重要事件,并且支持包含图标、动作按钮等多种内容。
本文将介绍如何使用 HTML、CSS 和 JavaScript 实现含动画效果的 Material Design 中的 Snackbar。
实现思路
Snackbar 的实现可以分为以下三个部分:
- HTML 结构:Snackbar 包含消息内容、动作按钮等多个元素,需要用 HTML 定义它们的关系和样式。
- CSS 样式:Snackbar 包含很多动画效果,需要使用 CSS 规定它们的动画过渡、位置、尺寸和颜色等。
- JavaScript 控制:Snackbar 需要在页面加载时自动弹出并且能够接受用户的交互操作,需要使用 JavaScript 实现自动弹出和多种交互效果。
下面我们将分别介绍这三个方面的实现细节。
HTML 结构
Snackbar 的 HTML 结构主要包括以下几个部分:
- 消息内容:用一个 div 元素包含消息内容,可以使用标签、文本和图标等。
- 动作按钮:可以选择包含一个动作按钮,用于用户点击后执行操作,通常放在消息内容之后。
- 关闭按钮:Snackbar 包含一个关闭按钮,用于用户手动关闭它,通常放在消息内容之后。
- 容器元素:Snackbar 要放在页面的底部或顶部,需要使用一个固定定位的容器元素作为其父元素。
下面是一个简单的 Snackbar 的 HTML 结构示例:
<div class="snackbar-container"> <div class="snackbar-message"> <span>这是一条消息</span> </div> <div class="snackbar-action"> <button>操作</button> </div> <div class="snackbar-close">✖</div> </div>
CSS 样式
Snackbar 的 CSS 样式主要包括以下几个部分:
- 位置和尺寸:Snackbar 要定位在屏幕的底部或顶部,需要使用绝对定位或固定定位实现。另外,Snackbar 的尺寸可以根据内容的宽度和高度自适应。
- 动画效果:Snackbar 的出现、消失和用户交互过程需要使用 CSS 动画实现,包括渐显、渐隐、上下移动等效果。
- 颜色和特效:Snackbar 的颜色和特效可以使用 Material Design 风格的颜色和阴影实现。
下面是一个简单的 Snackbar 的 CSS 样式示例:
.snackbar-container { position: fixed; bottom: 0; width: 100%; padding: 0.5em 1em; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); background-color: #fff; animation: animateIn 0.3s ease-out; animation-fill-mode: forwards; } .snackbar-message { display: inline-block; margin-right: 1em; } .snackbar-action { display: inline-block; } .snackbar-close { position: absolute; top: 0.5em; right: 0.5em; font-size: 1.25em; cursor: pointer; animation: rotateIn 0.3s ease-out; animation-fill-mode: forwards; } @keyframes animateIn { from { transform: translateY(100%); } to { transform: translateY(0%); } } @keyframes animateOut { from { transform: translateY(0%); } to { transform: translateY(100%); } } @keyframes rotateIn { from { transform: rotate(0); } to { transform: rotate(45deg); } } @keyframes rotateOut { from { transform: rotate(45deg); } to { transform: rotate(0); } }
这里定义了一个 .snackbar-container 的容器元素,和三个 .snackbar-message、.snackbar-action、.snackbar-close 的子元素。.snackbar-message 和 .snackbar-action 定义了消息内容和动作按钮的布局,.snackbar-close 定义了关闭按钮的样式。而.animateIn、.animateOut、.rotateIn、.rotateOut 则分别定义了出现、消失和关闭按钮旋转的动画效果。
JavaScript 控制
Snackbar 的 JavaScript 控制主要要实现以下几个功能:
- 自动弹出:Snackbar 要在页面加载时自动弹出,可以在页面加载完成时执行一个 JavaScript 函数来实现。
- 自动关闭:Snackbar 弹出后要自动关闭,可以使用 setTimeout() 来等待一定时间后自动关闭。
- 手动关闭:Snackbar 要支持用户手动关闭,可以给关闭按钮添加点击事件来实现。
- 动作按钮:Snackbar 的动作按钮要支持点击事件和回调函数,可以通过参数传递回调函数和事件处理逻辑。
下面是一个简单的 Snackbar 的 JavaScript 控制示例:
function showSnackbar(message, action, callback) { var container = document.createElement("div"); container.className = "snackbar-container"; var messageEle = document.createElement("div"); messageEle.className = "snackbar-message"; messageEle.innerHTML = message; var actionEle = null; if (action) { actionEle = document.createElement("div"); actionEle.className = "snackbar-action"; var button = document.createElement("button"); button.innerHTML = action; button.onclick = function () { callback(); hideSnackbar(container); }; actionEle.appendChild(button); } var closeEle = document.createElement("div"); closeEle.className = "snackbar-close"; closeEle.innerHTML = "✖"; closeEle.onclick = function () { hideSnackbar(container); }; container.appendChild(messageEle); if (actionEle) { container.appendChild(actionEle); } container.appendChild(closeEle); document.body.appendChild(container); setTimeout(function () { hideSnackbar(container); }, 5000); } function hideSnackbar(container) { container.classList.add("animateOut"); container.addEventListener("animationend", function () { container.remove(); }); }
这里定义了一个 showSnackbar() 函数来创建 Snackbar,它接受三个参数,分别是消息内容、动作按钮内容和回调函数。在函数内部,首先创建一个 .snackbar-container 的容器元素,然后根据参数创建消息内容、动作按钮等元素,最后添加到容器元素中,并将容器元素添加到body中。同时通过 setTimeout() 定时器来控制 Snackbar 自动关闭。
最后定义了一个 hideSnackbar() 函数,用于处理 Snackbar 的关闭效果。在这个函数中通过给容器元素添加 .animateOut 类,来触发 CSS 动画,并在动画结束后将容器元素从页面中删除。
示例代码
下面是一个完整的含动画效果的 Material Design 中的 Snackbar 的示例代码,可以直接运行在浏览器中。
<!DOCTYPE html> <html> <head> <title>Snackbar</title> <style> .snackbar-container { position: fixed; bottom: 0; width: 100%; padding: 0.5em 1em; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); background-color: #fff; animation: animateIn 0.3s ease-out; animation-fill-mode: forwards; } .snackbar-message { display: inline-block; margin-right: 1em; } .snackbar-action { display: inline-block; } .snackbar-close { position: absolute; top: 0.5em; right: 0.5em; font-size: 1.25em; cursor: pointer; animation: rotateIn 0.3s ease-out; animation-fill-mode: forwards; } @keyframes animateIn { from { transform: translateY(100%); } to { transform: translateY(0%); } } @keyframes animateOut { from { transform: translateY(0%); } to { transform: translateY(100%); } } @keyframes rotateIn { from { transform: rotate(0); } to { transform: rotate(45deg); } } @keyframes rotateOut { from { transform: rotate(45deg); } to { transform: rotate(0); } } </style> </head> <body> <button onclick="showSnackbar('这是一条消息', '操作', function(){console.log('点击操作按钮')})">弹出 Snackbar</button> <script> function showSnackbar(message, action, callback) { var container = document.createElement("div"); container.className = "snackbar-container"; var messageEle = document.createElement("div"); messageEle.className = "snackbar-message"; messageEle.innerHTML = message; var actionEle = null; if (action) { actionEle = document.createElement("div"); actionEle.className = "snackbar-action"; var button = document.createElement("button"); button.innerHTML = action; button.onclick = function () { callback(); hideSnackbar(container); }; actionEle.appendChild(button); } var closeEle = document.createElement("div"); closeEle.className = "snackbar-close"; closeEle.innerHTML = "✖"; closeEle.onclick = function () { hideSnackbar(container); }; container.appendChild(messageEle); if (actionEle) { container.appendChild(actionEle); } container.appendChild(closeEle); document.body.appendChild(container); setTimeout(function () { hideSnackbar(container); }, 5000); } function hideSnackbar(container) { container.classList.add("animateOut"); container.addEventListener("animationend", function () { container.remove(); }); } </script> </body> </html>
总结
通过本文的介绍,我们了解了如何使用 HTML、CSS 和 JavaScript 实现含动画效果的 Material Design 中的 Snackbar。Snackbar 具有复杂的 UI 和交互特性,涉及到 HTML、CSS 和 JavaScript 的多个方面,需要具备一定的前端开发能力才能很好地实现它。但是,掌握 Snackbar 的技术原理和实现方法,对于提升前端开发能力和应用 Material Design 风格有重要的学习和指导意义。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659e6054add4f0e0ff759c7d