【问题标题】:How can I tell within a Shiny app if the navbar is collapsed?如何在 Shiny 应用程序中判断导航栏是否折叠?
【发布时间】:2021-06-14 23:09:42
【问题描述】:

我有一个使用navbarPage() 结构的闪亮应用程序,该结构具有固定位置、可折叠的导航栏。我希望能够在我的服务器端代码中检查导航栏当前是否折叠。我正在使用 Bootstrap 4。

以下是一些示例代码,用于说明应用设置,以及服务器端的一些伪代码:

library(shiny)
library(bslib)

ui <- navbarPage(
  title = "An app",
  # Specifying Bootstrap 4, as solutions may differ
  # by Bootstrap version
  theme = bs_theme(version = "4"),
  tabPanel(title = "A tab",
           position = "fixed-top",
           collapsible = TRUE,
           "Some content")
  
)

server <- function(input, output, session) {
  # PSEUDO-CODE:
  # if (navbar_is_collapsed) {
  #   do something
  # }
  
}

shinyApp(ui, server)

reprex package (v2.0.0) 于 2021-06-15 创建

如何在server 内查看导航栏是否折叠?

【问题讨论】:

    标签: r twitter-bootstrap shiny


    【解决方案1】:

    首先,参数positioncollapsiblenavbarPage不是 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 应该以不同方式呈现。这给了我们正在寻找的钩子:

    1. 使用 Javascript 获取 实际 断点(事实证明,尽管有文档,但在我的系统上,菜单在宽度低于 576px 时折叠起来)。
    2. 当屏幕通过resize 事件调整大小时通知闪亮。为方便起见,我们报告我们当前低于哪个断点)。关键断点是最小的(即位置0处的断点)。
    3. 然后我们可以收听这个新创建的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)
    

    您可以通过运行应用程序并调整窗口大小来测试,您会看到菜单被折叠后,文本框也会相应更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 1970-01-01
      • 2016-04-01
      • 2021-08-23
      相关资源
      最近更新 更多