如何在移动端不加载R Markdown页面中的指定元素?
问题
我有个带大型Leaflet地图的R Markdown报告,想让移动端用户完全不加载这个地图——毕竟CSS只能隐藏元素,资源还是会下载;图片懒加载那套也不适用。用shiny::renderUI加jQuery能实现,但我想要更纯粹的R Markdown方案。
下面是复现问题的代码:
--- title: "no load on mobile reprex" output: html_document --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = FALSE, warning = FALSE) library(htmltools) library(leaflet) library(spData) # 实际场景中这是几MB级的大型地图资源,不想让移动端加载 mapdata = us_states
// 简单打印窗口宽度 $( document ).ready(function() { var window_width = $(window).width(); console.log('window_width is ',window_width); });
/* CSS能隐藏地图但有两个问题: 1. 会随窗口缩放动态切换显示状态,我只想在页面加载时判断一次 2. 地图资源还是会加载,浪费移动端带宽 */ @media only screen and (max-width: 768px) { #desktopOnlyContent { display: none; } }
A message to all users
h3('This message is for all users')
Different content for different users
div(id = 'desktopOnlyContent', h3('If you can see this, that means you have a large screen'), p('If you dont have a large screen then this should not even be visible in the elements tab of the devtools inside your browser, because if it is, then it is wasting bandwidth'), leaflet(elementId = 'desktopMap') |> addPolygons(data = mapdata) )
Another message to all users
h3('This message is also for all users')
# 纯R Markdown解决方案 核心思路是:页面加载时用JS做一次窗口宽度判断,只有桌面端(宽度>768px)才动态插入地图的HTML和依赖资源,移动端根本不会触发地图资源的请求,从根源节省带宽。 完整实现代码: ```r --- title: "移动端不加载大型地图的纯Rmd实现" output: html_document --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = FALSE, warning = FALSE) library(htmltools) library(leaflet) library(spData) # 生成大型地图对象(实际场景为几MB级资源) map_obj <- leaflet() |> addPolygons(data = us_states) # 将地图转换为可插入的HTML字符串和依赖资源列表 map_html <- as.character(map_obj) map_deps <- htmltools::resolveDependencies(map_obj$dependencies)
$(document).ready(function() { // 定义桌面端宽度阈值 const desktopThreshold = 768; const windowWidth = $(window).width(); // 仅当屏幕宽度大于阈值时,加载地图资源并插入内容 if (windowWidth > desktopThreshold) { // 插入地图HTML $("#mapContainer").html(`r map_html`); // 动态加载地图依赖的CSS和JS `r lapply(map_deps, function(dep) { if (dep$type == "css") { paste0('$("<link/>", {rel: "stylesheet", href: "', dep$href, '"}).appendTo("head");') } else if (dep$type == "javascript") { paste0('$.getScript("', dep$src$file, '");') } }) |> paste(collapse = "\n")` } else { // 移动端显示替代内容 $("#mapContainer").html('<h3>移动端不加载地图,节省带宽</h3>'); } });
给所有用户的消息
h3('这条消息面向所有用户')
不同设备显示不同内容
另一条给所有用户的消息
h3('这条消息也面向所有用户')
### 关键细节 - 先在R代码块中预先生成地图对象,转成HTML字符串和依赖列表,但不直接渲染到页面 - JS仅在页面首次加载时判断一次窗口宽度,不会随窗口缩放动态切换 - 只有桌面端才会注入地图内容并加载对应的CSS/JS资源,移动端完全不会触发这些请求 - 移动端显示替代文字,避免空容器影响页面布局 内容的提问来源于stack exchange,提问作者michael
相关产品推荐
相关产品推荐

