【问题标题】:How to correclty use MutationObserve in Shiny app如何在 Shiny 应用程序中正确使用 MutationObserver
【发布时间】:2021-04-14 12:36:05
【问题描述】:

我正在尝试使用 Shiny 中的 javascript mutationObserver 来观察 css 的变化。我正在使用rhandsontable,因为我们可以更改应用程序中表格元素的宽度,并且我正在尝试通过mutationObserver 来获取此更改。

javascript 似乎无法正常工作。我不确定为什么。控制台没有记录任何内容,没有警报消息,并且闪亮没有注册由 javascript 设置的变量。

MutationObserver 代码

jsCode <- "
    const observer = new MutationObserver(
      # this function runs when something is observed.
      function(mutations){
        console.log('activated')
        var i;
        var text;
        var widthArray = [];
        text = ''
        for (i = 0; i < document.getElementsByClassName('htCore')[0].getElementsByTagName('col').length; i++) {
          text += document.getElementsByClassName('htCore')[0].getElementsByTagName('col')[i].style.width + '<br>';
          widthArray.push(document.getElementsByClassName('htCore')[0].getElementsByTagName('col')[i].style.width);
        }
        alert(text)
        Shiny.setInputValue('colWidth', widthArray);
      }
    )
    const cols = document.getElementsByClassName('htCore')[0].getElementsByTagName('col')
    observer.observe(cols, {
      attributes: true # observe when attributes of ul.bears change (width, height)
    })
"

闪亮的代码:

library(shiny)
library(rhandsontable)

ui <- fluidPage(
  tags$head(tags$script(HTML(jsCode))),
  rhandsontable::rHandsontableOutput("dataTable")
)
server <- function(input, output, session) {
    df = data.frame(
        company = c('a', 'b', 'c', 'd'),
        bond = c(0.2, 1, 0.3, 0),
        equity = c(0.7, 0, 0.5, 1),
        cash = c(0.1, 0, 0.2, 0),
        stringsAsFactors = FALSE
    )
  output$dataTable <- renderRHandsontable({
      rhandsontable(df, manualColumnResize = TRUE, manualRowResize = TRUE)
    })
  observeEvent(input$colWidth, {
    print(input$colWidth)
  })
}
shinyApp(ui, server)


【问题讨论】:

    标签: r shiny mutation-observers


    【解决方案1】:

    这行得通:

    jsCode <- "
    $(document).on('shiny:connected', function(){
      setTimeout(function(){
        const observer = new MutationObserver(
          function(mutations){
            console.log('activated')
            var i;
            var text;
            var widthArray = [];
            text = ''
            for (i = 0; i < document.getElementsByClassName('htCore')[0].getElementsByTagName('col').length; i++) {
              text += document.getElementsByClassName('htCore')[0].getElementsByTagName('col')[i].style.width + '<br>';
              widthArray.push(document.getElementsByClassName('htCore')[0].getElementsByTagName('col')[i].style.width);
            }
            alert(text)
            Shiny.setInputValue('colWidth', widthArray);
          }
        )
        const cols = document.getElementsByClassName('htCore')[0].getElementsByTagName('colgroup')[0]
        observer.observe(cols, {
          attributes: true, subtree: true 
        });
      }, 500);
    });
    "
    

    【讨论】:

    • 谢谢!我有两个问题,为什么我们需要使用setTimeout?另外,为什么我们需要$(document).on("shiny:connected", ...?取而代之的是,如果我在服务器端使用runjs(jsCode) 执行一次观察者代码,它是否也可以工作?
    • @Frank 我们需要延迟,否则找不到元素。
    • @Frank 请参阅 stackoverflow.com/q/65636472/1100107> 以获得更好的方法。
    • @Frank 如果你更喜欢突变观察器的解决方案,最好将JS代码放在onRender函数中,而不是使用延迟。
    猜你喜欢
    • 2021-09-19
    • 2018-03-07
    • 2017-11-23
    • 2017-06-17
    • 2018-12-30
    • 2020-03-30
    • 2021-05-30
    • 1970-01-01
    相关资源
    最近更新 更多