如何在无server端代码的Shiny中嵌入JS实现文本输入实时更新
问题背景
需要在不编写任何Shiny server端代码的前提下,通过嵌入JavaScript实现效果:文本输入框输入内容时,页面中id为res的p标签默认文本「Value」同步更新为输入的内容。原有代码无法实现预期,代码如下:
library(shiny) ui <- fluidPage( tags$head(HTML('<p id="res">Value</p>'), tags$script("document.getElementById('res').innerHTMl=x")), textInput("x", label = "Text") ) server <- function(input, output) { } shinyApp(ui, server)
原有代码问题
- 标签位置错误:
<p>是可见页面元素,不能放在tags$head内部,head区域仅用于加载脚本、样式、元数据,放在其中的p标签无法正常在页面渲染。 - 语法拼写错误:DOM元素设置内容的属性为
innerHTML,原代码错写为innerHTMl(末尾字母L大小写错误);如果仅更新纯文本内容,优先使用textContent属性,避免XSS安全风险。 - 交互逻辑缺失:原代码中的JS仅会在页面加载阶段执行一次,既没有给输入框绑定内容变化的监听事件,也没有定义代码中出现的
x变量,输入内容变化时不会触发任何更新逻辑,自然拿不到输入框的实时值。
可行实现代码
完全不需要编写server端逻辑,修正标签位置、补全事件监听即可,完整可运行代码如下:
library(shiny) ui <- fluidPage( # 结果p标签放在页面正文区域 tags$p(id = "res", "Value"), textInput("x", label = "Text"), # 嵌入JS监听输入变化 tags$script(HTML(" $(document).on('shiny:inputchanged', function(e) { if(e.name === 'x') { document.getElementById('res').textContent = e.value; } }) ")) ) server <- function(input, output) {} shinyApp(ui, server)
实现说明:这里直接监听Shiny内置的
shiny:inputchanged事件,不需要手动给输入框绑定原生键盘、粘贴事件,能完美适配Shiny输入框的所有值变化场景(包括键盘输入、粘贴、代码触发值更新等),稳定性更高。
内容的提问来源于stack exchange,提问作者manu p
相关产品推荐
相关产品推荐

