我想知道用户何时在shiny 的应用程序中单击图像.我的完整应用程序在一种"照片搜寻"游戏中显示图像,我想捕捉用户点击每张图像中相关位置所需的时间.然而,我很难捕获客户端时间,这很重要,因为服务器端时间可能会由于各种原因而延迟.我想我需要下面的javascript之类的东西,但我不知道如何将其集成到应用程序中.

  1. 在页面上查找元素
var image = document.getElementById('img');
  1. 倾听点击并捕捉时间
addEventListener("click", true,
click_time = new Date().getTime();)
  1. 将捕获的时间发送到shiny server,如下所示:
Shiny.onInputChange("new_click_time",click_time);
  1. 收听shiny以获取click\u时间
observeEvent(input$new_click_time,{
  # This should be the time the user clicked on the image:
   input$new_click_time
})

下面是一个获得服务器时间而非客户端时间的shiny 应用程序示例:

library(shiny)
library(shinyjs)
options(digits.secs = 3)     # Modify default global time to show milleseconds

shinyApp(
  ui = fluidPage(
    useShinyjs(),
    sidebarLayout(
      sidebarPanel(
        p("When clicking on the histogram, I'd like to capture the client-side computer's time"),
        actionButton(inputId="new_image", label= "New Image")
      ),
      mainPanel(
        imageOutput("img", click = "photo_click"),
        textOutput("client_time"),
        textOutput("server_time")
      )
    )
  ),
  server = function(input, output) {


    output$img <- renderImage({
      input$new_image

      outfile <- tempfile(fileext='.png')
      png(outfile, width=400, height=400)
      hist(rnorm(100))
      dev.off()

      list(src = outfile,
           alt = "This is alternate text")
    },
    deleteFile = TRUE)

    output$server_time <- renderText({
      req(input$photo_click)

      server.time <- as.character(strptime(Sys.time(), "%Y-%m-%d %H:%M:%OS"))    # Time with milliseconds
      paste("SERVER TIME:", server.time)
    })

    output$client_time <- renderText({
      # cat("\nI'd like to capture click-time, possibly here -- the time on the client's machine when a click is made")
      req(input$photo_click)
      client.time <- "???"    # Time with milliseconds
      paste("CLIENT TIME:", client.time)
    })


  }
)

推荐答案

您可以使用Shiny提供给客户端的javascript函数Shiny.setInputValue.例子:

library(shiny)
ui <- shiny::fluidPage(
                 img(id = 'trigger_image', 
                     src = 'notfound.jpg',
                     height = '100px',
                     width = '100px'
                     ),
                 tags$script('
              document.getElementById("trigger_image").onclick = function(){
              var the_time = new Date().getTime();
              // set input$client_time to the_time:
              Shiny.setInputValue("client_time", the_time)}
        ')
        )

server <- function(input, output) {
    observeEvent(input$client_time,{
        ## do stuff with input$client_time
    })
}

shinyApp(ui, server)

请注意,Javascript getTime返回自1970年1月1日以来经过的毫秒数.

光泽:Communicating with Javascript

Edit

如果必须测量在客户端更新映像和用户响应(单击刷新映像)之间经过的时间,可以在客户端捕获并计算两个事件之间的持续时间,如下所示:

library(shiny)
ui <- shiny::fluidPage(
    tags$script('
    // ------ javascript code ------
    // $(document).ready(...) ensures execution only after document is fully rendered
    // so that events like .onclick can be attached 
    $(document).ready(function(){
        // function to set Shiny input value to current time: 
        const clockEvent = function(inputName){Shiny.setInputValue(inputName, new Date().getTime())}
        // trigger when the value of output id "trigger_image" changes: 
        $(document).on("shiny:value",
               function(event){
                   if (event.target.id === "trigger_image") {clockEvent("displayed_at")}
               }
              )
        // trigger when the image, after being sent or refreshed, is clicked:
        document.getElementById("trigger_image")
                    .onclick = function(){clockEvent("reacted_at")}
    })
    // ------------------------------
    '),
    shiny::imageOutput('trigger_image'),
    actionButton('show_new', 'show new image'),
    textOutput('reaction_time')
)


server <- function(input, output) {
    observeEvent(input$show_new,{
        output$trigger_image <- shiny::renderImage(list(id = 'trigger_image',
                                                        'src' = 'image001.png'
                               ), deleteFile = FALSE)
                               
        output$reaction_time <- renderPrint(paste('reaction time (ms)', input$reacted_at - input$displayed_at))
})
}

shinyApp(ui, server)

Javascript相关问答推荐

Angular material -在收件箱视图中显示不同的文本,而不是 Select 的选项

使用Astro和React的动态API

为什么子组件没有在reaction中渲染?

如何在alpinejs中显示dev中x-for的元素

在JS中获取名字和姓氏的首字母

Bootstrap动态选项卡在切换选项卡后保持活动状态,导致元素堆叠

Exceljs:我们在file.xlsx(...)&#中发现了一个问题'"" 39人;

XSLT处理器未运行

可更改语言的搜索栏

WhatsApp Cloud API上载问题:由于MIME类型不正确而导致接收&Quot;INVALID_REQUEST";错误

闭包是将值复制到内存的另一个位置吗?

如何在不影响隐式类型的情况下将类型分配给对象?

VSCode中出现随机行

为什么JPG图像不能在VITE中导入以进行react ?

回溯替代方式

Phaserjs-创建带有层纹理的精灵层以自定义外观

如何为仅有数据可用的点显示X轴标签?

如何更改Html元素S的 colored颜色 ,然后将其褪色为原始 colored颜色

使用Reaction窗体挂钩注册日历组件

Next.js无法从外部本地主机获取图像