Flexdashboard侧边栏pickerInput点击时滚动位置异常问题求助
问题:Flexdashboard侧边栏pickerInput点击后滚动位置重置
之前通过JS修改pickerInput样式解决长内容截断问题,但当侧边栏出现滚动条时,滚动后点击目标pickerInput,侧边栏会跳回初始位置,小屏幕多筛选器场景下体验极差。
可复现代码
--- title: "TEST" runtime: shiny output: flexdashboard::flex_dashboard: orientation: rows ---
library(dplyr) library(shiny) library(DT) library(shinyWidgets) Name <- c("LONNGGGGGGGGGGGGGGG TEXXTTTTTTTTTTTTTTTTTT", "Bill", "Maria", "Ben", "Tina") Age <- c(23, 41, 32, 58, 26) df <- data.frame(Name, Age)
$(document).ready(function(){ $('#name1').on('show.bs.select', function() { $(" .sidebar").css("overflow", "visible"); $(" .sidebar").css("z-index", "10000"); }).on('hide.bs.select', function() { $(" .sidebar").css("overflow-y", "auto"); }); });
Filters
pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name, multiple = TRUE) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name1", label = "Third Filter", choices = df$Name, selected = df$Name, multiple = TRUE, options = list(`actions-box` = TRUE, `selected-text-format` = paste0("count > ", length(unique(df$Name, split=";")) -1),`count-selected-text` = "All")) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name) pickerInput( inputId = "name", label = "test", choices = df$Name, selected = df$Name)
TEST
Row
filtered_data <- reactive ({ req(input$name) df %>% filter(Name %in% input$name) }) renderDataTable(filtered_data(), class = 'cell-border stripe', extensions = 'Buttons', rownames = FALSE, options = list( columnDefs = list(list(className = 'dt-center',width = '100px', targets = "_all"))),fillContainer=TRUE)
解决方案
修改原JS代码,在修改侧边栏overflow属性前后保存并恢复滚动位置,避免浏览器布局重计算导致的滚动重置:
$(document).ready(function(){ $('#name1').on('show.bs.select', function() { // 保存当前侧边栏滚动位置 const scrollPos = $(".sidebar").scrollTop(); // 修改样式时设置相对定位,确保滚动上下文稳定 $(".sidebar").css({ "overflow": "visible", "z-index": "10000", "position": "relative" }); // 恢复滚动位置 $(".sidebar").scrollTop(scrollPos); }).on('hide.bs.select', function() { // 关闭时同样保存并恢复滚动位置 const scrollPos = $(".sidebar").scrollTop(); $(".sidebar").css({ "overflow-y": "auto", "position": "" // 恢复默认定位 }); $(".sidebar").scrollTop(scrollPos); }); });
原理说明
原代码修改overflow时,浏览器会触发元素重排,导致侧边栏滚动位置被重置为0。新方案通过:
- 预存滚动位置:在修改样式前记录当前滚动距离
- 稳定滚动上下文:设置
position: relative避免布局计算干扰滚动状态 - 恢复滚动位置:修改样式后立即把滚动条放回原位,从视觉上消除跳转感
如果需要对所有pickerInput生效,可将选择器从#name1改为.selectpicker(shinyWidgets生成的pickerInput会带有这个类),实现全局适配。
内容的提问来源于stack exchange,提问作者user3249770
相关产品推荐
相关产品推荐

