<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          飛書一鍵復(fù)制網(wǎng)頁內(nèi)容為圖片原理

          共 3457字,需瀏覽 7分鐘

           ·

          2024-08-16 09:10

             

          很多2C的移動端H5應(yīng)用,都會有邀請好友、分享之類的,通常會在前端實時生成一副海報圖片,用戶可以分享到朋友圈等,這類需求都需要解決前端DOM轉(zhuǎn)圖片的問題。今天帶來一篇文章,作者從飛書的一鍵復(fù)制網(wǎng)頁內(nèi)容為圖片,層層分解前端涉及到的技術(shù)點,希望大家看完有收獲。

          下面是正文部分。



          李經(jīng)理在使用飛書時無意中發(fā)現(xiàn),飛書竟然支持一鍵復(fù)制網(wǎng)頁內(nèi)容到剪貼板的功能。

          他立即叫來了公司的前端開發(fā)小王,興致勃勃地說:

          "小王啊,你看,飛書的這個功能多方便!我們公司的協(xié)同辦公系統(tǒng)是不是也可以實現(xiàn)類似的功能?這樣用戶體驗一定能得到很大提升!"

          小王看著李經(jīng)理充滿expectant的眼神, 雖然內(nèi)心已經(jīng)吐槽"就這點功能至于嗎", 但表面上還是恭恭敬敬地回答:

          "老板英明,這個功能確實很實用。技術(shù)上應(yīng)該不難實現(xiàn),主要就是用Clipboard API寫幾行代碼的事。我這就去安排!"

          回到工位后,小王苦笑著搖搖頭,找來相關(guān)文檔開始翻閱,暗暗發(fā)誓一定要把這個"劃時代"的功能做好.

          小王找來了領(lǐng)導(dǎo)說的飛書文檔復(fù)制網(wǎng)頁內(nèi)容的功能, 如下:

          小王思考了片刻…

          功能拆解:

          要實現(xiàn)這個功能, 要拆分為4個步驟:

          1. 獲得選中內(nèi)容所屬的 div

          2. 把選中內(nèi)容的div 轉(zhuǎn)換成canvas

          3. 轉(zhuǎn)換canvas到二進制圖像

          4. 復(fù)制二進制圖像到剪貼板

          由于小王的業(yè)務(wù)只需要復(fù)制固定區(qū)域的div, 所以第一步可以忽略, 簡化成:


          const element = document.getElementById("target");

          轉(zhuǎn)換div成 canvas:

          時間已經(jīng)很晚了, 小王咳了一杯咖啡, 繼續(xù)奮戰(zhàn). 小王苦思冥想, 要怎么把div轉(zhuǎn)換成 canvas. 他琢磨:

          1. 遞歸遍歷 DOM 樹:

            • 會從指定的根元素開始,遞歸遍歷整個 DOM 樹。

            • 對于每個遇到的元素, 分析其樣式、位置、大小等屬性。

          2. 處理樣式和布局:

            • 通過讀取元素的 CSS 樣式,如顏色、背景、邊框等, 復(fù)制元素的視覺表現(xiàn)。

            • 它會計算元素的盒模型、定位、層疊等布局信息,以確定元素在最終圖片中的位置。

          小王這時候已經(jīng)覺得很累了, 于是索性打開瀏覽器搜索, 結(jié)果第一頁就看到了: html2canvas. 他看了一眼, github 29K stars. 他查看了一下調(diào)用api:


          html2canvas(document.body).then(function(canvas) {
          document.body.appendChild(canvas);
          });

          它正是小王需要的!

          于是小王在項目中命令行輸入:


          npm install --save html2canvas

          然后小王在業(yè)務(wù)代碼中敲下了:


          function copyDivToImage() {
          const element = document.getElementById("target");
          html2canvas(element).then(canvas => {
          // canvas 拿到了, 然后呢
          }
          }

          轉(zhuǎn)換canvas到二進制圖像

          小王猶豫, 為什么要轉(zhuǎn)成二進制圖像呢, 我直接復(fù)制 base64 字符不行嗎. 不過很快, 小王就意識到了, 剪貼版API 不支持base64字符串的類型. 于是他翻開 mdn 文檔:

          HTMLCanvasElement: toBlob() method - Web APIs | MDN (mozilla.org)



          function copyDivToImage() {
          const element = document.getElementById("target");
          html2canvas(element).then(canvas => {
          canvas.toBlob(
          (blob) => {
          // 復(fù)制文件到剪貼板
          },
          "image/jpeg", // 文件的格式
          1 // 圖像壓縮質(zhì)量 0-1
          );
          });
          }

          復(fù)制二進制圖像到剪貼板

          這一步小王已經(jīng)先前看過 MDN 文檔了, ClipboardItem - Web APIs | MDN (mozilla.org) 可以直接調(diào)用瀏覽器的 navigator api :



          function copyDivToImage() {
          const element = document.getElementById("target");
          html2canvas(element).then(canvas => {
          canvas.toBlob(
          (blob) => {
          // 復(fù)制文件到剪貼板
          try {
          await navigator.clipboard.write([
          // eslint-disable-next-line no-undef
          new ClipboardItem({
          [blob.type]: blob
          })
          ]);
          console.log("圖像已成功復(fù)制到剪??板");
          } catch (err) {
          console.error("無法復(fù)制圖像到剪貼板", err);
          }
          },
          "image/jpeg", // 文件的格式
          1 // 圖像壓縮質(zhì)量 0-1
          );
          });
          }

          小王遇到挫折

          所有代碼已經(jīng)就緒, 小王隨即啟動項目, 運行他剛剛編寫好的完美的代碼. 不出所料,  他遇到了挫折:

          小王看到這個報錯, 完全沒有頭緒, 幸好有多年的開發(fā)經(jīng)驗, 他遇到這種問題的時候并沒有慌張, 內(nèi)心想, “第一次跑通常這樣!”. 隨即他打開百度搜索, 有一個回答引起了小王的注意:

          原來, 小王是在 http 環(huán)境調(diào)試的, 他修改了代理的配置, 換成了 https 環(huán)境下調(diào)試本地代碼.

          然而讓小王沒有想到的是, 程序還是沒有如期運行, 小王遇到了第二個挫折:

          小王崩潰了 “這是什么鬼. 明明都是按照API文檔寫的!”

          原來, 瀏覽器剪貼板對 jpeg的支持不大好, 于是小王把 canvas.toBlob() 的參數(shù)改成了 "image/png”.

          他再次運行代碼, 他成功了:

          小王欣喜地把這個消息告訴了李經(jīng)理.

          功夫不負有心人,憑借扎實的JavaScript功底,小王很快就實現(xiàn)了一個簡潔優(yōu)雅的"一鍵復(fù)制"功能,并成功集成到公司的協(xié)同辦公系統(tǒng)中。

          李經(jīng)理在看到小王的杰作后非常滿意,當即表揚了小王的能力和效率,并承諾會在年終績效考核中給予小王優(yōu)秀評級,同時還暗示未來會給小王升職加薪的機會。小王聽后喜上眉梢,他明白自己的努力和才能得到了老板的認可。

          這次經(jīng)歷不僅鞏固了小王在公司中的地位,更堅定了他在前端開發(fā)領(lǐng)域繼續(xù)鉆研的決心。他暗自慶幸,幸虧當初學(xué)習(xí)JavaScript時沒有偷懶,才能在關(guān)鍵時刻派上用場,贏得了老板的青睞。

          從此以后,小王在技術(shù)方面更加勤奮刻苦,也更加善于捕捉用戶需求和痛點,設(shè)計出更多優(yōu)秀的功能和體驗。他逐漸成長為團隊中不可或缺的核心成員,并最終如愿晉升為高級前端開發(fā)工程師,走上了實現(xiàn)自我價值和理想的康莊大道。

          作者:ziolau

          https://juejin.cn/post/7348634049681293312

          瀏覽 291
          2點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          2點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  12一14女人毛片 | 999综合色 | 欧美A片免费观看 | 亚洲综合五月天婷婷 | 亚洲巨幕av |