如何让showNotification在可滚动DT数据表的点击行附近正确弹出?
解决DT表格滚动后通知位置偏移的问题
问题出在你使用的e.pageX/e.pageY是相对于整个文档的坐标,当DT表格的tbody滚动时,这个坐标没有考虑表格自身的滚动偏移,导致通知位置和点击行脱节。我们可以通过获取被点击行在视口中的位置来修正这个问题:
修改后的完整代码
library(shiny) library(DT) ui <- fluidPage( tags$script(HTML(" $(document).on('click', 'table tbody tr', function(e) { // 获取被点击行的视口位置信息 const rect = this.getBoundingClientRect(); // 把通知定位在行的右侧,避免被表格遮挡 const x = rect.right + 10; const y = rect.top; Shiny.setInputValue('click_coords', {x: x, y: y}, {priority: 'event'}); }); Shiny.addCustomMessageHandler('adjustNotifPosition', function(message) { $('.shiny-notification').css({ 'top': message.y + 'px', 'left': message.x + 'px', // 确保通知在最上层,不被其他元素遮挡 'z-index': 9999 }); }); ")), tags$style(HTML(" .shiny-notification { width: 250px; height: auto; position: fixed; background-color: #FFD700; /* Gold background */ color: black; font-weight: bold; border: 2px solid black; border-radius: 15px; padding: 10px; text-align: center; margin: 0; /* 移除默认margin,避免位置偏移 */ } ")), DT::dataTableOutput('summary_table') ) server <- function(input, output, session) { data <- data.frame( ID = 1:1000, Value = rnorm(1000) ) output$summary_table <- DT::renderDataTable({ datatable(data, selection = 'single') }, server = FALSE) observeEvent(input$click_coords, { if (!is.null(input$summary_table_rows_selected)) { selected_row <- input$summary_table_rows_selected # 先移除旧通知,避免重复显示 removeNotification(id = "notif") # 显示通知 showNotification( paste("You selected row number", selected_row), closeButton = TRUE, duration = NULL, action = actionButton("go_to_figure_tables", "Go to Figure Tables"), id = "notif" ) x_coord <- input$click_coords$x y_coord <- input$click_coords$y # 调整通知位置 session$sendCustomMessage('adjustNotifPosition', list(x = x_coord, y = y_coord)) } }) observeEvent(input$go_to_figure_tables, { # 处理按钮点击逻辑 print("Go to Figure Tables button clicked!") removeNotification(id = "notif") }) } shinyApp(ui, server)
关键修改说明
- 坐标获取方式:用
this.getBoundingClientRect()获取被点击行在当前视口中的位置,这个值不受表格滚动影响,能精准定位行的位置。我们把通知设置在行的右侧(rect.right +10),避免被表格本身遮挡。 - 通知样式优化:移除默认的
margin,添加z-index:9999确保通知显示在最上层,不会被其他UI元素覆盖。 - 重复通知处理:在显示新通知前先移除旧通知,避免同一位置堆叠多个通知。
这样修改后,无论表格怎么滚动,通知都会精准显示在被点击行的右侧位置。
内容的提问来源于stack exchange,提问作者Majid Zaremehrjardy
相关产品推荐
相关产品推荐

