You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用原生JavaScript替代jQuery slideToggle()时的内边距动态获取问题

原生JS实现带padding平滑过渡的slideToggle效果

关键解决方案:提前获取计算样式+CSS类切换

1. 正确获取Tailwind定义的初始padding值

无需硬编码,利用getComputedStyle直接获取元素的计算后样式,这会自动读取Tailwind类定义的padding值,不管元素初始状态是展开还是收起:

const menu = document.querySelector('.your-menu');
// 获取初始padding的四个方向计算值
const computedStyle = getComputedStyle(menu);
const initialPadding = {
  top: computedStyle.paddingTop,
  right: computedStyle.paddingRight,
  bottom: computedStyle.paddingBottom,
  left: computedStyle.paddingLeft
};

如果元素初始是收起状态(已设height:0或padding:0),可以用临时克隆元素的方法获取真实初始值:

const clone = menu.cloneNode(true);
// 隐藏克隆元素但保留样式计算
clone.style.cssText = 'visibility:hidden; position:absolute; height:auto; padding:;';
document.body.appendChild(clone);
const cloneStyle = getComputedStyle(clone);
const initialPadding = {
  top: cloneStyle.paddingTop,
  right: cloneStyle.paddingRight,
  bottom: cloneStyle.paddingBottom,
  left: cloneStyle.paddingLeft
};
document.body.removeChild(clone);

2. 用CSS类控制过渡动画

避免JS直接操作行内样式打断动画,把过渡逻辑交给CSS:

.your-menu {
  transition: height 0.3s ease, padding 0.3s ease;
  overflow: hidden;
}
/* 收起状态的样式 */
.menu-collapsed {
  height: 0;
  padding-block: 0;
  padding-inline: 0;
}

3. 实现toggle逻辑

处理初始状态,切换时通过类和行内样式配合实现平滑动画:

// 标记当前状态:初始是否展开(根据是否有收起类判断)
let isExpanded = !menu.classList.contains('menu-collapsed');

// 初始化元素高度:展开状态下先设置为真实内容高度,避免动画异常
if (isExpanded) {
  menu.style.height = `${menu.scrollHeight}px`;
} else {
  menu.style.height = '0';
}

function toggleMenu() {
  if (isExpanded) {
    // 收起:设置height为0,添加收起类
    menu.style.height = '0';
    menu.classList.add('menu-collapsed');
  } else {
    // 展开:先移除收起类,恢复padding,再设置为内容真实高度
    menu.classList.remove('menu-collapsed');
    menu.style.paddingTop = initialPadding.top;
    menu.style.paddingRight = initialPadding.right;
    menu.style.paddingBottom = initialPadding.bottom;
    menu.style.paddingLeft = initialPadding.left;
    // 强制重绘后设置高度,避免动画跳变
    requestAnimationFrame(() => {
      menu.style.height = `${menu.scrollHeight}px`;
    });
  }
  isExpanded = !isExpanded;

  // 动画结束后重置height为auto,适配动态内容变化
  menu.addEventListener('transitionend', function onTransitionEnd() {
    if (isExpanded) {
      menu.style.height = 'auto';
    }
    menu.removeEventListener('transitionend', onTransitionEnd);
  }, { once: true });
}

常见问题修复

  • 移除行内样式/用revert-layer会触发即时重绘,打断过渡动画,因此必须通过提前缓存初始值+类切换的方式实现;
  • 克隆元素时必须挂载到DOM中才能获取正确的计算样式,否则getComputedStyle会返回默认值而非Tailwind定义的样式;
  • 动画结束后设置height:auto,确保菜单内容动态变化时,展开状态能自适应高度。

内容的提问来源于stack exchange,提问作者Telexx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:39:51