Shiny应用中如何为多个表格添加顶底双向水平滚动条
问题原因
代码不生效是三个jQuery和DOM逻辑错误导致的:
- ID重复违规:HTML标准要求页面内ID全局唯一,你给三个表格的外层包裹层都设置了
id="scrolldiv",调用$('#scrolldiv')时永远只会选中第一个匹配元素(也就是table1的外层容器),table2、table3的滚动逻辑完全没有被初始化。 - 作用域混乱:初始化doubleScroll时用全局选择器
$('table')匹配内容元素,会抓取页面所有表格,不是当前要处理的单个表格,会导致DOM嵌套结构错乱。 - 重复绑定包裹逻辑:任意一个表格触发
shiny:value事件时,你都会给所有三个表格重复套一层外层div,多次渲染后DOM结构完全不符合插件要求。
修正代码
只需要替换你原有的JS代码即可,其余CSS、R端逻辑不需要改动:
library(formattable) library(shiny) js <- " $(document).ready(function(){ // 给三个输出表格统一绑定渲染完成事件 $('#table1, #table2, #table3').on('shiny:value', function(e){ const $currentTable = $(this).find('table'); setTimeout(function(){ // 只给当前渲染完成的表格套滚动容器,用类名不用固定ID $currentTable.wrap('<div class=\"scroll-wrapper\"></div>'); // 只在当前表格的父容器上初始化滚动插件,限定查找范围 $currentTable.parent('.scroll-wrapper').doubleScroll({ contentElement: $currentTable, scrollCss: { 'overflow-x': 'scroll', 'overflow-y': 'hidden' }, contentCss: { 'overflow-x': 'scroll', 'overflow-y': 'hidden' }, resetOnWindowResize: true }); setTimeout(function(){$(window).resize();}, 100); }, 0); }); }); " CSS <- " .doubleScroll-scroll-wrapper { clear: both; } " ui <- fluidPage( tags$head( tags$script(src = "jquery.doubleScroll.js"), tags$script(HTML(js)), tags$style(HTML(CSS)) ), fluidRow(column(2,formattableOutput("table1"))), fluidRow(column(2,formattableOutput("table2"))), fluidRow(column(2,formattableOutput("table3"))) ) server <- function(input, output) { output$table1 <- renderFormattable({ formattable(mtcars) }) output$table2 <- renderFormattable({ formattable(mtcars) }) output$table3 <- renderFormattable({ formattable(mtcars) }) } shinyApp(ui = ui, server = server)
效果说明
修正后三个表格都会独立初始化顶部+底部双向水平滚动,不会出现DOM结构错乱、部分表格不生效的问题:
- 用类名
scroll-wrapper替代重复ID,符合HTML规范 - 每次事件触发只操作当前渲染完成的单个表格,不会重复嵌套DOM
- 插件初始化时明确指定当前表格为内容元素,不会跨表格匹配元素
内容的提问来源于stack exchange,提问作者Kate Chalmers
相关产品推荐
相关产品推荐

