#javascript #html #r #shiny
#javascript #HTML #r #блестящий
Вопрос:
Резюме: я хотел бы адаптировать библиотеку JavaScript (а именно OwlCarousel2) в R, а точнее в R Shiny. Я уже сделал несколько шагов, но не могу найти способ добавить JS-скрипт, необходимый в конце структуры HTML (непосредственно перед концом тела).
OwlCarousel2
это библиотека, которая позволяет создавать карточки и заставлять их скользить. Смотрите здесь для получения более подробной информации.
Что я сделал до сих пор:
-
Прежде всего, я проверил, что могу воспроизвести ожидаемое поведение этой библиотеки только с помощью HTML, CSS и JS, следуя этому руководству.
-
Затем я попытался адаптировать это в R Shiny. По сути, я создал функции, встраивающие необработанный HTML, вставил JS и CSS
www
и запустил приложение, чтобы убедиться, что оно работает. Это произошло: карты были отображены, и было поведение слайда. Но это было немного запутанно, поэтому я решил превратить его в пакет, чтобы мне (и другим) было проще использовать его повторно. -
Чтобы преобразовать это в пакет, я использовал два источника:
- учебное пособие, сопровождающее пакет
{applause}
- эта новая книга о R и Javascript
- учебное пособие, сопровождающее пакет
Я создал три функции: owl_carousel_item()
для создания карточек, owl_carousel()
для встраивания карточек в a div
с классом slider owl-carousel
и html_dependency_owlcarousel()
для включения зависимостей.
html_dependency_owlcarousel <- function() {
htmltools::htmlDependency(
name = "owl.carousel",
version = "2.3.4",
package = "shinymisc",
src = "htmlwidgets/owl_carousel",
script = c("owl.carousel.min.js", "owl.carousel.js"),
stylesheet = c("owl.carousel.min.css", "style.css"),
all_files = FALSE
)
}
owl_carousel <- function(id, ...) {
tag <- htmltools::tags$div(
id = id,
class = "slider owl-carousel",
...
)
htmltools::tagList(
tag,
html_dependency_owlcarousel()
)
}
owl_carousel_item <- function(title, subtitle, content = NULL, button_text = NULL, width = "300px") {
if (!is.null(button_text))
button <- shiny::tags$div(class = "btn", value = button_text)
else
button <- NULL
shiny::tags$div(
class = "card",
style = paste0("width: ", width),
shiny::tags$div(class = "img"),
shiny::tags$div(
class = "content",
shiny::tags$div(class = "title", title),
shiny::tags$div(class = "sub-title", subtitle),
shiny::tags$p(content),
button
)
)
}
С помощью этого кода (и зависимостей) я создаю приложение, которое имеет структуру HTML, почти эквивалентную той, которую я мог бы создать вне среды пакета: оно отображает карточки, но они не скользят. Чего не хватает <script>
, так это того, что должно быть внизу этой структуры, непосредственно перед концом <body>
. Вот почему карточки не скользят.
Я попытался применить метод, описанный в этой главе упомянутой ранее книги, но безуспешно, потому что я не мог заставить htmlwidgets::createWidget()
работать с моим tag
.
Поэтому мой вопрос: как я могу разместить следующий скрипт в конце структуры HTML?
$(".slider").owlCarousel({
loop: true,
autoplay: true,
autoplayTimeout: 2000, //2000ms = 2s;
autoplayHoverPause: true,
});
Имейте в виду, что эти параметры должны быть доступны для редактирования с помощью функции owl_carousel()
(поэтому просто вставить это в конце tag
in owl_carousel()
недостаточно).
Я знаю, что это должно быть не очень понятно, поэтому вот ссылка на репозиторий, содержащий то, что я сделал до сих пор.
Примечание: это должно быть менее сложным, чем для других виджетов. Здесь нет *Output
render*
функций or, нет данных, просто функция для встраивания блоков и заставления их скользить.
Редактировать: некоторый код для проверки того, что он работает (он должен отображать две карточки и анимацию):
library(shiny)
library(fullPage)
ui <- fullPage(
menu = c("Section 1" = "section1"),
pageSection(
menu = "section1",
owl_carousel(
id = "test",
owl_carousel_item(
title = "test1",
subtitle = "subtitle1",
content = "this is a test"
),
owl_carousel_item(
title = "test2",
subtitle = "subtitle2",
content = "this is a test",
button_text = "button to click"
)
)
)
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
Комментарии:
1. возможно, добавление a
htmltools::tags$script('ur jquery code here')
в список тегов2. Спасибо, это работает
shiny::fluidPage
, но не для других макетов, например,fullPage::fullPage
потому, что скрипт кажется «слишком высоким» в структуре HTML. Более того, это не похоже на простой способ связать javascript с функцией в пакете.3. можете ли вы предоставить MWE, чтобы я мог его протестировать. также спасибо за то, что сделали shiny лучше
4. также, возможно, если вы дождетесь загрузки содержимого, это сработает
5. Я уже знаю, как заставить это работать в «классической» настройке. Здесь моя проблема связана с тем фактом, что это пакет R, и что структура сильно отличается. Поэтому я не могу создать MWE. Тем не менее, вы можете загрузить репозиторий, на который я ссылался в своем посте, чтобы иметь точную ситуацию, в которой я нахожусь.
Ответ №1:
Решение заключалось в перемещении owl_carousel.js
в inst/htmlwidgets
и изменении renderValue
функции для включения предоставленного jQuery
кода.
renderValue: function(x) {
// TODO: code to render the widget, e.g.
el.innerHTML = x.message;
$(".slider").owlCarousel({
loop: true,
autoplay: true,
autoplayTimeout: 2000, //2000ms = 2s;
autoplayHoverPause: true,
})
}
И изменение возвращаемого значения owl_carousel
функции на :
owl_carousel <- function(id, ..., width = "100%", height = "400px") {
tag <- htmltools::tags$div(
id = id,
class = "slider owl-carousel",
...
)
x <- list(message=as.character(htmltools::tagList(
tag,
html_dependency_owlcarousel()
)))
htmlwidgets::createWidget(
name = 'owl_carousel',
x,
package = 'shinymisc'
)
}
Редактировать
Для проблемы с css, которую вы не включили style.css
в yaml:
dependencies:
- name: jQuery
version: 3.5.1
src: htmlwidgets/jquery
script: jquery.min.js
- name: OwlCarousel2
version: 2.3.4
src: htmlwidgets/owl_carousel
script: owl.carousel.min.js
stylesheet:
- owl.carousel.min.css
- style.css
Результат
Комментарии:
1. Это не работает. Я добавил пример в свой пост, чтобы легко проверить, работает код или нет. В этом примере после применения ваших изменений ошибок нет, но ничего не отображается
2. @bretauv ошибка возникает из-за того, что jquery не находит
owlCarousel
функцию, возможно, существует конфликт между версией jQuery, используемойfullPage
и используемойowlCarousel
3. fullPage использует jQuery 3.2, а OwlCarousel использует 3.5
4. это работает при печати виджета и с
shiny::fluidPage
5. Действительно, мне пришлось открыть его в браузере. Однако стиль css не применяется (хотя это было раньше). Не могли бы вы сделать форк репозитория, чтобы у меня было именно то, что у вас есть?