如何用原生JavaScript捕获div区域内可见的页面内容

需求为截取设置了position: absolute、z-index高于底图、悬浮在图片上方的div区域内的可见内容。最初实现方案导出的截图为空白,效果如下:
问题原因
原有代码输出空白图的核心逻辑错误:id为capture的canvas元素从未被写入任何实际渲染内容,仅在两个空canvas之间反复执行绘制操作,最终导出的自然是无内容的空白图像。
无需引入任何第三方库,使用原生Canvas API即可完成指定区域截图功能。
实现逻辑
- 获取目标悬浮div的几何参数:相对于视口的左偏移、上偏移、自身宽度、自身高度
- 创建离屏canvas,将画布尺寸设置为和目标div尺寸完全一致
- 将需要截取的内容源(底图、区域内其他可见元素)绘制到离屏canvas上,绘制时按照div的偏移值做反向坐标偏移,让div覆盖范围的内容正好填充整个画布
- 从离屏canvas导出图像数据,完成截图
完整实现代码
HTML结构
<div class="utility-btn"> <button class="enquiry-btn" onclick="openEnquiry()">?</button> </div> <!-- 底层展示图片 --> <img id="bgImage" src="你的底图路径" crossorigin="anonymous" alt="底层图"> <div id="enquiry"> <button id="close" onclick="closeEnquiry()">X</button> <div class="cover"> <button class="btn" onclick="takeScreenshot()"> Click to enquiry </button> </div> </div>
截图核心函数
function takeScreenshot() { // 获取目标悬浮区域的位置、尺寸信息 const targetArea = document.querySelector('.cover'); const rect = targetArea.getBoundingClientRect(); const areaWidth = rect.width; const areaHeight = rect.height; const areaLeft = rect.left; const areaTop = rect.top; // 初始化离屏画布 const offscreenCanvas = document.createElement('canvas'); const ctx = offscreenCanvas.getContext('2d'); offscreenCanvas.width = areaWidth; offscreenCanvas.height = areaHeight; // 绘制底图,通过反向偏移只保留目标区域覆盖的内容 const bgImg = document.getElementById('bgImage'); // 必须等图片加载完成后再执行绘制,否则会出现内容缺失 if (!bgImg.complete) { bgImg.onload = () => drawContent(); return; } drawContent(); function drawContent() { ctx.drawImage( bgImg, -areaLeft, -areaTop, bgImg.naturalWidth, bgImg.naturalHeight ); // 如果目标区域内还有其他需要截取的DOM元素,可按对应坐标依次绘制到画布上 // 导出截图 const screenshotData = offscreenCanvas.toDataURL('image/png'); console.log(screenshotData); // 后续可自行实现截图预览、保存、上传逻辑 } } // 原有弹窗开关函数保留即可 function openEnquiry() { document.getElementById('enquiry').style.display = 'block'; } function closeEnquiry() { document.getElementById('enquiry').style.display = 'none'; }
注意事项
- 若截图包含跨域资源,需要给对应资源(如图片)添加
crossorigin="anonymous"属性,同时服务端配置跨域访问权限,否则canvas会被污染,无法调用toDataURL导出内容 - 所有绘制到canvas的资源必须加载完成后再执行绘制操作,避免截图内容缺失
- 如果需要截取整个页面(不只是单张底图)在目标div区域的内容,可通过多段绘制拼接滚动区域内容,核心裁剪逻辑不变
内容的提问来源于stack exchange,提问作者Noob_Coder
相关产品推荐
相关产品推荐

