bslib 0.5.1中page_navbar嵌套nav_menu失效问题求助
问题原因
bslib 0.5.1基于Bootstrap 5构建,默认下拉菜单的data-bs-auto-close属性为true,点击子菜单时事件会向上冒泡,触发父下拉菜单的关闭逻辑,导致嵌套菜单无法正常展开。
解决方法
方法1:利用Bootstrap下拉菜单属性(推荐)
给父级nav_menu手动添加data-bs-auto-close="outside"属性,该属性设置后,只有点击下拉菜单外部时才会关闭父菜单,点击内部子菜单不会触发关闭。
修改后的代码:
library(bslib) library(shiny) shinyApp( page_navbar( title = "Nested nav_menu attempt", id = "nav", # 手动构建父级下拉菜单,添加auto-close属性 tags$li(class = "nav-item dropdown", tags$a(class = "nav-link dropdown-toggle", href = "#", role = "button", `data-bs-toggle` = "dropdown", `data-bs-auto-close` = "outside", `aria-expanded` = "false", "Parent nav_menu"), tags$ul(class = "dropdown-menu", tags$li(nav_panel("First item", "first item text")), tags$li( nav_menu(title = "Nested nav_menu", nav_panel("Second nested item", "second item text"), nav_panel("Third nested item", "third item text")) ) ) ), sidebar = sidebar() ), server = function(...) { # no server logic required } )
方法2:自定义JavaScript阻止事件冒泡
通过监听子菜单的点击事件,阻止事件向上传递到父菜单,避免触发父菜单的关闭逻辑。
修改后的代码:
library(bslib) library(shiny) shinyApp( page_navbar( title = "Nested nav_menu attempt", id = "nav", nav_menu( title = "Parent nav_menu", value = "First item", nav_panel("First item", "first item text"), nav_menu(title = "Nested nav_menu", nav_panel("Second nested item", "second item text"), nav_panel("Third nested item", "third item text")) ), sidebar = sidebar(), # 添加自定义脚本阻止事件冒泡 tags$script(HTML(" document.addEventListener('click', function(e) { // 定位到子菜单的下拉触发按钮 if (e.target.closest('.dropdown-menu .dropdown-toggle')) { e.stopPropagation(); } }); ")) ), server = function(...) { # no server logic required } )
替代方案:使用navbarMenu作为父容器
尝试用shiny::navbarMenu替代bslib::nav_menu作为父容器,部分场景下可规避交互冲突:
library(bslib) library(shiny) shinyApp( page_navbar( title = "Nested nav_menu attempt", id = "nav", navbarMenu( title = "Parent nav_menu", tabPanel("First item", "first item text"), nav_menu(title = "Nested nav_menu", nav_panel("Second nested item", "second item text"), nav_panel("Third nested item", "third item text")) ), sidebar = sidebar() ), server = function(...) { # no server logic required } )
内容的提问来源于stack exchange,提问作者Michaël
相关产品推荐
相关产品推荐

