如何在 Shiny 应用中正确使用 MutationObserver

How to correclty use MutationObserve in Shiny app

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

javascript 似乎不起作用。我不确定为什么。没有任何内容记录到控制台,没有警报消息,并且 shiny 没有注册由 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)


这个有效:

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);
});
"