如何用JavaScript获取HTML文档可见区域元素优化截图插件
截取HTML文档可见区域的实现方案
你当前代码通过document.body截取了整个页面,要改成仅捕获当前可见视口内容,有两种可行方案:
方案一:截取后裁剪图片(基于现有domtoimage流程)
先获取完整页面截图,再用Canvas裁剪出视口范围内的部分:
async function onSupportButtonClick() { try { setSupportButtonLoading(true) const corsImages = []; const originalCorsSources = []; proxifyCorsImages(corsImages, originalCorsSources) const supportEmail = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL_EMAIL) if (supportEmail) supportEmail.value = document?.profile?.email ?? "" const imageContainer = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL_IMAGE_CONTAINER); imageContainer.innerHTML = "" //removing previous screenshot // 获取视口参数 const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; const scrollX = window.scrollX; const scrollY = window.scrollY; // 获取完整页面截图 const fullDataUrl = await domtoimage.toPng(document.body, { imagePlaceholder: EMPTY_IMAGE_PLACEHOLDER }) deproxifyCorsImages(corsImages, originalCorsSources) // 用Canvas裁剪出可见区域 const img = new Image(); img.src = fullDataUrl; await new Promise(resolve => img.onload = resolve); const canvas = document.createElement('canvas'); canvas.width = viewportWidth; canvas.height = viewportHeight; const ctx = canvas.getContext('2d'); // 绘制视口对应的区域:从截图的(scrollX, scrollY)位置,截取viewport宽高的内容 ctx.drawImage(img, scrollX, scrollY, viewportWidth, viewportHeight, 0, 0, viewportWidth, viewportHeight); // 获取裁剪后的dataURL const croppedDataUrl = canvas.toDataURL('image/png'); setMuiModalsDisplay("none"); setScreenshotImage(croppedDataUrl, imageContainer) } catch (err) { console.log(err) showSupportAlert(createElementFromHTML(errorAlertChild), JIRASUPPOTER_SUPPORT_ALERT_TYPES.WARNING) } const modal = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL); if (modal) modal.style.display = "flex"; }
方案二:克隆并裁剪DOM后截取(更高效)
直接克隆页面内容,隐藏视口外的部分,再截取克隆元素:
async function onSupportButtonClick() { try { setSupportButtonLoading(true) const corsImages = []; const originalCorsSources = []; proxifyCorsImages(corsImages, originalCorsSources) const supportEmail = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL_EMAIL) if (supportEmail) supportEmail.value = document?.profile?.email ?? "" const imageContainer = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL_IMAGE_CONTAINER); imageContainer.innerHTML = "" //removing previous screenshot // 获取视口参数 const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; const scrollX = window.scrollX; const scrollY = window.scrollY; // 克隆body并设置裁剪样式 const clonedBody = document.body.cloneNode(true); clonedBody.style.position = 'relative'; clonedBody.style.overflow = 'hidden'; clonedBody.style.width = `${viewportWidth}px`; clonedBody.style.height = `${viewportHeight}px`; clonedBody.style.left = `-${scrollX}px`; clonedBody.style.top = `-${scrollY}px`; // 把克隆元素添加到页面(临时) document.body.appendChild(clonedBody); // 截取克隆元素 const dataUrl = await domtoimage.toPng(clonedBody, { imagePlaceholder: EMPTY_IMAGE_PLACEHOLDER }) // 移除临时克隆元素 document.body.removeChild(clonedBody); deproxifyCorsImages(corsImages, originalCorsSources) setMuiModalsDisplay("none"); setScreenshotImage(dataUrl, imageContainer) } catch (err) { console.log(err) showSupportAlert(createElementFromHTML(errorAlertChild), JIRASUPPOTER_SUPPORT_ALERT_TYPES.WARNING) } const modal = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL); if (modal) modal.style.display = "flex"; }
关键说明
- 方案一适合不想修改DOM结构的场景,缺点是需要先渲染完整页面截图再裁剪,性能略低。
- 方案二更高效,直接针对可见区域渲染,但需要临时操作DOM,注意避免影响页面原有交互。
- 两种方案都依赖浏览器原生API获取视口尺寸与滚动偏移,兼容性良好。
内容的提问来源于stack exchange,提问作者kdam
相关产品推荐
相关产品推荐

