RShiny: Почему htmlOutput предотвращает работу JavaScript?

#javascript #html #r #shiny #shinyjs

Вопрос:

Я создаю приложение RShiny, в котором мне нужно создавать кнопки ванильного/обычного html и предоставлять им базовую функциональность с помощью JavaScript. В моем оригинальном приложении у меня есть элемент htmlOutput (или uiOutput), содержащий эти кнопки (они генерируются динамически на основе пользовательского ввода). К сожалению, JavaScript неправильно работает внутри этого элемента htmlOutput, и я не могу понять, почему. Пожалуйста, посмотрите мой минимальный воспроизводимый пример (приложение.R):

 library(shiny)
library(shinyjs)

# define ui
ui <- fluidPage(
    useShinyjs(),
    tags$head(
        tags$script(
            HTML(
            "window.onload = function(){
            var coll = document.getElementsByClassName('testclass');
            var i;
            console.log(coll);
              for (i = 0; i < coll.length; i  ) {
                  coll[i].addEventListener('click', function() {
                    alert('clicked');
                  });
              };
            };
            ")
            )
    ),
    mainPanel(
        # normal button (working)
        tags$button(
            type="button",
            class="testclass",
            "Click to alert (button inside main panel)"
        ),
        # html output button (not working)
        htmlOutput("html_out")
    )
)

# define server
server <- function(input, output) {

    # generate html output button (problematic with JS)
    output$html_out <- renderUI({
        tags$button(
            type="button",
            class="testclass",
            "Click to alert (button inside htmlOutput)"
        )
    })
}

# run app
shinyApp(ui = ui, server = server)

 

Элемент tags$button() работает без проблем, если он статически добавлен в главную панель. Но если тот же элемент tags$button() добавляется через htmlOutput, он не работает с кодом JavaScript. Есть ли какое-либо объяснение или обходной путь для этого?

Единственное отличие в коде вывода html заключается в том, что элемент htmlOutput заключен в div с классом = «блестящий-html-вывод, блестящий-связанный-вывод». И я знаю, что обычно я должен использовать кнопку действия (), но в моем случае это невозможно.

Спасибо за вашу помощь!

Комментарии:

1. Возможно, опубликовать визуализированный вывод с помощью view-source?

Ответ №1:

Проблема в том, что начальный JS head запускается при запуске приложения, но вторая кнопка недоступна сразу. вы можете добавить код JS непосредственно в HTML-код

 library(shiny)
library(shinyjs)

# define ui
ui <- fluidPage(
    useShinyjs(),
    tags$head(
        tags$script(
            HTML(
                "window.onload = function(){
            var coll = document.getElementsByClassName('testclass');
            var i;
            console.log(coll);
              for (i = 0; i < coll.length; i  ) {
                  coll[i].addEventListener('click', function() {
                    alert('clicked');
                  });
              };
            };
            ")
        )
    ),
    mainPanel(
        # normal button (working)
        tags$button(
            type="button",
            class="testclass",
            "Click to alert (button inside main panel)"
        ),
        # html output button (not working)
        htmlOutput("html_out")
    )
)

# define server
server <- function(input, output) {
    
    # generate html output button (problematic with JS)
    output$html_out <- renderUI({
        tags$button(
            type="button",
            class="testclass",
            
            # ADD JS HERE
            onclick = "alert('clicked');",
            "Click to alert (button inside htmlOutput)"
        )
    })
}

# run app
shinyApp(ui = ui, server = server)