最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端html2canvas使用場(chǎng)景的詳細(xì)教程

 更新時(shí)間:2025年11月04日 10:11:22   作者:七梔?  
html2canvas是一個(gè)前端JavaScript庫(kù),能夠?qū)eb頁面中的DOM元素渲染為高保真的圖片,適用于生成頁面截圖或?qū)崿F(xiàn)打印預(yù)覽功能,這篇文章主要介紹了前端html2canvas使用場(chǎng)景的相關(guān)資料,需要的朋友可以參考下

前言

html2canvas 是前端常用的 “DOM 轉(zhuǎn)圖片” 庫(kù),核心是將頁面 DOM 節(jié)點(diǎn)渲染為 Canvas,再轉(zhuǎn)為圖片(Base64 或 Blob)。以下是 9 種核心使用場(chǎng)景的詳細(xì)教程,包含代碼示例、參數(shù)配置、問題解決,覆蓋日常開發(fā)需求。

一、基礎(chǔ)使用:將指定 DOM 轉(zhuǎn)為 Base64 圖片

適用于簡(jiǎn)單場(chǎng)景(如生成證書、截圖分享),無需復(fù)雜配置。

1. 安裝與引入

# npm 安裝
npm install html2canvas --save

javascript

// 模塊化項(xiàng)目引入(Vue/React/Angular)
import html2canvas from 'html2canvas';

// 非模塊化項(xiàng)目(直接引入 CDN)
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>

2. 核心代碼

html

<!-- 目標(biāo) DOM:需要轉(zhuǎn)為圖片的容器 -->
<div id="targetDom" style="width: 300px; height: 200px; background: #f5f5f5; padding: 20px;">
  <h2>基礎(chǔ)截圖示例</h2>
  <p>這是要轉(zhuǎn)為圖片的內(nèi)容</p>
</div>

<!-- 圖片預(yù)覽容器 -->
<img id="previewImg" style="margin-top: 20px; max-width: 100%;" />

javascript

// 觸發(fā)截圖(如點(diǎn)擊按鈕后)
document.querySelector('#btn').addEventListener('click', async () => {
  // 1. 獲取目標(biāo) DOM
  const targetDom = document.getElementById('targetDom');
  
  // 2. 調(diào)用 html2canvas 生成 Canvas
  const canvas = await html2canvas(targetDom, {
    scale: 2, // 2倍縮放,避免圖片模糊(關(guān)鍵參數(shù))
    useCORS: true, // 允許跨域圖片(如網(wǎng)絡(luò)圖片)
    logging: false, // 關(guān)閉控制臺(tái)日志
    backgroundColor: null // 保留 DOM 原有背景(默認(rèn)白色)
  });
  
  // 3. Canvas 轉(zhuǎn)為 Base64 圖片(支持 jpeg/png)
  const base64Img = canvas.toDataURL('image/jpeg', 1.0); // 1.0 表示質(zhì)量(0-1)
  
  // 4. 預(yù)覽圖片
  document.getElementById('previewImg').src = base64Img;
  
  // 5. (可選)下載圖片
  const link = document.createElement('a');
  link.href = base64Img;
  link.download = '基礎(chǔ)截圖.jpg';
  link.click();
});

二、進(jìn)階場(chǎng)景:處理跨域圖片

