如何用JavaScript实现与CSS效果一致的Table表头Hover动画Tooltip
问题描述
已尝试参考相关hover动画方案,但仍未解决:需要为表格中除第一个<th>外的表头元素,通过JavaScript的mouseover/mouseout事件实现与现有CSS版Tooltip完全一致的动画效果。目前已实现Tooltip的显示隐藏,但无法复现原有的过渡动画。
现有CSS版Tooltip的核心动画逻辑:
- 内容容器从透明到显示,配合延迟过渡
- 文本容器从横向缩放为0到1
- 内部内容从下方平移进入
当前JS版仅能实现基础显示隐藏,代码如下:
现有JS版Tooltip容器HTML
<div id="toolTipContainer" style="z-index:100; font-size: 1.2em; color: #D93742; border-style: solid; border-width: 2px; width: 200px; height: 80px; position:absolute; display:none;"> <span class="tooltiptable-content"><span class="tooltiptable-text"><span class="tooltiptable-inner"> If you require access to modules, <br/> please contact to your system administrator </span></span></span> </div>
现有JS逻辑
$(document).ready(function () { $('th').mouseover(function () { if ($(this).index() === 0) { return; } else { const top = $(this).offset().top - 82; const left = $(this).offset().left; $('#toolTipContainer').css({'top': top, 'left': left, 'width': $(this).width()}); $('.tooltiptable-content').css({'width': $(this).width()}); //show tool tips $('#toolTipContainer').show(); } }); $('th').mouseout(function () { $("#toolTipContainer").hide(); }); $('#toolTipContainer').mouseover(function () { $('#toolTipContainer').show(); }); $('#toolTipContainer').mouseout(function () { $('#toolTipContainer').hide(); }); });
解决方案
核心思路:用CSS类切换替代show()/hide(),把原CSS中:hover触发的动画逻辑,转移到自定义的.active类上,再通过JS控制这个类的添加/移除,同时保留原过渡动画的延迟和变换逻辑。
步骤1:编写适配JS控制的CSS样式
把原CSS的tooltip动画逻辑迁移到tooltiptable-*类,并用.active类触发动画:
/* 重置容器初始状态,去掉内联display:none */ #toolTipContainer { position: absolute; z-index: 100; font-size: 1.2em; color: #D93742; border-style: solid; border-width: 2px; width: 200px; height: 80px; /* 初始隐藏用opacity和transform,不是display:none,保证过渡生效 */ opacity: 0; pointer-events: none; } /* Tooltip内容容器 */ .tooltiptable-content { position: absolute; z-index: 9999; left: 50%; bottom: 100%; font-size: 18px; line-height: 1.4; text-align: center; font-weight: 400; color: #D93742; background: transparent; opacity: 0; transform: translateX(-50%); margin-bottom: 5px; cursor: default; pointer-events: none; font-family: inherit; /* 保留原过渡逻辑 */ transition: opacity 0.3s 0.3s; } /* 激活状态:显示内容容器 */ #toolTipContainer.active .tooltiptable-content { opacity: 1; pointer-events: auto; transition-delay: 0s; } .tooltiptable-content span { display: block; } .tooltiptable-text { border-bottom: 10px solid #D93742; overflow: hidden; transform: scale3d(0,1,1); transition: transform 0.3s 0.3s; } /* 激活状态:横向展开文本容器 */ #toolTipContainer.active .tooltiptable-text { transition-delay: 0s; transform: scale3d(1,1,1); } .tooltiptable-inner { background: rgba(85,61,61,0.95); padding: 5px; transform: translate3d(0,100%,0); transition: transform 0.3s; color: white; } /* 激活状态:平移内部内容 */ #toolTipContainer.active .tooltiptable-inner { transition-delay: 0.3s; transform: translate3d(0,0,0); } /* 箭头样式 */ .tooltiptable-content::after { content: ''; bottom: -20px; left: 50%; border: solid transparent; height: 0; width: 0; position: absolute; pointer-events: none; border-color: transparent; border-top-color: #D93742; border-width: 10px; margin-left: -10px; }
步骤2:修改Tooltip容器HTML
去掉内联的display:none,用CSS控制初始隐藏:
<div id="toolTipContainer"> <span class="tooltiptable-content"> <span class="tooltiptable-text"> <span class="tooltiptable-inner"> If you require access to modules, <br/> please contact to your system administrator </span> </span> </span> </div>
步骤3:修改JS逻辑,用类切换替代show/hide
$(document).ready(function () { const $tooltip = $('#toolTipContainer'); // 表头鼠标移入 $('th').mouseover(function () { if ($(this).index() === 0) return; const $th = $(this); const top = $th.offset().top - 82; const left = $th.offset().left; const thWidth = $th.width(); // 设置位置和宽度 $tooltip.css({ 'top': top, 'left': left, 'width': thWidth }); $('.tooltiptable-content').css({'width': thWidth}); // 添加激活类触发动画 $tooltip.addClass('active'); }); // 表头鼠标移出 $('th').mouseout(function () { if ($(this).index() === 0) return; // 移除激活类触发退出动画 $tooltip.removeClass('active'); }); // Tooltip自身的鼠标移入移出,防止误隐藏 $tooltip.mouseover(function () { $tooltip.addClass('active'); }); $tooltip.mouseout(function () { $tooltip.removeClass('active'); }); });
关键说明
- 为什么不用
show()/hide()?因为display:none会中断CSS过渡动画,改用opacity和pointer-events控制显示隐藏,保证过渡可以正常执行。 - 保留原CSS的过渡延迟逻辑:
.tooltiptable-content的显示延迟、.tooltiptable-inner的平移延迟,完全复现原动画的时序。 - 用
.active类统一控制所有动画状态,JS只负责切换类,动画逻辑仍由CSS处理,保证性能和一致性。
内容的提问来源于stack exchange,提问作者Samet Dağ
相关产品推荐
相关产品推荐

