如何让jQuery的Click与Tap事件触发同一函数并修复移动端涟漪失效问题
问题分析与优化方案
我来帮你拆解下当前代码的问题,然后给出更稳定的实现方式~
首先看你遇到的核心问题:移动端触摸时涟漪效果不生效,结合你的代码来看,主要有这几个原因:
1. 重复事件绑定导致逻辑冲突
你同时用了.click()和.on('click tap')绑定同一个元素,这会让点击/触摸时两个函数同时执行:一个在切换fill类,另一个直接给克隆元素加fill类,不仅逻辑矛盾,还打乱了DOM状态,这是最影响效果的问题。
2. tap事件本身无效
jQuery核心库不自带tap事件,这个事件是jQuery Mobile的扩展功能,如果没引入相关库,.on('tap')根本不会触发,移动端还是只能靠click响应。
3. 移动端:active伪类触发异常
移动端浏览器默认不会在触摸元素时保持:active状态,而你的涟漪动画刚好依赖:active:before,再加上没设置视口元标签,直接导致触摸时动画无法触发。
4. 不必要的元素克隆
每次点击都克隆、移除原元素的操作完全没必要,既破坏DOM结构,还可能引发事件绑定的意外问题,直接操作原元素的类就能实现需求。
优化后的完整实现
下面是修复后的代码,解决了所有问题,同时兼顾桌面端和移动端的体验:
<!-- 必须添加视口元标签,确保移动端正常识别交互状态 --> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet"> <div style="padding: 100px; float: left;"> <a class="hvr-ripple-out"><i class="fas fa-check"></i></a> </div> <style> .hvr-ripple-out { margin: 5px; width: 20px; height: 20px; padding: 10px; color: #333; text-align: center; border: 1px solid #333; border-radius: 50%; /* 移除移动端点击默认高亮 */ -webkit-tap-highlight-color: transparent; } .hvr-ripple-out:hover { color: #39CCCC; border-color: #39CCCC; } @-webkit-keyframes hvr-ripple-out { 100% { top: -12px; right: -12px; bottom: -12px; left: -12px; opacity: 0; } } @keyframes hvr-ripple-out { 100% { top: -12px; right: -12px; bottom: -12px; left: -12px; opacity: 0; } } .hvr-ripple-out { display: inline-block; vertical-align: middle; -webkit-backface-visibility: hidden; backface-visibility: hidden; -moz-osx-font-smoothing: grayscale; position: relative; } .hvr-ripple-out:before { content: ''; position: absolute; border: rgba(0, 0, 0, 0.0) solid 2px; border-radius: 50%; top: 0; right: 0; bottom: 0; left: 0; animation-duration: 1s; } /* 同时支持hover/focus/active和自定义touch-active类,确保移动端触发动画 */ .hvr-ripple-out:hover:before, .hvr-ripple-out:focus:before, .hvr-ripple-out:active:before, .hvr-ripple-out.touch-active:before { animation-name: hvr-ripple-out; border-color: #39CCCC; animation-fill-mode: forwards; } .fill { background-color: #39CCCC; color: #fff; border: 1px solid #fff; } .fill:hover { color: #fff; border: 1px solid #fff; } </style> <script> // 用指针事件统一处理鼠标/触摸/笔输入,替代click和tap $(document).on('pointerdown', '.hvr-ripple-out', function(e) { const $el = $(this); // 直接切换类,替代克隆元素的冗余操作 $el.toggleClass('fill'); // 辅助移动端触发涟漪动画(部分浏览器需要) $el.addClass('touch-active'); setTimeout(() => $el.removeClass('touch-active'), 1000); // 和动画时长保持一致 }); // 阻止触摸默认行为,避免冲突 $(document).on('touchstart', '.hvr-ripple-out', function(e) { e.preventDefault(); }); </script>
关键优化说明
- 指针事件(
pointerdown):W3C标准事件,统一处理所有指针交互(鼠标、触摸、笔),不需要额外库,兼容性覆盖现代桌面/移动端浏览器。 - 视口元标签:必须添加,确保移动端浏览器正确识别设备宽度,正常触发
:active伪类。 - 移除元素克隆:用
toggleClass直接修改状态,保持DOM结构稳定,减少性能开销。 - 自定义
touch-active类:针对部分移动端浏览器无法触发:active的问题,通过JS动态添加类来触发涟漪动画。 - 移除默认高亮:
-webkit-tap-highlight-color: transparent消除移动端点击时的默认灰色高亮,提升视觉一致性。
这样修改后,无论是桌面端点击还是移动端触摸,涟漪效果都能正常触发,状态切换逻辑也更清晰稳定~
内容的提问来源于stack exchange,提问作者crffty
相关产品推荐
相关产品推荐

