Shiny中如何向嵌入JS的document.getElementById传递动态变量
R Shiny中向document.getElementById传入动态元素ID的实现方法
硬编码问题的本质是:onclick参数接收的是最终要渲染到HTML里的JS字符串,只要在R侧把动态ID值拼接到这个字符串的对应位置,就能替代写死的'small_ID',不需要特殊的传参语法。
基础实现方法(R变量存储动态ID)
- 提前把动态生成的元素ID存在R变量中,用
paste0/sprintf把变量值拼接到JS代码串里,注意保留JS语法需要的引号配对。
示例代码:
# 实际场景中这个值是动态生成的,比如接口返回、循环生成、用户输入产生的ID dynamic_element_id <- "small_ID" actionButton( inputId = "show1", class = "act_button", label = list( span(id = "m1", class="top left", "Model 1"), span(class="top right", Sys.time()) ), onclick = paste0( "Shiny.setInputValue('btnid', document.getElementById('", dynamic_element_id, "').textContent);" ) )
拼接时注意:
getElementById的参数要求是字符串类型,所以R侧拼接时要给动态ID值前后补上JS语法需要的单引号,否则渲染出的JS会把ID值当成未定义的JS变量,直接抛出运行错误。
批量生成按钮场景的写法
如果是循环批量生成多个按钮,每个按钮对应不同的目标元素ID,直接在循环内部完成拼接即可:
# 示例:批量生成3个绑定不同目标元素的按钮 button_list <- lapply(1:3, function(index) { # 每个按钮对应要读取内容的元素ID,随循环动态变化 current_target_id <- paste0("m", index) actionButton( inputId = paste0("show", index), class = "act_button", label = list( span(id = current_target_id, class="top left", paste0("Model ", index)), span(class="top right", Sys.time()) ), onclick = paste0( "Shiny.setInputValue('btnid', document.getElementById('", current_target_id, "').textContent);" ) ) })
更简便的无ID依赖写法
如果要读取的内容就在当前点击的按钮内部,完全不需要提前获取动态ID,直接用JS事件的上下文对象this(指向当前被点击的按钮本身)查找子元素即可,彻底避免ID拼接的问题:
actionButton( inputId = "show1", class = "act_button", label = list( # 目标元素甚至不需要设置ID span(class="top left", "Model 1"), span(class="top right", Sys.time()) ), # 直接查找当前按钮下class为top left的子元素 onclick = "Shiny.setInputValue('btnid', this.querySelector('.top.left').textContent);" )
内容的提问来源于stack exchange,提问作者manu p
相关产品推荐
相关产品推荐

