首先,参数position 和collapsible 是navbarPage 和不是 tabPanel 的一部分。
如果您阅读?navbarPage 的文档,它会在菜单折叠时给出第一个提示:
collapsible: ‘TRUE’ to automatically collapse the navigation elements
into a menu when the width of the browser is less than 940
pixels (useful for viewing on smaller touchscreen device)
进一步查看bootstrap.css,我们看到定义了@media 规则以定义断点,此时HTML 应该以不同方式呈现。这给了我们正在寻找的钩子:
- 使用 Javascript 获取 实际 断点(事实证明,尽管有文档,但在我的系统上,菜单在宽度低于
576px 时折叠起来)。
- 当屏幕通过
resize 事件调整大小时通知闪亮。为方便起见,我们报告我们当前低于哪个断点)。关键断点是最小的(即位置0处的断点)。
- 然后我们可以收听这个新创建的
input 并做出相应的反应。
library(shiny)
library(bslib)
js <- HTML("
(function() {
function getAllMediaBreakpoints() {
var bt_css = $.grep(document.styleSheets, (css) => /bootstrap/.test(css.href))[0];
var media_rules = $.grep(bt_css.cssRules, (rule) => rule instanceof CSSMediaRule &
/min-width/.test(rule.conditionText));
var widths = $.map(media_rules, (rule) => parseInt(rule.conditionText.replace(/.*:\\s?(\\d+)px.*/, '$1')));
return $.grep(widths, (width, index) => index == $.inArray(width, widths));
}
function getBreakpoint(all_breakpoints) {
var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
for (var i = 0; i < all_breakpoints.length; i++) {
var lim = all_breakpoints[i];
if (width < lim) {
return(i)
}
}
return(i);
}
const breakpoints = getAllMediaBreakpoints();
$(document).one('shiny:connected', () => Shiny.setInputValue('breakpoint', getBreakpoint(breakpoints)));
$(window).on('resize', () => Shiny.setInputValue('breakpoint', getBreakpoint(breakpoints)))
})();")
ui <- navbarPage(
title = "An app",
theme = bs_theme(version = "4"),
# position = "fixed-top", # removed to not hide the content below the navbar
selected = "A tab", # this argument bwlongs to navbarPage and not tabPanel
collapsible = TRUE, # this argument bwlongs to navbarPage and not tabPanel
tags$head(tags$script(js)), # include our JavaScript
tabPanel(title = "A tab",
h3("Title"),
verbatimTextOutput("collapsed")))
server <- function(input, output, session) {
navbar_is_collapsed <- reactive(input$breakpoint == 0)
output$collapsed <- renderPrint(paste("Collapsed:", navbar_is_collapsed()))
}
shinyApp(ui, server)
您可以通过运行应用程序并调整窗口大小来测试,您会看到菜单被折叠后,文本框也会相应更新。