更新: 使用 Dean Attali (link) 的包 shinyjs,我编写了一个帮助函数,您可以从 R 调用它来创建和运行一个 jQuery 函数来修改 CSS 元素基于来自 R 语法的输入的给定对象(或选择器,通常)。当标签更改时,您可以使用它来修改<body>的CSS。
这解决了我之前建议的问题 - 现在不需要切换 body 的类,当<body> 的所有样式类都被关闭时,有时会导致闪烁。
下面是工作示例:
library(shiny)
library(shinyjs)
## Modify the CSS style of a given selector
modifyStyle <- function(selector, ...) {
values <- as.list(substitute(list(...)))[-1L]
parameters <- names(values)
args <- Map(function(p, v) paste0("'", p,"': '", v,"'"), parameters, values)
jsc <- paste0("$('",selector,"').css({", paste(args, collapse = ", "),"});")
shinyjs::runjs(code = jsc)
}
# UI for the app
user <- shinyUI(
navbarPage(title = "", id = "navtab",
header = div(useShinyjs()),
tabPanel("Home Page",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
)
)
# Server for the app
serv <- shinyServer(function(input, output, session) {
observeEvent(input$navtab, {
currentTab <- input$navtab # Name of the current tab
if (currentTab == "Home Page") {
modifyStyle("body", background = "blue", color = "white", 'font-family' = "Arial")
}
if (currentTab == "Glossary") {
modifyStyle("body", background = "red", color = "white", 'font-family' = "Arial")
}
})
})
shinyApp(user, serv)
我自己是 CSS 新手,但您的问题似乎可以通过稍微更改 CSS 标签来解决。将#one 更改为.one 并删除括号前的body 将使CSS 样式应用于one 类的div。
使用选择器#one 将更改 id 而非类为one 的 div 的 CSS 样式。这是a guide on w3shools.com 的链接,它解释了 CSS 语法中不同选择器的使用。
其他一些注意事项:
- 你也可以使用
tags$head来组织你的风格标签
一个地方,而不是在代码周围散布它们。 (不过,这取决于个人喜好。)
- 您可以将
class 参数传递给 tabPanel 以设置其 CSS 类 - 这样就无需内部 div 来设置类。
修改后的示例代码:
library(shiny)
user <- shinyUI(navbarPage(
tags$head(
tags$style(HTML(".one {background-color: blue; color: white; font-family: Arial}")),
tags$style(HTML(".two {background-color: red; color: white; font-family: Arial}"))
),
tabPanel("Home Page", class = "one",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary", class = "two",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
))
serv <- shinyServer(function(input, output) {})
shinyApp(user, serv)
就像我提到的,我是 CSS 新手,所以我不能 100% 确定这是否是您正在寻找的输出。
EDIT2:这是一个解决方案,使用包shinyjs 在所选选项卡更改时更新<body> 的类。 (请注意,要使用shinyjs 中的功能,您需要在您的ui 中包含useShinyjs()。)
我们的想法是通过将navbarPage 的ID 设置为navtab,使navbarPage 返回input$navtab 中当前处于活动状态的选项卡的名称。然后我们可以使用 shinyjs 包中的 toggleClass 函数来动态更改 <body> 的类,从而应用适当的 CSS 样式。
这并不完美,因为类更改仅在服务器收到选项卡已更改的通知后发生,这有时会导致背景在更改之前闪烁。它可能会有点烦人。我怀疑更好的解决方案是在单击链接以更改选项卡时使用 javascript 更改 <body> 类,但我不知道如何使用 Shiny 来做到这一点。
代码如下:
library(shiny)
library(shinyjs)
user <- shinyUI(
navbarPage(title = "", id = "navtab",
header = tags$head(
useShinyjs(),
tags$style(HTML(".one {background: blue; color: white; font-family: Arial}")),
tags$style(HTML(".two {background: red; color: white; font-family: Arial}"))
),
tabPanel("Home Page",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
)
)
serv <- shinyServer(function(input, output, session) {
observeEvent(input$navtab, {
shinyjs::toggleClass(selector = "body", class = "one",
condition = (input$navtab == "Home Page"))
shinyjs::toggleClass(selector = "body", class = "two",
condition = (input$navtab == "Glossary"))
})
})
shinyApp(user, serv)