树莓派Zero下抓取网页无缝更新与动态字体适配问题求解
解决隐藏iframe无法动态调整字体的问题
需求背景
- 在1080p显示器的kiosk模式下显示「本周安排」
- 数据抓取自第三方网页,需自定义格式(背景图、无滚动条、新页眉页脚)
- 原网页更新频率低,自身页面每15分钟更新一次
- 需最大化字体显示,内容溢出时自动缩小字体
- 运行设备为性能有限的Raspberry Pi Zero
当前实现方案
通过Perl脚本配合cron定时抓取第三方网页数据,提取表格内容并添加自定义页眉页脚生成iframe.html;主页面采用双iframe切换实现无缝更新,核心代码如下:
主页面核心代码
<body onload="load(); update();"> <h1>What's on this week</h1> <div id="floating-div"> <iframe src="iframe.html" allowtransparency="true" frameborder="0" style="width:100%;height:100%;" id="if1"></iframe> <iframe src="iframe.html" allowtransparency="true" frameborder="0" style="width:100%;height:100%;" id="if2"></iframe> </div> </body> <script> function update() { if1 = document.getElementById("if1"); if2 = document.getElementById("if2"); if (if1.style.display == "none") { if1.style.display = "block"; if2.style.display = "none"; if2.src = "iframe.html"; } else { if2.style.display = "block"; if1.style.display = "none"; if1.src = "iframe.html"; } } function load() { setInterval(update, 15000); } </script>
iframe.html核心代码
<body onload="set_size();"> <div class="cdiv"> <table id="calendar" class="weekly"> ... </table> </div> </body>
溢出检测函数
function check(el) { var curOverf = el.style.overflow; if (!curOverf || curOverf === "visible") el.style.overflow = "hidden"; var isOverflowing = el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight; el.style.overflow = curOverf; return isOverflowing; }
核心问题
隐藏状态的iframe(设置display:none)无法触发set_size()完成动态字体调整,仅可见iframe能正常生效,导致切换后可能出现内容溢出或字体未最大化的情况。
解决方法
方法1:用定位替代display:none隐藏iframe
将隐藏的iframe移出可视区域但保持渲染状态,确保set_size()能正常计算尺寸:
- 添加CSS样式:
#floating-div { position: relative; width: 100%; height: calc(100vh - 50px); /* 减去页眉高度 */ overflow: hidden; } #floating-div iframe { position: absolute; top: 0; left: 0; transition: left 0.3s ease; } #floating-div iframe.hidden { left: -100%; }
- 修改
update()函数:
function update() { const if1 = document.getElementById("if1"); const if2 = document.getElementById("if2"); if (if1.classList.contains('hidden')) { if1.classList.remove('hidden'); if2.classList.add('hidden'); if2.src = "iframe.html"; } else { if2.classList.remove('hidden'); if1.classList.add('hidden'); if1.src = "iframe.html"; } }
此方法让隐藏的iframe仍在后台渲染,set_size()可正常执行,切换时通过平滑过渡实现无缝更新,且对Pi Zero性能影响极小。
方法2:预计算字体大小(适配低性能设备)
考虑到Pi Zero性能有限,可在Perl脚本生成iframe.html时,提前根据内容量预估字体大小,减少前端计算压力:
# Perl脚本示例:根据表格行数调整字体大小 my $row_count = scalar @table_rows; my $font_size = 24; # 默认字体大小 if ($row_count > 10) { $font_size = 18; } elsif ($row_count > 5) { $font_size = 22; } # 将计算后的font_size写入iframe.html的<style>标签
此方式完全避免前端动态调整,适合内容结构稳定的场景。
方法3:iframe加载完成后通知主页面触发调整
在iframe的set_size()完成后向主页面发送消息,主页面可触发二次检查(作为方法1的补充):
- 修改iframe的
set_size()函数:
function set_size() { // 原字体调整逻辑... window.parent.postMessage({ type: 'sizeAdjusted', iframeId: window.frameElement.id }, '*'); }
- 主页面监听消息:
window.addEventListener('message', function(e) { if (e.data.type === 'sizeAdjusted') { const iframe = document.getElementById(e.data.iframeId); // 可根据需要执行额外的尺寸检查逻辑 } });
最优方案推荐
优先选择方法1,既解决了隐藏iframe的字体调整问题,又能保持无缝切换体验,且适配Pi Zero的低性能特性。
内容的提问来源于stack exchange,提问作者WhyNine
相关产品推荐
相关产品推荐