當(dāng) DOM 中包含網(wǎng)絡(luò)圖片(如 https://xxx.com/xxx.jpg),易出現(xiàn) “圖片空白” 問題,需配置跨域參數(shù)。

關(guān)鍵配置

  • 前端配置useCORS: true + allowTaint: true(允許跨域圖片污染 Canvas);
  • 后端配置:圖片服務(wù)器需返回 Access-Control-Allow-Origin: *(或當(dāng)前域名),否則跨域圖片仍會(huì)空白。

完整代碼

javascript

const canvas = await html2canvas(targetDom, {
  scale: 2,
  useCORS: true, // 允許加載跨域圖片
  allowTaint: true, // 允許 Canvas 被跨域圖片污染(否則圖片會(huì)被過濾)
  logging: false,
  // (可選)處理跨域圖片加載失敗的情況
  onclone: (clonedDoc) => {
    // clonedDoc 是 DOM 克隆體,可在此修改圖片地址
    const imgs = clonedDoc.querySelectorAll('img');
    imgs.forEach(img => {
      // 替換圖片為同源地址(若后端未配置 CORS 時(shí)的備選方案)
      if (img.src.includes('跨域域名')) {
        img.src = img.src.replace('跨域域名', '同源代理域名');
      }
    });
  }
});

三、復(fù)雜場(chǎng)景:固定寬高 + 滾動(dòng)內(nèi)容截圖

適用于 “長(zhǎng)列表截圖”(如表格、聊天記錄),需固定截圖寬高,同時(shí)包含滾動(dòng)區(qū)域的所有內(nèi)容。

核心思路

  • 先保存目標(biāo) DOM 的原始樣式(overflow/height);
  • 臨時(shí)修改為 overflow: visible + 自適應(yīng)高度(確保所有內(nèi)容展開);
  • 截圖完成后恢復(fù)原始樣式。

完整代碼

javascript

async function captureScrollContent() {
  const targetDom = document.getElementById('targetDom');
  // 1. 保存原始樣式
  const originalStyle = {
    overflow: targetDom.style.overflow,
    height: targetDom.style.height
  };
  
  try {
    // 2. 臨時(shí)修改樣式:展開所有滾動(dòng)內(nèi)容
    targetDom.style.overflow = 'visible';
    targetDom.style.height = 'auto'; // 自適應(yīng)高度,顯示所有內(nèi)容
    
    // 3. 截圖(固定寬高,避免內(nèi)容變形)
    const canvas = await html2canvas(targetDom, {
      scale: 2,
      useCORS: true,
      logging: false,
      windowWidth: targetDom.offsetWidth, // 固定截圖寬度
      windowHeight: targetDom.offsetHeight // 固定截圖高度(此時(shí)已包含所有內(nèi)容)
    });
    
    // 4. 轉(zhuǎn)為圖片并下載
    const base64Img = canvas.toDataURL('image/png', 1.0);
    const link = document.createElement('a');
    link.href = base64Img;
    link.download = '長(zhǎng)列表截圖.png';
    link.click();
    
  } finally {
    // 5. 恢復(fù)原始樣式(無論成功失敗都要恢復(fù))
    targetDom.style.overflow = originalStyle.overflow;
    targetDom.style.height = originalStyle.height;
  }
}

// 調(diào)用
captureScrollContent();

四、Vue 項(xiàng)目:組件內(nèi) DOM 截圖(含響應(yīng)式數(shù)據(jù))

Vue 中需注意 “DOM 渲染時(shí)機(jī)”—— 確保數(shù)據(jù)更新后(如接口請(qǐng)求完成)再截圖,避免內(nèi)容空白。

核心注意點(diǎn)

  • 用 this.$nextTick() 確保 DOM 已更新;
  • 若用 v-for 渲染列表,需等待列表渲染完成后再截圖。

完整代碼(Vue 3 示例)

vue

<template>
  <div>
    <!-- 目標(biāo) DOM:包含響應(yīng)式數(shù)據(jù) -->
    <div ref="certDom" class="cert-container">
      <h2>{{ userName }} 的證書</h2>
      <p>項(xiàng)目:{{ projectName }}</p>
      <p>時(shí)間:{{ date }}</p>
    </div>
    
    <button @click="generateCert">生成證書</button>
    <img :src="previewImg" alt="證書預(yù)覽" style="max-width: 100%; margin-top: 20px;" />
  </div>
</template>

<script setup>
import { ref, nextTick } from 'vue';
import html2canvas from 'html2canvas';

// 響應(yīng)式數(shù)據(jù)
const userName = ref('');
const projectName = ref('');
const date = ref('2025-01-01');
const previewImg = ref('');
const certDom = ref(null); // 目標(biāo) DOM 引用

// 接口請(qǐng)求:獲取用戶數(shù)據(jù)
const fetchUserInfo = async () => {
  const res = await fetch('/api/user');
  const data = await res.json();
  userName.value = data.userName;
  projectName.value = data.projectName;
};

// 生成證書(截圖)
const generateCert = async () => {
  // 1. 先獲取數(shù)據(jù),確保 DOM 已更新
  await fetchUserInfo();
  // 2. 等待 Vue DOM 渲染完成
  await nextTick();
  
  // 3. 截圖(certDom.value 是目標(biāo) DOM)
  const canvas = await html2canvas(certDom.value, {
    scale: 2,
    useCORS: true,
    backgroundColor: '#fff'
  });
  
  // 4. 預(yù)覽并下載
  previewImg.value = canvas.toDataURL('image/jpeg', 1.0);
  const link = document.createElement('a');
  link.href = previewImg.value;
  link.download = `${userName.value}的證書.jpg`;
  link.click();
};
</script>

<style scoped>
.cert-container {
  width: 500px;
  height: 700px;
  background: url('@/assets/cert-bg.jpg') no-repeat center;
  background-size: 100% 100%;
  padding: 50px;
  box-sizing: border-box;
}
</style>

五、React 項(xiàng)目:函數(shù)組件截圖(含 Hooks)

React 中需用 useRef 獲取 DOM 節(jié)點(diǎn),用 useEffect 處理異步渲染時(shí)機(jī)。

完整代碼(React 18 示例)

jsx

import { useRef, useState } from 'react';
import html2canvas from 'html2canvas';

const ScreenshotComponent = () => {
  // 1. 獲取目標(biāo) DOM 引用
  const targetRef = useRef(null);
  // 2. 預(yù)覽圖片狀態(tài)
  const [previewImg, setPreviewImg] = useState('');

  // 截圖函數(shù)
  const captureDom = async () => {
    if (!targetRef.current) return;
    
    // 3. 調(diào)用 html2canvas
    const canvas = await html2canvas(targetRef.current, {
      scale: 2,
      useCORS: true,
      logging: false
    });
    
    // 4. 轉(zhuǎn)為圖片
    const base64 = canvas.toDataURL('image/png', 1.0);
    setPreviewImg(base64);
    
    // 5. 下載圖片
    const link = document.createElement('a');
    link.href = base64;
    link.download = 'react截圖.png';
    link.click();
  };

  return (
    <div style={{ padding: 20 }}>
      {/* 目標(biāo) DOM:用 ref 綁定 */}
      <div 
        ref={targetRef} 
        style={{ width: 400, height: 300, background: '#e8f4f8', padding: 20 }}
      >
        <h3>React 截圖示例</h3>
        <p>當(dāng)前時(shí)間:{new Date().toLocaleString()}</p>
      </div>
      
      <button onClick={captureDom} style={{ margin: 20 }}>生成截圖</button>
      {previewImg && <img src={previewImg} alt="預(yù)覽" style={{ maxWidth: '100%' }} />}
    </div>
  );
};

export default ScreenshotComponent;

六、特殊場(chǎng)景:隱藏 DOM 截圖(不顯示在頁面)

適用于 “后臺(tái)生成圖片”(如生成后直接下載,無需在頁面顯示 DOM),需臨時(shí)將 DOM 渲染到頁面外。

核心思路

  • 目標(biāo) DOM 初始樣式設(shè)為 position: absolute; left: -9999px; top: -9999px;(隱藏在視口外);
  • 截圖完成后可刪除該 DOM(可選)。

完整代碼

html

<!-- 隱藏的目標(biāo) DOM:在視口外渲染 -->
<div id="hiddenDom" style="position: absolute; left: -9999px; top: -9999px; width: 500px; height: 300px; background: #fff; padding: 30px;">
  <h2>隱藏 DOM 生成的圖片</h2>
  <p>用戶:張三</p>
  <p>等級(jí):VIP</p>
</div>

<button id="generateBtn">生成隱藏圖片</button>

javascript

document.getElementById('generateBtn').addEventListener('click', async () => {
  const hiddenDom = document.getElementById('hiddenDom');
  
  // 截圖(與正常 DOM 一致)
  const canvas = await html2canvas(hiddenDom, {
    scale: 2,
    useCORS: true,
    logging: false
  });
  
  // 下載圖片
  const base64 = canvas.toDataURL('image/jpeg', 1.0);
  const link = document.createElement('a');
  link.href = base64;
  link.download = '隱藏DOM圖片.jpg';
  link.click();
  
  // (可選)截圖后刪除隱藏 DOM
  // hiddenDom.remove();
});

七、性能優(yōu)化:批量截圖 + 避免重復(fù)渲染

當(dāng)需要批量生成圖片(如多條數(shù)據(jù)生成證書),需控制截圖順序,避免同時(shí)渲染導(dǎo)致瀏覽器卡頓。

核心思路

  • 用 async/await 按順序截圖(一條完成后再截下一條);
  • 截圖前判斷是否已生成,避免重復(fù)操作。

完整代碼

javascript

// 批量數(shù)據(jù)(如多條證書信息)
const certList = [
  { id: 1, userName: '張三', project: '前端開發(fā)' },
  { id: 2, userName: '李四', project: '后端開發(fā)' },
  { id: 3, userName: '王五', project: 'UI設(shè)計(jì)' }
];

// 批量截圖函數(shù)
async function batchCapture() {
  for (const cert of certList) {
    // 1. 動(dòng)態(tài)創(chuàng)建目標(biāo) DOM(每條數(shù)據(jù)一個(gè) DOM)
    const tempDom = document.createElement('div');
    tempDom.style.width = '500px';
    tempDom.style.height = '700px';
    tempDom.style.background = '#fff';
    tempDom.style.padding = '50px';
    tempDom.style.position = 'absolute';
    tempDom.style.left = '-9999px'; // 隱藏在視口外
    tempDom.innerHTML = `
      <h2>${cert.userName} 的證書</h2>
      <p>項(xiàng)目:${cert.project}</p>
      <p>日期:2025-01-01</p>
    `;
    document.body.appendChild(tempDom);
    
    try {
      // 2. 截圖(按順序執(zhí)行)
      const canvas = await html2canvas(tempDom, {
        scale: 2,
        useCORS: true,
        logging: false
      });
      
      // 3. 下載圖片
      const base64 = canvas.toDataURL('image/jpeg', 1.0);
      const link = document.createElement('a');
      link.href = base64;
      link.download = `${cert.userName}的證書.jpg`;
      link.click();
      
    } finally {
      // 4. 移除臨時(shí) DOM(避免內(nèi)存占用)
      document.body.removeChild(tempDom);
      // (可選)延遲 500ms,避免瀏覽器卡頓
      await new Promise(resolve => setTimeout(resolve, 500));
    }
  }
}

// 調(diào)用批量截圖
batchCapture();

八、問題解決:常見報(bào)錯(cuò)與優(yōu)化方案

1. 圖片模糊

  • 原因:Canvas 默認(rèn)縮放為 1,屏幕 DPI 過高(如 Retina 屏)導(dǎo)致模糊;
  • 解決:設(shè)置 scale: 2 或 scale: window.devicePixelRatio(自適應(yīng)屏幕 DPI)。

javascript

const canvas = await html2canvas(targetDom, {
  scale: window.devicePixelRatio, // 自適應(yīng)屏幕縮放
  useCORS: true
});

2. 跨域圖片空白

  • 原因:圖片服務(wù)器未配置 CORS,或未開啟 useCORS: true;
  • 解決

    后端添加 Access-Control-Allow-Origin 響應(yīng)頭;

    前端配置 useCORS: true + allowTaint: true;

    備選方案:用同源代理服務(wù)器轉(zhuǎn)發(fā)圖片(如 Nginx 代理)。

3. DOM 內(nèi)容未完全渲染(如接口數(shù)據(jù)空白)

  • 原因:截圖時(shí)機(jī)過早,DOM 尚未更新(如接口請(qǐng)求未完成);
  • 解決
    • Vue:用 this.$nextTick() 等待 DOM 渲染;
    • React:用 useEffect 或 await 等待數(shù)據(jù)加載;
    • 原生 JS:在接口 then 回調(diào)中執(zhí)行截圖。

4. 大 DOM 截圖卡頓

  • 原因:DOM 節(jié)點(diǎn)過多(如長(zhǎng)列表、復(fù)雜表格),渲染耗時(shí);
  • 解決

    簡(jiǎn)化 DOM(移除截圖無關(guān)的節(jié)點(diǎn),如隱藏按鈕、多余注釋);

    分批截圖(避免一次性渲染大量節(jié)點(diǎn));

    關(guān)閉日志:logging: false(減少控制臺(tái)輸出耗時(shí))。

九、高級(jí)場(chǎng)景:Canvas 轉(zhuǎn) Blob 上傳服務(wù)器

當(dāng)需要將生成的圖片上傳到后端(而非本地下載),需將 Canvas 轉(zhuǎn)為 Blob 格式(比 Base64 更節(jié)省帶寬)。

完整代碼

javascript

async function captureAndUpload() {
  const targetDom = document.getElementById('targetDom');
  const canvas = await html2canvas(targetDom, {
    scale: 2,
    useCORS: true,
    logging: false
  });
  
  // 1. Canvas 轉(zhuǎn)為 Blob(支持指定格式和質(zhì)量)
  canvas.toBlob(async (blob) => {
    // 2. 構(gòu)建 FormData(用于上傳)
    const formData = new FormData();
    formData.append('image', blob, '上傳圖片.jpg'); // 第三個(gè)參數(shù)是文件名
    formData.append('userId', '123'); // 其他參數(shù)(如用戶ID)
    
    // 3. 上傳到服務(wù)器
    try {
      const res = await fetch('/api/upload-image', {
        method: 'POST',
        body: formData,
        // 注意:FormData 上傳無需設(shè)置 Content-Type,瀏覽器會(huì)自動(dòng)處理
      });
      
      const data = await res.json();
      if (data.success) {
        alert('圖片上傳成功!');
        console.log('圖片地址:', data.imageUrl);
      }
    } catch (err) {
      console.error('上傳失?。?, err);
    }
  }, 'image/jpeg', 0.8); // 0.8 表示圖片質(zhì)量(0-1,值越高質(zhì)量越好)
}

// 調(diào)用
captureAndUpload();

總結(jié) 

到此這篇關(guān)于前端html2canvas使用場(chǎng)景的文章就介紹到這了,更多相關(guān)前端html2canvas使用場(chǎng)景內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決eclipse中沒有js代碼提示的問題

    解決eclipse中沒有js代碼提示的問題

    今天小編就為大家分享一篇解決eclipse中沒有js代碼提示的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • 解析arp病毒背后利用的Javascript技術(shù)附解密方法

    解析arp病毒背后利用的Javascript技術(shù)附解密方法

    解析arp病毒背后利用的Javascript技術(shù)附解密方法...
    2007-08-08
  • js千分位實(shí)現(xiàn)方法大匯總

    js千分位實(shí)現(xiàn)方法大匯總

    這篇文章主要介紹了js千分位實(shí)現(xiàn)方法大匯總,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • js判斷FCKeditor內(nèi)容是否為空的兩種形式

    js判斷FCKeditor內(nèi)容是否為空的兩種形式

    FCKeditor內(nèi)容是否為空在提交表單時(shí)一定要判斷的,下面與大家分享下兩種形式,感興趣的朋友可以參考下哈
    2013-05-05
  • 利用TypeScript編寫貪吃蛇游戲

    利用TypeScript編寫貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了如何利用TypeScript編寫貪吃蛇游戲,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的可以了解一下
    2022-09-09
  • JavaScript監(jiān)聽觸摸事件代碼實(shí)例

    JavaScript監(jiān)聽觸摸事件代碼實(shí)例

    這篇文章主要介紹了JavaScript監(jiān)聽觸摸事件代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • javascript 動(dòng)態(tài)修改css樣式方法匯總(四種方法)

    javascript 動(dòng)態(tài)修改css樣式方法匯總(四種方法)

    為了達(dá)到某種特殊的效果我們需要用Javascript動(dòng)態(tài)的去更改某一個(gè)標(biāo)簽的Css屬性,如何動(dòng)態(tài)修改css樣式呢?面對(duì)這個(gè)問題,小編帶領(lǐng)大家來解決javascript動(dòng)態(tài)修改css樣式,小伙伴們都快來學(xué)習(xí)吧
    2015-08-08
  • JavaScript 閉包:函數(shù)背后的“背包”(一文詳解)

    JavaScript 閉包:函數(shù)背后的“背包”(一文詳解)

    文章詳細(xì)解釋了JavaScript閉包的概念及其作用,包括數(shù)據(jù)封裝、函數(shù)柯里化和異步回調(diào)中的的狀態(tài)保持,并通過實(shí)例展示了閉閉如何工作以及如何避免潛在的內(nèi)存泄漏問題,感興趣的朋友一起看看吧
    2026-05-05
  • bootstrap table實(shí)現(xiàn)合并單元格效果

    bootstrap table實(shí)現(xiàn)合并單元格效果

    這篇文章主要為大家詳細(xì)介紹了bootstrap table實(shí)現(xiàn)合并單元格效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • js實(shí)現(xiàn)隨機(jī)div顏色位置 類似滿天星效果

    js實(shí)現(xiàn)隨機(jī)div顏色位置 類似滿天星效果

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)隨機(jī)div顏色位置,類似滿天星效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10

最新評(píng)論

徐水县| 乌兰浩特市| 昌平区| 社会| 遵义县| 霍州市| 新和县| 西青区| 叙永县| 元朗区| 漳浦县| 阳山县| 淮滨县| 郎溪县| 德清县| 赣榆县| 宁夏| 安化县| 衡阳市| 长垣县| 彰武县| 科尔| 闽侯县| 尼木县| 宜良县| 秦皇岛市| 白沙| 无棣县| 临沭县| 麻城市| 黄龙县| 永川市| 梅河口市| 丰顺县| 青铜峡市| 金湖县| 怀柔区| 甘洛县| 达尔| 阳曲县| 金阳县|