Shiny中如何通过Tab键在shinyalert弹窗输入字段间切换
问题原因
shinyalert 基于 sweetalert2 实现,默认内置了焦点管控逻辑,仅允许 Tab 键在弹窗自带的确认、取消按钮间循环切换,自定义插入的 HTML 表单输入框不会被纳入默认的焦点遍历列表,因此按 Tab 无法切换到自定义输入框。另外原代码中三个输入框使用了重复的id属性,不符合HTML规范,也会干扰焦点识别。
修复方案
- 先给三个文本输入框设置唯一的
id属性,避免DOM识别异常 - 在自定义HTML中嵌入一段原生JavaScript,监听弹窗内的键盘按下事件,手动实现Tab/Shift+Tab的焦点切换逻辑,不需要额外引入其他R包。
完整可运行代码如下:
library(shiny) library(shinyalert) ui <- fluidPage( useShinyalert() ) server <- function(input, output) { shinyalert( title = " ", type = "info", confirmButtonText = "ok", showCancelButton = TRUE, showConfirmButton = TRUE, confirmButtonCol = "#6DBADE", size = "m", closeOnEsc = TRUE, closeOnClickOutside = TRUE, animation = TRUE, html = TRUE, text = div(HTML(' <form style="display:flex; flex-direction: row; justify-content: center; align-items: center" action=""> <div style="border: 5px black;"> <input type="text" name="add_nosha_tohen" autocomplete="off" id="add_nosha_tohen_1" value="" dir="rtl" style="border-color: black; font-size: 12px;height: 45px; width: 400px; display: block;"/> <input type="text" name="add_nosha_tohen" autocomplete="off" id="add_nosha_tohen_2" value="" dir="rtl" style="border-color: black; font-size: 12px;height: 45px; width: 400px; display: block;"/> <input type="text" name="add_nosha_tohen" autocomplete="off" id="add_nosha_tohen_3" value="" dir="rtl" style="border-color: black; font-size: 12px;height: 45px; width: 400px; display: block;"/> </div> </form> <script> // 获取弹窗内所有自定义输入框 const inputs = document.querySelectorAll(".swal2-html-container input[type=text]"); // 监听弹窗内键盘事件 document.querySelector(".swal2-popup").addEventListener("keydown", function(e) { if (e.key === "Tab") { // 阻止默认的焦点切换逻辑 e.preventDefault(); // 找到当前聚焦的元素索引 const currentIndex = Array.from(inputs).indexOf(document.activeElement); let nextIndex; if (e.shiftKey) { // Shift+Tab 反向切换 nextIndex = currentIndex <= 0 ? inputs.length - 1 : currentIndex - 1; } else { // Tab 正向切换 nextIndex = currentIndex === inputs.length - 1 ? 0 : currentIndex + 1; } // 移动焦点到目标输入框 inputs[nextIndex].focus(); } }) // 弹窗打开后默认聚焦第一个输入框 setTimeout(() => inputs[0].focus(), 100); </script> ' )) ) } shinyApp(ui, server)
效果说明
代码运行后弹窗弹出时会自动聚焦第一个输入框,按Tab可从上到下依次切换三个输入框的焦点,按Shift+Tab可反向切换,完全符合原生表单的键盘交互习惯。
内容的提问来源于stack exchange,提问作者asdf1212
相关产品推荐
相关产品推荐

