如何从Shiny Server捕获iframe中的JavaScript变量值?
解决iframe中JavaScript变量传递到Shiny的问题
问题描述
现有Shiny应用嵌入iframe加载foo.html,iframe内按钮点击会更新clickCounter变量,控制台能正常输出该变量值,但Shiny无法捕获input$clickCounter的值,需实现iframe内变量同步到Shiny。
修改方案
1. 更新www/foo.html代码
在iframe内的按钮点击事件中,通过主页面的Shiny对象将变量传递给Shiny应用:
<html> <script type="text/javascript"> let clickCounter = 0; </script> <body> TEST <button id="myButton" onclick="clickCounter += 1; console.log(clickCounter); window.parent.Shiny.setInputValue('clickCounter', clickCounter);">Click here</button> </body> </html>
关键改动:在按钮onclick事件末尾添加window.parent.Shiny.setInputValue('clickCounter', clickCounter),将更新后的clickCounter值发送到Shiny的input$clickCounter中。
2. 简化Shiny应用Server代码
无需额外包裹reactive对象,直接使用input$clickCounter即可:
library(shiny) library(shinydashboard) ui <- dashboardPage( dashboardHeader(title = 'demo'), dashboardSidebar( sidebarMenu( menuItem('Banco de Dados', tabName = 'banco_de_dados', icon = icon('th')) ) ), dashboardBody( tabItems( tabItem(tabName = 'banco_de_dados', h2('Banco de Dados'), textOutput('view'), htmlOutput('map') ) ) ) ) server <- function(input, output, session) { output$map <- shiny::renderUI({ tags$iframe(seamless = 'seamless', src = 'foo.html', width = 800, height = 800) }) output$view <- renderText(paste0('Click counter is: ', input$clickCounter)) } shinyApp(ui, server)
原理说明
iframe与Shiny主页面属于同源环境(同域名下),因此iframe可通过window.parent访问主页面的Shiny对象,调用Shiny.setInputValue直接将数据同步到Shiny输入对象中。
内容的提问来源于stack exchange,提问作者Lucas Almeida Carotta
相关产品推荐
相关产品推荐

