shinyjs::show启用动画后无法显示datatable?求排查及替代方案
问题分析与解决办法
这个问题不是shinyjs的bug,是shinyjs的动画逻辑和DT表格的动态渲染机制冲突导致的:
shinyjs的show(anim = TRUE)是通过逐步修改元素的height和opacity实现动画,但DT表格在刚触发显示时还没完成渲染,此时元素的实际高度为0,动画执行完毕后元素会停留在高度0的状态,所以只看到轻微位移,表格内容无法显示。
除了禁用动画,有两种可行的解决办法:
办法1:延迟触发动画,给DT留足渲染时间
通过shinyjs::delay()延迟执行show动画,让DT先完成表格渲染,再启动动画:
library(shiny) library(shinyjs) library(DT) ui <- fluidPage( useShinyjs(), "Bli", checkboxInput("ch","Display datatable"), DTOutput("dt"), "Blub" ) server <- function(input, output, session) { observeEvent(input$ch,{ if(input$ch){ # 延迟100ms执行动画,确保DT已渲染完成 delay(100, { show("dt", anim = TRUE) }) } else { hide("dt") } }) output$dt <- renderDT(datatable(iris)) } shinyApp(ui, server)
办法2:自定义CSS动画,替代shinyjs的内置动画
自己通过CSS过渡动画控制容器的显示隐藏,避开shinyjs动画和DT的冲突:
library(shiny) library(shinyjs) library(DT) ui <- fluidPage( useShinyjs(), # 自定义CSS动画样式 tags$style( ".dt-wrapper { max-height: 0; overflow: hidden; transition: max-height 0.5s ease; } .dt-wrapper.active { max-height: 1000px; /* 设置足够大的值覆盖表格高度 */ }" ), "Bli", checkboxInput("ch","Display datatable"), # 将DT放在自定义容器中 div(class = "dt-wrapper", DTOutput("dt")), "Blub" ) server <- function(input, output, session) { observeEvent(input$ch,{ if(input$ch){ addClass("dt-wrapper", "active") } else { removeClass("dt-wrapper", "active") } }) output$dt <- renderDT(datatable(iris)) } shinyApp(ui, server)
这种方式的动画更稳定,还能自定义动画时长和效果。
内容的提问来源于stack exchange,提问作者Noskario
相关产品推荐
相关产品推荐

