You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用JavaScript(无外部库/框架)实现网页全屏截图(覆盖桌面端场景及移动端开发需求)

如何使用JavaScript(无外部库/框架)实现网页全屏截图(覆盖桌面端场景及移动端开发需求)

嘿,这个需求我太懂了!用手机确实没法搞全屏截图,而且不想碰在线工具的话,咱们完全可以用浏览器原生API来实现,不用任何第三方库。下面给你两种靠谱的纯JS方案,都是我自己试过能用的:


方案一:SVG+Canvas 纯原生渲染全屏页面内容

这个方法的核心思路是把页面的DOM结构序列化为SVG,再把SVG作为图像源绘制到Canvas上,最后导出为图片。好处是能捕获整个页面(包括超出视口的滚动内容),不需要用户额外授权,特别适合你要的项目主应用页面截图需求。

实现代码(直接可用)

function captureFullPageScreenshot() {
  // 1. 获取页面实际宽高(包含所有滚动内容的完整尺寸)
  const pageWidth = Math.max(
    document.body.scrollWidth,
    document.documentElement.scrollWidth,
    document.body.offsetWidth,
    document.documentElement.offsetWidth,
    document.documentElement.clientWidth
  );
  const pageHeight = Math.max(
    document.body.scrollHeight,
    document.documentElement.scrollHeight,
    document.body.offsetHeight,
    document.documentElement.offsetHeight,
    document.documentElement.clientHeight
  );

  // 2. 创建SVG容器,嵌入页面DOM内容
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  svg.setAttribute('width', pageWidth);
  svg.setAttribute('height', pageHeight);
  svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');

  // 用foreignObject标签包裹DOM内容,让SVG能解析HTML
  const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
  foreignObject.setAttribute('width', '100%');
  foreignObject.setAttribute('height', '100%');
  foreignObject.setAttribute('x', 0);
  foreignObject.setAttribute('y', 0);
  foreignObject.setAttribute('externalResourcesRequired', 'true');

  // 克隆页面主体DOM,避免修改原页面结构
  const clonedBody = document.body.cloneNode(true);
  // 修复克隆元素的样式,确保能完整渲染
  clonedBody.style.width = `${pageWidth}px`;
  clonedBody.style.height = `${pageHeight}px`;
  clonedBody.style.margin = '0';
  clonedBody.style.padding = '0';
  clonedBody.style.overflow = 'visible';

  foreignObject.appendChild(clonedBody);
  svg.appendChild(foreignObject);

  // 3. 将SVG转为Blob URL,作为图片源
  const svgData = new XMLSerializer().serializeToString(svg);
  const svgBlob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
  const svgUrl = URL.createObjectURL(svgBlob);

  // 4. 创建Canvas并绘制SVG内容
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.width = pageWidth;
  canvas.height = pageHeight;

  const img = new Image();
  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    URL.revokeObjectURL(svgUrl); // 及时释放内存,避免内存泄漏

    // 5. 导出图片:自动下载到本地
    const link = document.createElement('a');
    link.download = 'project-full-screenshot.png';
    link.href = canvas.toDataURL('image/png');
    link.click();

    // 可选:如果想把截图显示在页面上,取消下面的注释
    // canvas.style.border = '1px solid #ccc';
    // document.body.appendChild(canvas);
  };
  img.src = svgUrl;
}

// 触发方式:可以在浏览器控制台直接执行,或者加个按钮点击触发
// 比如:document.querySelector('#screenshot-btn').addEventListener('click', captureFullPageScreenshot);

注意事项

  • 部分复杂CSS属性(如高级滤镜、自定义字体、复杂渐变)可能渲染不完全,SVG的foreignObject对CSS的支持有一定限制,遇到这种情况可以尝试把复杂样式转为内联形式,或者简化样式
  • 跨域的外部资源(如第三方图片、字体)会因为CORS策略无法渲染,需要目标服务器配置Access-Control-Allow-Origin头,或者把资源转为Base64内联到页面中

方案二:利用浏览器getDisplayMedia API 截取整个窗口

如果你需要的是包括浏览器地址栏、标签页在内的完整窗口截图,可以用这个方案。它调用浏览器原生的屏幕捕获API,不过需要用户手动授权允许捕获屏幕。

实现代码

function captureBrowserWindow() {
  // 请求用户授权捕获浏览器窗口
  navigator.mediaDevices.getDisplayMedia({
    video: {
      displaySurface: 'browser', // 指定捕获浏览器窗口,可选'monitor'捕获整个显示器
      cursor: 'always' // 显示鼠标光标
    },
    audio: false // 不需要捕获音频
  }).then(stream => {
    const video = document.createElement('video');
    video.srcObject = stream;
    video.muted = true; // 静音避免播放反馈
    video.onloadedmetadata = function () {
      // 创建Canvas绘制当前视频帧(即截图)
      const canvas = document.createElement('canvas');
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(video, 0, 0);

      // 导出图片
      const link = document.createElement('a');
      link.download = 'browser-window-screenshot.png';
      link.href = canvas.toDataURL('image/png');
      link.click();

      // 停止媒体流,释放资源
      stream.getTracks().forEach(track => track.stop());
    };
    // 加载视频流
    video.play();
  }).catch(err => {
    console.error('截图失败:', err);
    alert('无法完成截图,请检查浏览器权限设置,或确保当前环境为HTTPS/localhost');
  });
}

// 触发方式:同样可以在控制台执行,或绑定到按钮
// captureBrowserWindow();

注意事项

  • 必须在HTTPS环境下使用(本地开发的localhost/127.0.0.1例外)
  • 需要用户手动点击授权弹窗,无法自动触发截图
  • 只能捕获用户选择的窗口/显示器的实时画面,如果页面有超出视口的内容,需要先滚动到对应位置,或者用方案一捕获完整页面内容

最后小提示

如果你现在用手机开发,没法操作电脑的话,可以把方案一的代码放到你的项目页面里,加个隐藏的按钮,然后用手机浏览器打开项目页面,点击按钮就能自动下载全屏截图了,亲测有效!

如果遇到样式渲染问题,优先检查是不是有跨域资源,或者复杂CSS属性,调整一下基本就能解决~

火山引擎 最新活动