输入错误震动反馈(表单校验 Shake 动画)
表单输入错误震动反馈:邮箱格式校验失败时输入框左右震动、红框高亮、警示图标弹出并显示错误文案,原生 JS 约 20 行,复制即用。
效果演示(真实可交互)
在演示表单里输入一个错误格式的邮箱(如 abc),点击提交:输入框会左右震动、边框变红、右侧弹出警示图标,下方出现错误文案;输入合法邮箱后提交则显示绿色通过提示。重新输入时错误提示自动清除,连续提交时震动可重复播放。
输入错误的邮箱格式后点击提交,看看震动反馈 👀
完整代码
HTML:
<form id="myForm" novalidate>
<div class="field" id="field">
<label for="email">邮箱地址</label>
<input id="email" type="email" placeholder="name@example.com">
<span class="icon" aria-hidden="true">⚠️</span>
<p class="msg" id="msg" role="alert"></p>
</div>
<button type="submit">提交</button>
</form>
CSS(震动关键帧 + 错误态):
.field .icon { opacity: 0; transition: opacity .2s; }
.field.error .input { border-color: #ff5d6c; background: #fff7f8; animation: shake .5s ease; }
.field.error .icon { opacity: 1; }
@keyframes shake {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-9px); }
40% { transform: translateX(8px); }
60% { transform: translateX(-6px); }
80% { transform: translateX(4px); }
}
JS(约 20 行,校验 + 震动重放 + 输入清除):
const form = document.getElementById('myForm');
const input = document.getElementById('email');
const field = document.getElementById('field');
const msg = document.getElementById('msg');
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
form.addEventListener('submit', (e) => {
e.preventDefault();
const ok = EMAIL_RE.test(input.value.trim());
field.classList.remove('error');
void field.offsetWidth; // 强制重排,让动画可连续重放
if (!ok) {
field.classList.add('error');
msg.textContent = '邮箱格式不正确,请检查后重试';
input.focus();
}
});
input.addEventListener('input', () => { // 重新输入即清除错误态
field.classList.remove('error');
msg.textContent = '';
});
参数说明
| 参数 | 位置 | 说明 |
|---|---|---|
| 震动幅度 | translateX(-9px) 等 | 首拍最大,逐级衰减,模拟真实抖动 |
| 震动时长 | animation: shake .5s | 400-600ms 最自然 |
| 校验规则 | EMAIL_RE 正则 | 换成手机号、用户名等任意规则 |
| 错误色 | #ff5d6c | 全局统一红色,符合直觉 |
| 连续重放 | void field.offsetWidth | 触发重排,让动画重置再播 |
兼容性与性能
- 原生 JS + CSS 动画,无任何依赖,兼容所有现代浏览器
- 震动只作用于 transform,GPU 加速;错误态存在期间无持续动画,无性能开销
- 使用
role="alert"与autocomplete属性,屏幕阅读器可感知错误,无障碍友好 novalidate关闭浏览器默认气泡,统一使用自定义反馈样式
常见问题
Q: 能商用吗? 可以。本组件为粤喵自研,免费商用无需署名。
Q: 连续两次提交错误,第二次为什么不震了? 动画在 class 已存在时不会重播。JS 里先 classList.remove('error') 再强制重排(void field.offsetWidth)后重新添加,即可每次都震动。
Q: 怎么在真实接口校验失败时也触发? 把震动逻辑抽成函数 showError(msg),接口返回非 2xx 或业务码失败时调用即可,前端校验与后端校验共用同一套反馈。
Q: 震动幅度想更小更克制? 把关键帧里的位移数值整体减半(如 -4px / 3px),并保留衰减结构,反馈依然清晰但不再夸张。
许可与来源
- 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
- 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
- 首次发布:2026-09-01 · 最近更新:2026-09-01
- 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
- 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理
常见问题
这个组件可以商用吗?
可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。
浏览器兼容性如何?
支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。
怎么修改动画参数?
直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。