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

如何实现弹出菜单箭头在hover与点击时的平滑左右切换

解决方案

问题分析

点击时箭头跳动的核心原因:

  • hover状态的transform: rotate(180deg)与点击后设置的transform: none产生冲突,触发不必要的过渡动画
  • 切换图标类(bi-chevron-left/bi-chevron-right)时,CSS过渡效果仍在生效,导致图标切换过程中出现旋转跳动

代码修改

1. 更新CSS

添加禁用过渡的工具类,同时调整hover和菜单激活状态的样式优先级:

#daily-muster-statuses-menu {
    opacity: 0;
    visibility: hidden;
    /* 给菜单添加过渡,优化显示/隐藏流畅度 */
    transition: opacity 0.1s linear, visibility 0.1s linear;
}

#daily-muster-statuses:hover > #daily-muster-statuses-menu,
#daily-muster-statuses-menu.show {
    opacity: 1;
    visibility: visible;
}

.dd-icon {
    bottom: 2.5px;
    left: 12px;
    opacity: 1;
    transition: transform 0.1s linear;
}

/* 仅菜单未激活时,hover触发箭头旋转 */
.outer-menu-item:not(.menu-active):hover .dd-icon {
    transform: rotate(180deg);
}

/* 临时禁用过渡的工具类 */
.dd-icon.no-transition {
    transition: none !important;
}

/* 菜单激活时,强制箭头保持指向右侧,覆盖hover效果 */
.menu-active .dd-icon {
    transform: none !important;
}

2. 修改JavaScript

在切换图标时临时禁用过渡,同时给触发元素添加状态类控制hover效果:

const musterStatusesRollup = $('#daily-muster-statuses-rollup');
const musterStatusesMenu = $('#daily-muster-statuses-menu');
const musterStatusesChevron = musterStatusesRollup.find('.dd-icon');
const outerMenuItem = musterStatusesRollup.find('.outer-menu-item');

let menuIsShown = false;

const hideDailyMusterStatusesMenu = () => {
    // 临时禁用过渡,切换图标类
    musterStatusesChevron.addClass('no-transition');
    musterStatusesChevron.removeClass('bi-chevron-right').addClass('bi-chevron-left');
    // 强制浏览器重绘后恢复过渡
    void musterStatusesChevron[0].offsetWidth;
    musterStatusesChevron.removeClass('no-transition');
    
    musterStatusesMenu.removeClass('show');
    outerMenuItem.removeClass('menu-active');
    return (menuIsShown = false);
};

const initialiseDailyMusterStatusesMenu = () => {
    musterStatusesRollup.on('click', e => {
        e.stopPropagation();
        
        if (menuIsShown) {
            return hideDailyMusterStatusesMenu();
        }

        // 临时禁用过渡,切换图标类
        musterStatusesChevron.addClass('no-transition');
        musterStatusesChevron.removeClass('bi-chevron-left').addClass('bi-chevron-right');
        void musterStatusesChevron[0].offsetWidth;
        musterStatusesChevron.removeClass('no-transition');
        
        musterStatusesMenu.addClass('show');
        outerMenuItem.addClass('menu-active');
        menuIsShown = true;

        $(document).one('click', hideDailyMusterStatusesMenu);
    });
};

关键说明

  • 使用no-transition类在图标切换瞬间禁用过渡,通过void element.offsetWidth强制浏览器重绘,避免过渡动画干扰图标切换
  • 添加menu-active类到触发元素,控制hover效果仅在菜单未激活时生效,解决hover与点击状态的样式冲突
  • 统一菜单显示/隐藏的触发条件,同时给菜单添加过渡效果,提升交互流畅度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:25:56