问题描述
我正在尝试使用 Shiny 中的 javascript mutationObserver 观察 css 的变化。我使用 rhandsontable
是因为我们可以更改应用程序中表格元素的宽度,并且我正在尝试通过 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.5,1),cash = c(0.1,0.2,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);
});
"