【问题标题】:R Shiny App Detect MobileR Shiny App 检测手机
【发布时间】:2019-04-04 08:16:18
【问题描述】:

我有一个闪亮的应用程序(实际上是一个交互式 R Markdown 报告),我想根据用户是否在移动设备上对其进行格式化。我发现 g3rv4 的这篇博客文章描述了如何对此进行测试,但我无法让它在下面的示例应用程序中工作。

https://g3rv4.com/2017/08/shiny-detect-mobile-browsers

我是一名建模师,而不是程序员,所以我可能做错了关于 Javascript 的一些事情。我没有收到错误消息,但我没有收到来自 textOutput('isItMobile') 的任何输出。

# shiny example from
# https://shiny.rstudio.com/tutorial/written-tutorial/lesson1/
# mobile detect code from
# https://g3rv4.com/2017/08/shiny-detect-mobile-browsers
library(shiny)

onStart <- function(input, output) {

  ### function to detect mobile ####
  mobileDetect <- function(inputId, value = 0) {
    tagList(
      singleton(tags$head(tags$script(src = "js/mobile.js"))),
      tags$input(id = inputId,
                 class = "mobile-element",
                 type = "hidden")
    )
  }

}

# Define UI for app that draws a histogram ----
ui <- fluidPage(

  # App title ----
  titlePanel("Hello Shiny!"),

  mobileDetect('isMobile'),
  textOutput('isItMobile'),

  # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel for inputs ----
    sidebarPanel(

      # Input: Slider for the number of bins ----
      sliderInput(inputId = "bins",
                  label = "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)

    ),

    # Main panel for displaying outputs ----
    mainPanel(

      # Output: Histogram ----
      plotOutput(outputId = "distPlot")

    )
  )
)

# Define server logic required to draw a histogram ----
server <- function(input, output) {

  output$isItMobile <- renderText({ 
    ifelse(input$isMobile, "You are on a mobile device", "You are not on a mobile device")
  })

  # Histogram of the Old Faithful Geyser Data ----
  output$distPlot <- renderPlot({

    x    <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins + 1)

    hist(x, breaks = bins, col = "#75AADB", border = "white",
         xlab = "Waiting time to next eruption (in mins)",
         main = "Histogram of waiting times")

  })

}

# this is how you run it
print('Running Simple Shiny App - Hit ESC to quit.')
shinyApp(ui = ui, server = server, onStart = onStart)

这是www/js/mobile.js 文件:

var isMobileBinding = new Shiny.InputBinding();
$.extend(isMobileBinding, {
  find: function(scope) {
    return $(scope).find(".mobile-element");
    callback();
  },
  getValue: function(el) {
    return /((iPhone)|(iPod)|(iPad)|(Android)|(BlackBerry))/.test(navigator.userAgent)
  },
  setValue: function(el, value) {
  },
  subscribe: function(el, callback) {
  },
  unsubscribe: function(el) {
  }
});

Shiny.inputBindings.register(isMobileBinding);

【问题讨论】:

  • 您是否考虑过使用提供框架的包来执行此内置操作?对于简单的要求,我建议flexdashboard,特别是考虑到您说它是用于交互式rmarkdown 报告。如果您需要更多功能,请查看shinydashboard,尽管学习曲线要​​陡峭得多。
  • 谢谢!我会调查的。
  • 嗨@SimonWoodward,你有没有设法解决这个问题?我也有同样的问题
  • 嗨@Sharma 不,我没有得到这个工作。

标签: r mobile shiny


【解决方案1】:

这是一种根据屏幕尺寸检测(小型)移动设备的方法。请注意,这故意排除了屏幕较大的平板电脑。

下面的 sn-p 检查屏幕大小是否低于 768 像素,并使用 onInputChange 作为名为 is_mobile_device 的输入将结果发送到 Shiny 服务器。仅在页面加载且 Shiny UI 完成加载时进行一次检查。

将其放入一个 JS 文件并将其包含在您的 UI 中(例如,就像在问题中使用 tags$script 完成的那样):

$(document).on('shiny:sessioninitialized', function (e) {
  var mobile = window.matchMedia("only screen and (max-width: 768px)").matches;
  Shiny.onInputChange('is_mobile_device', mobile);
});

浏览器支持:http://caniuse.com/#feat=matchmedia

在您的 Shiny server 函数中,您可以定义一个 reactive 来检索值:

server <- function(input, output, session) {
    is_mobile_device <- reactive(isTRUE(input$is_mobile_device))
    # ...
}

有关在 JavaScript 端检测移动设备的其他方法(例如,基于用户代理还包括平板电脑),请在此处查看优秀答案:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-08
    • 2020-10-07
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    相关资源
    最近更新 更多