You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 18:05:34