整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          手把手教你前端的各種文件上傳攻略和大文件斷點續傳



          在前面

          今年國慶假期終于可以憋在家里了不用出門了,不用出去看后腦了,真的是一種享受。這么好的光陰怎么浪費,睡覺、吃飯、打豆豆這怎么可能(耍多了也煩),完全不符合我們程序員的作風,趕緊起來把文章寫完。

          這篇文章比較基礎,在國慶期間的業余時間寫的,這幾天又完善了下,力求把更多的前端所涉及到的關于文件上傳的各種場景和應用都涵蓋了,若有疏漏和問題還請留言斧正和補充。

          自測讀不讀

          以下是本文所涉及到的知識點,break or continue ?

          • 文件上傳原理
          • 最原始的文件上傳
          • 使用 koa2 作為服務端寫一個文件上傳接口
          • 單文件上傳和上傳進度
          • 多文件上傳和上傳進度
          • 拖拽上傳
          • 剪貼板上傳
          • 大文件上傳之分片上傳
          • 大文件上傳之斷點續傳
          • node 端文件上傳

          原理概述

          原理很簡單,就是根據 http 協議的規范和定義,完成請求消息體的封裝和消息體的解析,然后將二進制內容保存到文件。

          我們都知道如果要上傳一個文件,需要把 form 標簽的enctype設置為multipart/form-data,同時method必須為post方法。

          那么multipart/form-data表示什么呢?

          multipart互聯網上的混合資源,就是資源由多種元素組成,form-data表示可以使用HTML Forms 和 POST 方法上傳文件,具體的定義可以參考RFC 7578。

          multipart/form-data 結構

          看下 http 請求的消息體



          • 請求頭:

          Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDCntfiXcSkPhS4PN 表示本次請求要上傳文件,其中boundary表示分隔符,如果要上傳多個表單項,就要使用boundary分割,每個表單項由———XXX開始,以———XXX結尾。

          • 消息體- Form Data 部分

          每一個表單項又由Content-Type和Content-Disposition組成。

          Content-Disposition: form-data 為固定值,表示一個表單元素,name 表示表單元素的 名稱,回車換行后面就是name的值,如果是上傳文件就是文件的二進制內容。

          Content-Type:表示當前的內容的 MIME 類型,是圖片還是文本還是二進制數據。

          解析

          客戶端發送請求到服務器后,服務器會收到請求的消息體,然后對消息體進行解析,解析出哪是普通表單哪些是附件。

          可能大家馬上能想到通過正則或者字符串處理分割出內容,不過這樣是行不通的,二進制buffer轉化為string,對字符串進行截取后,其索引和字符串是不一致的,所以結果就不會正確,除非上傳的就是字符串。

          不過一般情況下不需要自行解析,目前已經有很成熟的三方庫可以使用。

          至于如何解析,這個也會占用很大篇幅,后面的文章在詳細說。

          最原始的文件上傳

          使用 form 表單上傳文件

          在 ie時代,如果實現一個無刷新的文件上傳那可是費老勁了,大部分都是用 iframe 來實現局部刷新或者使用 flash 插件來搞定,在那個時代 ie 就是最好用的瀏覽器(別無選擇)。

          DEMO



          這種方式上傳文件,不需要 js ,而且沒有兼容問題,所有瀏覽器都支持,就是體驗很差,導致頁面刷新,頁面其他數據丟失。

          HTML

           <form method="post" action="http://localhost:8100" enctype="multipart/form-data">
          
                  選擇文件:
                      <input type="file" name="f1"/> input 必須設置 name 屬性,否則數據無法發送<br/>
          <br/>
                      標題:<input type="text" name="title"/><br/><br/><br/>
          
                  <button type="submit" id="btn-0">上 傳</button>
          
          </form>
          
          復制代碼

          文件上傳接口

          服務端文件的保存基于現有的庫koa-body結合 koa2實現服務端文件的保存和數據的返回。

          在項目開發中,文件上傳本身和業務無關,代碼基本上都可通用。

          在這里我們使用koa-body庫來實現解析和文件的保存。

          koa-body 會自動保存文件到系統臨時目錄下,也可以指定保存的文件路徑。



          然后在后續中間件內得到已保存的文件的信息,再做二次處理。

          • ctx.request.files.f1 得到文件信息,f1為input file 標簽的 name
          • 獲得文件的擴展名,重命名文件

          NODE

          /**
           * 服務入口
           */
          var http = require('http');
          var koaStatic = require('koa-static');
          var path = require('path');
          var koaBody = require('koa-body');//文件保存庫
          var fs = require('fs');
          var Koa = require('koa2');
          
          var app = new Koa();
          var port = process.env.PORT || '8100';
          
          var uploadHost= `http://localhost:${port}/uploads/`;
          
          app.use(koaBody({
              formidable: {
                  //設置文件的默認保存目錄,不設置則保存在系統臨時目錄下  os
                  uploadDir: path.resolve(__dirname, '../static/uploads')
              },
              multipart: true // 開啟文件上傳,默認是關閉
          }));
          
          //開啟靜態文件訪問
          app.use(koaStatic(
              path.resolve(__dirname, '../static') 
          ));
          
          //文件二次處理,修改名稱
          app.use((ctx) => {
              var file = ctx.request.files.f1;//得道文件對象
              var path = file.path;
              var fname = file.name;//原文件名稱
              var nextPath = path+fname;
              if(file.size>0 && path){
                  //得到擴展名
                  var extArr = fname.split('.');
                  var ext = extArr[extArr.length-1];
                  var nextPath = path+'.'+ext;
                  //重命名文件
                  fs.renameSync(path, nextPath);
              }
              //以 json 形式輸出上傳文件地址
              ctx.body = `{
                  "fileUrl":"${uploadHost}${nextPath.slice(nextPath.lastIndexOf('/')+1)}"
              }`;
          });
          
          /**
           * http server
           */
          var server = http.createServer(app.callback());
          server.listen(port);
          console.log('demo1 server start ......   ');
          復制代碼

          CODE

          https://github.com/Bigerfe/fe-learn-code/

          譯自: https://medium.freecodecamp.org/for-your-first-html-code-lets-help-batman-write-a-love-letter-64c203b9360b

          作者: Kunal Sarkar

          譯者: MjSeven

          在一個美好的夜晚,你的肚子拒絕消化你在晚餐吃的大塊披薩,所以你不得不在睡夢中沖進洗手間。

          在浴室里,當你在思考為什么會發生這種情況時,你聽到一個來自通風口的低沉聲音:“嘿,我是蝙蝠俠。”

          這時,你會怎么做呢?

          在你恐慌并處于關鍵時刻之前,蝙蝠俠說:“我需要你的幫助。我是一個超級極客,但我不懂 HTML。我需要用 HTML 寫一封情書,你愿意幫助我嗎?”

          誰會拒絕蝙蝠俠的請求呢,對吧?所以讓我們用 HTML 來寫一封蝙蝠俠的情書。

          你的第一個 HTML 文件

          HTML 網頁與你電腦上的其它文件一樣。就同一個 .doc 文件以 MS Word 打開,.jpg 文件在圖像查看器中打開一樣,一個 .html 文件在瀏覽器中打開。

          那么,讓我們來創建一個 .html 文件。你可以在 Notepad 或其它任何編輯器中完成此任務,但我建議使用 VS Code。 在這里下載并安裝 VS Code 。它是免費的,也是我唯一喜歡的微軟產品。

          在系統中創建一個目錄,將其命名為 “HTML Practice”(不帶引號)。在這個目錄中,再創建一個名為 “Batman’s Love Letter”(不帶引號)的目錄,這將是我們的項目根目錄。這意味著我們所有與這個項目相關的文件都會在這里。

          打開 VS Code,按下 ctrl+n 創建一個新文件,按下 ctrl+s 保存文件。切換到 “Batman’s Love Letter” 文件夾并將其命名為 “loveletter.html”,然后單擊保存。

          現在,如果你在文件資源管理器中雙擊它,它將在你的默認瀏覽器中打開。我建議使用 Firefox 來進行 web 開發,但 Chrome 也可以。

          讓我們將這個過程與我們已經熟悉的東西聯系起來。還記得你第一次拿到電腦嗎?我做的第一件事是打開 MS Paint 并繪制一些東西。你在 Paint 中繪制一些東西并將其另存為圖像,然后你可以在圖像查看器中查看該圖像。之后,如果要再次編輯該圖像,你在 Paint 中重新打開它,編輯并保存它。

          我們目前的流程非常相似。正如我們使用 Paint 創建和編輯圖像一樣,我們使用 VS Code 來創建和編輯 HTML 文件。就像我們使用圖像查看器查看圖像一樣,我們使用瀏覽器來查看我們的 HTML 頁面。

          HTML 中的段落

          我們有一個空的 HTML 文件,以下是蝙蝠俠想在他的情書中寫的第一段。

          “After all the battles we fought together, after all the difficult times we saw together, and after all the good and bad moments we’ve been through, I think it’s time I let you know how I feel about you.”

          復制這些到 VS Code 中的 loveletter.html。單擊 “View -> Toggle Word Wrap (alt+z)” 自動換行。

          保存并在瀏覽器中打開它。如果它已經打開,單擊瀏覽器中的刷新按鈕。

          瞧!那是你的第一個網頁!

          我們的第一段已準備就緒,但這不是在 HTML 中編寫段落的推薦方法。我們有一種特定的方法讓瀏覽器知道一個文本是一個段落。

          如果你用 <p> 和 </p> 來包裹文本,那么瀏覽器將識別 <p> 和 </p> 中的文本是一個段落。我們這樣做:

          <p>After all the battles we fought together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.</p>

          通過在 <p> 和 </p>中編寫段落,你創建了一個 HTML 元素。一個網頁就是 HTML 元素的集合。

          讓我們首先來認識一些術語:<p> 是開始標簽,</p> 是結束標簽,“p” 是標簽名稱。元素開始和結束標簽之間的文本是元素的內容。

          “style” 屬性

          在上面,你將看到文本覆蓋屏幕的整個寬度。

          我們不希望這樣。沒有人想要閱讀這么長的行。讓我們設定段落寬度為 550px。

          我們可以通過使用元素的 style 屬性來實現。你可以在其 style 屬性中定義元素的樣式(例如,在我們的示例中為寬度)。以下行將在 p 元素上創建一個空樣式屬性:

          <p style="">...</p>

          你看到那個空的 "" 了嗎?這就是我們定義元素外觀的地方。現在我們要將寬度設置為 550px。我們這樣做:

          <p style="width:550px;">

          After all the battles we fought together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          我們將 width 屬性設置為 550px,用冒號 : 分隔,以分號 ; 結束。

          另外,注意我們如何將 <p> 和 </p> 放在單獨的行中,文本內容用一個制表符縮進。像這樣設置代碼使其更具可讀性。

          HTML 中的列表

          接下來,蝙蝠俠希望列出他所欽佩的人的一些優點,例如:

          You complete my darkness with your light. I love:

          - the way you see good in the worst things

          - the way you handle emotionally difficult situations

          - the way you look at Justice

          I have learned a lot from you. You have occupied a special place in my heart over time.

          這看起來很簡單。

          讓我們繼續,在 </p> 下面復制所需的文本:

          <p style="width:550px;">

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <p style="width:550px;">

          You complete my darkness with your light. I love:

          - the way you see good in the worse

          - the way you handle emotionally difficult situations

          - the way you look at Justice

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          保存并刷新瀏覽器。



          哇!這里發生了什么,我們的列表在哪里?

          如果你仔細觀察,你會發現沒有顯示換行符。在代碼中我們在新的一行中編寫列表項,但這些項在瀏覽器中顯示在一行中。

          如果你想在 HTML(新行)中插入換行符,你必須使用 <br>。讓我們來使用 <br>,看看它長什么樣:

          <p style="width:550px;">

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <p style="width:550px;">

          You complete my darkness with your light. I love: <br>

          - the way you see good in the worse <br>

          - the way you handle emotionally difficult situations <br>

          - the way you look at Justice <br>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          保存并刷新:



          好的,現在它看起來就像我們想要的那樣!

          另外,注意我們沒有寫一個 </br>。有些標簽不需要結束標簽(它們被稱為自閉合標簽)。

          還有一件事:我們沒有在兩個段落之間使用 <br>,但第二個段落仍然是從一個新行開始,這是因為 <p> 元素會自動插入換行符。

          我們使用純文本編寫列表,但是有兩個標簽可以供我們使用來達到相同的目的:<ul> and <li>。

          讓我們解釋一下名字的意思:ul 代表 無序列表(Unordered List),li 代表 列表項目(List Item)。讓我們使用它們來展示我們的列表:

          <p style="width:550px;">

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <p style="width:550px;">

          You complete my darkness with your light. I love:

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          在復制代碼之前,注意差異部分:

          • 我們刪除了所有的 <br>,因為每個 <li> 會自動顯示在新行中
          • 我們將每個列表項包含在 <li> 和 </li> 之間
          • 我們將所有列表項的集合包裹在 <ul> 和 </ul> 之間
          • 我們沒有像 <p> 元素那樣定義 <ul> 元素的寬度。這是因為 <ul> 是 <p> 的子節點,<p> 已經被約束到 550px,所以 <ul> 不會超出這個范圍。

          讓我們保存文件并刷新瀏覽器以查看結果:



          你會立即注意到在每個列表項之前顯示了重點標志。我們現在不需要在每個列表項之前寫 “-”。

          經過仔細檢查,你會注意到最后一行超出 550px 寬度。這是為什么?因為 HTML 不允許 <ul> 元素出現在 <p> 元素中。讓我們將第一行和最后一行放在單獨的 <p> 元素中:

          <p style="width:550px;">

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <p style="width:550px;">

          You complete my darkness with your light. I love:

          </p>

          <ul style="width:550px;">

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p style="width:550px;">

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          保存并刷新。

          注意,這次我們還定義了 <ul> 元素的寬度。那是因為我們現在已經將 <ul> 元素放在了 <p> 元素之外。

          定義情書中所有元素的寬度會變得很麻煩。我們有一個特定的元素用于此目的:<div> 元素。一個 <div> 元素就是一個通用容器,用于對內容進行分組,以便輕松設置樣式。

          讓我們用 <div> 元素包裝整個情書,并為其賦予寬度:550px 。

          <div style="width:550px;">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          </div>

          棒極了,我們的代碼現在看起來簡潔多了。

          HTML 中的標題

          到目前為止,蝙蝠俠對結果很高興,他希望在情書上標題。他想寫一個標題: “Bat Letter”。當然,你已經看到這個名字了,不是嗎?:D

          你可以使用 <h1>、<h2>、<h3>、<h4>、<h5> 和 <h6> 標簽來添加標題,<h1> 是最大的標題和最主要的標題,<h6> 是最小的標題。



          讓我們在第二段之前使用 <h1> 做主標題和一個副標題:

          <div style="width:550px;">

          <h1>Bat Letter</h1>

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          </div>

          保存,刷新。



          HTML 中的圖像

          我們的情書尚未完成,但在繼續之前,缺少一件大事:蝙蝠俠標志。你見過是蝙蝠俠的東西但沒有蝙蝠俠的標志嗎?

          并沒有。

          所以,讓我們在情書中添加一個蝙蝠俠標志。

          在 HTML 中包含圖像就像在一個 Word 文件中包含圖像一樣。在 MS Word 中,你到 “菜單 -> 插入 -> 圖像 -> 然后導航到圖像位置為止 -> 選擇圖像 -> 單擊插入”。

          在 HTML 中,我們使用 <img> 標簽讓瀏覽器知道我們需要加載的圖像,而不是單擊菜單。我們在 src 屬性中寫入文件的位置和名稱。如果圖像在項目根目錄中,我們可以簡單地在 src 屬性中寫入圖像文件的名稱。

          在我們深入編碼之前,從 這里 下載蝙蝠俠標志。你可能希望裁剪圖像中的額外空白區域。復制項目根目錄中的圖像并將其重命名為 “bat-logo.jpeg”。

          <div style="width:550px;">

          <h1>Bat Letter</h1>

          <img src="bat-logo.jpeg">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          </div>

          我們在第 3 行包含了 <img> 標簽。這個標簽也是一個自閉合的標簽,所以我們不需要寫 </img>。在 src 屬性中,我們給出了圖像文件的名稱。這個名稱應與圖像名稱完全相同,包括擴展名(.jpeg)及其大小寫。

          保存并刷新,查看結果。



          該死的!剛剛發生了什么?

          當使用 <img> 標簽包含圖像時,默認情況下,圖像將以其原始分辨率顯示。在我們的例子中,圖像比 550px 寬得多。讓我們使用 style 屬性定義它的寬度:

          <div style="width:550px;">

          <h1>Bat Letter</h1>

          <img src="bat-logo.jpeg" style="width:100%">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          </div>

          你會注意到,這次我們定義寬度使用了 “%” 而不是 “px”。當我們在 “%” 中定義寬度時,它將占據父元素寬度的百分比。因此,100% 的 550px 將為我們提供 550px。

          保存并刷新,查看結果。



          太棒了!這讓蝙蝠俠的臉露出了羞澀的微笑 :)。

          HTML 中的粗體和斜體

          現在蝙蝠俠想在最后幾段中承認他的愛。他有以下文本供你用 HTML 編寫:

          “I have a confession to make

          It feels like my chest does have a heart. You make my heart beat. Your smile brings a smile to my face, your pain brings pain to my heart.

          I don’t show my emotions, but I think this man behind the mask is falling for you.”

          當閱讀到這里時,你會問蝙蝠俠:“等等,這是給誰的?”蝙蝠俠說:

          “這是給超人的。”



          你說:哦!我還以為是給神奇女俠的呢。

          蝙蝠俠說:不,這是給超人的,請在最后寫上 “I love you Superman.”。

          好的,我們來寫:

          <div style="width:550px;">

          <h1>Bat Letter</h1>

          <img src="bat-logo.jpeg" style="width:100%">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          <h2>I have a confession to make</h2>

          <p>

          It feels like my chest does have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart.

          </p>

          <p>

          I don't show my emotions, but I think this man behind the mask is falling for you.

          </p>

          <p>I love you Superman.</p>

          <p>

          Your not-so-secret-lover, <br>

          Batman

          </p>

          </div>

          這封信差不多完成了,蝙蝠俠另外想再做兩次改變。蝙蝠俠希望在最后段落的第一句中的 “does” 一詞是斜體,而 “I love you Superman” 這句話是粗體的。

          我們使用 <em> 和 <strong> 以斜體和粗體顯示文本。讓我們來更新這些更改:

          <div style="width:550px;">

          <h1>Bat Letter</h1>

          <img src="bat-logo.jpeg" style="width:100%">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          <h2>I have a confession to make</h2>

          <p>

          It feels like my chest <em>does</em> have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart.

          </p>

          <p>

          I don't show my emotions, but I think this man behind the mask is falling for you.

          </p>

          <p><strong>I love you Superman.</strong></p>

          <p>

          Your not-so-secret-lover, <br>

          Batman

          </p>

          </div>



          HTML 中的樣式

          你可以通過三種方式設置樣式或定義 HTML 元素的外觀:

          • 內聯樣式:我們使用元素的 style 屬性來編寫樣式。這是我們迄今為止使用的,但這不是一個好的實踐。
          • 嵌入式樣式:我們在由 <style> 和 </style> 包裹的 “style” 元素中編寫所有樣式。
          • 鏈接樣式表:我們在具有 .css 擴展名的單獨文件中編寫所有元素的樣式。此文件稱為樣式表。

          讓我們來看看如何定義 <div> 的內聯樣式:

          <div style="width:550px;">

          我們可以在 <style> 和 </style> 里面寫同樣的樣式:

          div{

          width:550px;

          }

          在嵌入式樣式中,我們編寫的樣式是與元素分開的。所以我們需要一種方法來關聯元素及其樣式。第一個單詞 “div” 就做了這樣的活。它讓瀏覽器知道花括號 {...} 里面的所有樣式都屬于 “div” 元素。由于這種語法確定要應用樣式的元素,因此它稱為一個選擇器。

          我們編寫樣式的方式保持不變:屬性(width)和值(550px)用冒號(:)分隔,以分號(;)結束。

          讓我們從 <div> 和 <img> 元素中刪除內聯樣式,將其寫入 <style> 元素:

          <style>

          div{

          width:550px;

          }

          img{

          width:100%;

          }

          </style>

          <div>

          <h1>Bat Letter</h1>

          <img src="bat-logo.jpeg">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          <h2>I have a confession to make</h2>

          <p>

          It feels like my chest <em>does</em> have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart.

          </p>

          <p>

          I don't show my emotions, but I think this man behind the mask is falling for you.

          </p>

          <p><strong>I love you Superman.</strong></p>

          <p>

          Your not-so-secret-lover, <br>

          Batman

          </p>

          </div>

          保存并刷新,結果應保持不變。

          但是有一個大問題,如果我們的 HTML 文件中有多個 <div> 和 <img> 元素該怎么辦?這樣我們在 <style> 元素中為 div 和 img 定義的樣式就會應用于頁面上的每個 div 和 img。

          如果你在以后的代碼中添加另一個 div,那么該 div 也將變為 550px 寬。我們并不希望這樣。

          我們想要將我們的樣式應用于現在正在使用的特定 div 和 img。為此,我們需要為 div 和 img 元素提供唯一的 id。以下是使用 id 屬性為元素賦予 id 的方法:

          <div id="letter-container">

          以下是如何在嵌入式樣式中將此 id 用作選擇器:

          #letter-container{

          ...

          }

          注意 # 符號。它表示它是一個 id,{...} 中的樣式應該只應用于具有該特定 id 的元素。

          讓我們來應用它:

          <style>

          #letter-container{

          width:550px;

          }

          #header-bat-logo{

          width:100%;

          }

          </style>

          <div id="letter-container">

          <h1>Bat Letter</h1>

          <img id="header-bat-logo" src="bat-logo.jpeg">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          <h2>I have a confession to make</h2>

          <p>

          It feels like my chest <em>does</em> have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart.

          </p>

          <p>

          I don't show my emotions, but I think this man behind the mask is falling for you.

          </p>

          <p><strong>I love you Superman.</strong></p>

          <p>

          Your not-so-secret-lover, <br>

          Batman

          </p>

          </div>

          HTML 已經準備好了嵌入式樣式。

          但是,你可以看到,隨著我們包含越來越多的樣式,<style></style> 將變得很大。這可能很快會混亂我們的主 HTML 文件。

          因此,讓我們更進一步,通過將 <style> 標簽內的內容復制到一個新文件來使用鏈接樣式。

          在項目根目錄中創建一個新文件,將其另存為 “style.css”:

          #letter-container{

          width:550px;

          }

          #header-bat-logo{

          width:100%;

          }

          我們不需要在 CSS 文件中寫 <style> 和 </style>。

          我們需要使用 HTML 文件中的 <link> 標簽來將新創建的 CSS 文件鏈接到 HTML 文件。以下是我們如何做到這一點:

          <link rel="stylesheet" type="text/css" href="style.css">

          我們使用 <link> 元素在 HTML 文檔中包含外部資源,它主要用于鏈接樣式表。我們使用的三個屬性是:

          • rel:關系。鏈接文件與文檔的關系。具有 .css 擴展名的文件稱為樣式表,因此我們保留 rel=“stylesheet”。
          • type:鏈接文件的類型;對于一個 CSS 文件來說它是 “text/css”。
          • href:超文本參考。鏈接文件的位置。

          link 元素的結尾沒有 </link>。因此,<link> 也是一個自閉合的標簽。

          <link rel="gf" type="cute" href="girl.next.door">

          如果只是得到一個女朋友,那么很容易:D

          可惜沒有那么簡單,讓我們繼續前進。

          這是我們 “loveletter.html” 的內容:

          <link rel="stylesheet" type="text/css" href="style.css">

          <div id="letter-container">

          <h1>Bat Letter</h1>

          <img id="header-bat-logo" src="bat-logo.jpeg">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          <h2>I have a confession to make</h2>

          <p>

          It feels like my chest <em>does</em> have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart.

          </p>

          <p>

          I don't show my emotions, but I think this man behind the mask is falling for you.

          </p>

          <p><strong>I love you Superman.</strong></p>

          <p>

          Your not-so-secret-lover, <br>

          Batman

          </p>

          </div>

          “style.css” 內容:

          #letter-container{

          width:550px;

          }

          #header-bat-logo{

          width:100%;

          }

          保存文件并刷新,瀏覽器中的輸出應保持不變。

          一些手續

          我們的情書已經準備好給蝙蝠俠,但還有一些正式的片段。

          與其他任何編程語言一樣,HTML 自出生以來(1990 年)經歷過許多版本,當前版本是 HTML5。

          那么,瀏覽器如何知道你使用哪個版本的 HTML 來編寫頁面呢?要告訴瀏覽器你正在使用 HTML5,你需要在頁面頂部包含 <!DOCTYPE html>。對于舊版本的 HTML,這行不同,但你不需要了解它們,因為我們不再使用它們了。

          此外,在之前的 HTML 版本中,我們曾經將整個文檔封裝在 <html></html> 標簽內。整個文件分為兩個主要部分:頭部在 <head></head> 里面,主體在 <body></body> 里面。這在 HTML5 中不是必須的,但由于兼容性原因,我們仍然這樣做。讓我們用 <Doctype>, <html>、 <head> 和 <body> 更新我們的代碼:

          <!DOCTYPE html>

          <html>

          <head>

          <link rel="stylesheet" type="text/css" href="style.css">

          </head>

          <body>

          <div id="letter-container">

          <h1>Bat Letter</h1>

          <img id="header-bat-logo" src="bat-logo.jpeg">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          <h2>I have a confession to make</h2>

          <p>

          It feels like my chest <em>does</em> have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart.

          </p>

          <p>

          I don't show my emotions, but I think this man behind the mask is falling for you.

          </p>

          <p><strong>I love you Superman.</strong></p>

          <p>

          Your not-so-secret-lover, <br>

          Batman

          </p>

          </div>

          </body>

          </html>

          主要內容在 <body> 里面,元信息在 <head> 里面。所以我們把 <div> 保存在 <body> 里面并加載 <head> 里面的樣式表。

          保存并刷新,你的 HTML 頁面應顯示與之前相同的內容。

          HTML 的標題

          我發誓,這是最后一次改變。

          你可能已經注意到選項卡的標題正在顯示 HTML 文件的路徑:



          我們可以使用 <title> 標簽來定義 HTML 文件的標題。標題標簽也像鏈接標簽一樣在 <head> 內部。讓我們我們在標題中加上 “Bat Letter”:

          <!DOCTYPE html>

          <html>

          <head>

          <title>Bat Letter</title>

          <link rel="stylesheet" type="text/css" href="style.css">

          </head>

          <body>

          <div id="letter-container">

          <h1>Bat Letter</h1>

          <img id="header-bat-logo" src="bat-logo.jpeg">

          <p>

          After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

          </p>

          <h2>You are the light of my life</h2>

          <p>

          You complete my darkness with your light. I love:

          </p>

          <ul>

          <li>the way you see good in the worse</li>

          <li>the way you handle emotionally difficult situations</li>

          <li>the way you look at Justice</li>

          </ul>

          <p>

          I have learned a lot from you. You have occupied a special place in my heart over the time.

          </p>

          <h2>I have a confession to make</h2>

          <p>

          It feels like my chest <em>does</em> have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart.

          </p>

          <p>

          I don't show my emotions, but I think this man behind the mask is falling for you.

          </p>

          <p><strong>I love you Superman.</strong></p>

          <p>

          Your not-so-secret-lover, <br>

          Batman

          </p>

          </div>

          </body>

          </html>

          保存并刷新,你將看到在選項卡上顯示的是 “Bat Letter” 而不是文件路徑。

          蝙蝠俠的情書現在已經完成。

          恭喜!你用 HTML 制作了蝙蝠俠的情書。



          我們學到了什么

          我們學習了以下新概念:

          • 一個 HTML 文檔的結構
          • 在 HTML 中如何寫元素(<p></p>)
          • 如何使用 style 屬性在元素內編寫樣式(這稱為內聯樣式,盡可能避免這種情況)
          • 如何在 <style>...</style> 中編寫元素的樣式(這稱為嵌入式樣式)
          • 在 HTML 中如何使用 <link> 在單獨的文件中編寫樣式并鏈接它(這稱為鏈接樣式表)
          • 什么是標簽名稱,屬性,開始標簽和結束標簽
          • 如何使用 id 屬性為一個元素賦予 id
          • CSS 中的標簽選擇器和 id 選擇器

          我們學習了以下 HTML 標簽:

          • <p>:用于段落
          • <br>:用于換行
          • <ul>、<li>:顯示列表
          • <div>:用于分組我們信件的元素
          • <h1>、<h2>:用于標題和子標題
          • <img>:用于插入圖像
          • <strong>、<em>:用于粗體和斜體文字樣式
          • <style>:用于嵌入式樣式
          • <link>:用于包含外部樣式表
          • <html>:用于包裹整個 HTML 文檔
          • <!DOCTYPE html>:讓瀏覽器知道我們正在使用 HTML5
          • <head>:包裹元信息,如 <link> 和 <title>
          • <body>:用于實際顯示的 HTML 頁面的主體
          • <title>:用于 HTML 頁面的標題

          我們學習了以下 CSS 屬性:

          • width:用于定義元素的寬度
          • CSS 單位:“px” 和 “%”

          朋友們,這就是今天的全部了,下一個教程中見。


          作者簡介:開發者 + 作者 | supersarkar.com | twitter.com/supersarkar


          via: https://medium.freecodecamp.org/for-your-first-html-code-lets-help-batman-write-a-love-letter-64c203b9360b

          作者: Kunal Sarkar 譯者: MjSeven 校對: wxy

          本文由 LCTT 原創編譯, Linux中國 榮譽推出

          點擊“了解更多”可訪問文內鏈接

          avaScript在前端領域占據著絕對的統治地位,目前更是從瀏覽器到服務端,移動端,嵌入式,幾乎所有的所有的應用領域都可以使用它。技術圈有一句很經典的話“凡是能用JavaScript實現的東西,最后都會用JavaScript實現”。

          Excel 電子表格自 1980 年代以來一直為各行業所廣泛使用,至今已擁有超過3億用戶,大多數人都熟悉 Excel 電子表格體驗。許多企業在其業務的各個環節中使用了 Excel 電子表格進行數據管理。

          SpreadJS可以為我們的Web應用提供更好的交互體驗,以及更靈活的權限控制、數據整合、數據可視化、戰略績效測量 (SPM)、復雜的統計分析等。多年來,Excel 兼容性一直是SpreadJS最重要的功能之一。

          SpreadJS 提供了熟悉的 Excel 電子表格界面。用戶可以通過SpreadJS直接在頁面端導入和導出 Excel 文件——這一切無需依賴 Excel。

          復制下面鏈接獲取SpreadJS下載:www.evget.com/product/3558/download

          在本文中,我們將介紹如何按照以下步驟在 JavaScript 中,實現頁面端電子表格導入/導出到 Excel:

          1. 設置 JavaScript 電子表格項目

          首先,我們可以使用托管在 NPM 上的SpreadJS文件。為此,我們可以使用命令行參數進行安裝。打開命令提示符并導航到應用程序的位置。在那里,您可以使用一個命令安裝所需的文件。

          在這種情況下,我們需要基本的 Spread-Sheets 庫、Spread-ExcelIO 和 jQuery:

          npm i @grapecity/spread-sheets @grapecity/spread-excelio jquery

          SpreadJS 不依賴于 jQuery,但在這種情況下,我們使用它來提供簡單的跨域請求支持,稍后我們將對其進行回顧。

          一旦安裝了這些,我們就可以在我們的代碼中添加對這些腳本和 CSS 文件的引用:

          <!DOCTYPE html>
          <html>
          <head>
          <title>SpreadJS ExcelIO</title>
          <script src="./node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
          
          <link href="./node_modules/@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css" rel="stylesheet" type="text/css" />
          <script type="text/javascript" src="./node_modules/@grapecity/spread-sheets/dist/gc.spread.sheets.all.min.js"></script>
          <script type="text/javascript" src="./node_modules/@grapecity/spread-excelio/dist/gc.spread.excelio.min.js"></script>
          
          </head>
          <body>
          <div id="ss" style="height:600px; width :100%; "></div>
          </body>
          </html>

          除了SpreadJS 和 jQuery 文件之外,我們還需要導入 FileSaver 庫,為了便于后續程序處理,SpreadJS默認提供完整的文件流,FileSaver庫可以用來把文件流轉成文件下載到本地。

          然后我們可以在頁面中添加一個腳本來初始化 Spread.Sheets 組件和一個 div 元素來包含它(因為 SpreadJS 電子表格組件使用了一個畫布,這是初始化組件所必需的):

          <script type="text/javascript">
          $(document).ready(function () {
          var workbook = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
          });
          </script>
          </head>
          <body>
          <div id="ss" style="height:600px ; width :100%; "></div>
          </body>

          2. 添加 Excel 導入代碼

          我們需要創建一個客戶端 ExcelIO 組件的實例,我們可以使用它來打開文件:

          var excelIO = new GC.Spread.Excel.IO();

          然后我們需要添加一個函數來導入文件。在此示例中,我們導入了一個本地文件,但您可以對服務器上的文件執行相同的操作。如果從服務器導入文件,您需要引用該位置。下面是一個輸入元素的示例,用戶可以在其中輸入文件的位置:

          <input type="text" id="importUrl" value="http://www.testwebsite.com/files/TestExcel.xlsx" style="width:300px" />

          一旦你有了它,你可以直接在腳本代碼中訪問該值:

          var excelUrl = $("#importUrl").val();

          導入函數的以下代碼使用“excelUrl”變量的本地文件:

          function ImportFile() {
          var excelUrl = "./test.xlsx";
          
          var oReq = new XMLHttpRequest();
          oReq.open('get', excelUrl, true);
          oReq.responseType = 'blob';
          oReq.onload = function () {
          var blob = oReq.response;
          excelIO.open(blob, LoadSpread, function (message) {
          console.log(message);
          });
          };
          oReq.send(null);
          }
          function LoadSpread(json) {
          jsonData = json;
          workbook.fromJSON(json);
          
          workbook.setActiveSheet("Revenues (Sales)");
          }

          無論您是在服務器上還是在本地引用文件,都需要在 $(document).ready 函數內的腳本中添加以下內容:

          $(document).ready(function () {
          $.support.cors = true;
          workbook = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
          //...
          });

          在這種情況下,我們需要啟用 Cross-Origin-Request-Support,因為我們可能會從 URL 加載文件。因此 $.support.cors = true;行,否則嘗試加載它會導致 CORS 錯誤。

          3. 將數據添加到導入的 Excel 文件

          我們使用本教程的“損益表”Excel 模板導入本地文件。

          現在我們可以使用 Spread.Sheets 腳本在這個文件中添加另一個收入行。讓我們在頁面上添加一個按鈕來執行此操作:

          <button id="addRevenue">Add Revenue</button>

          我們可以為該按鈕的單擊事件處理程序編寫一個函數來添加一行并從前一行復制樣式以準備添加一些數據。要復制樣式,我們需要使用 copyTo 函數并傳入:

          1. 原始和目標行和列索引
          2. 行數和列數
          3. 樣式的 CopyToOptions 值
          document.getElementById("addRevenue").onclick = function () {
          var sheet = workbook.getActiveSheet();
          sheet.addRows(newRowIndex, 1);
          sheet.copyTo(10, 1, newRowIndex, 1, 1, 29, GC.Spread.Sheets.CopyToOptions.style);
          }

          以下用于添加數據和 Sparkline 的腳本代碼將包含在此按鈕單擊事件處理程序中。對于大部分數據,我們可以使用 setValue 函數。這允許我們通過傳入行索引、列索引和值來在 Spread 中的工作表中設置值:

          sheet.setValue(newRowIndex, 1, "Revenue 8");
          for (var c = 3; c < 15; c++) {
          sheet.setValue(newRowIndex, c, Math.floor(Math.random() * 200) + 10);
          }

          在 P 列中設置 SUM 公式以匹配其他行并為 Q 列設置百分比:

          sheet.setFormula(newRowIndex, 15, "=SUM([@[Jan]:[Dec]])")
          sheet.setValue(newRowIndex, 16, 0.15);

          最后,我們可以再次使用 copyTo 函數將先前行中的公式復制到 R 到 AD 列的新行,這次使用 CopyToOptions.formula:

          sheet.copyTo(10, 17, newRowIndex, 17, 1, 13, GC.Spread.Sheets.CopyToOptions.formula);

          4. 添加迷你圖

          現在,我們可以添加迷你圖來匹配其他數據行。為此,我們需要提供一系列單元格以從中獲取數據以及迷你圖的一些設置。在這種情況下,我們可以指定:

          1. 單元格的范圍,我們只是將數據添加到
          2. 使迷你圖看起來像同一列中的其他迷你圖的設置
          var data = new GC.Spread.Sheets.Range(11, 3, 1, 12);
          var setting = new GC.Spread.Sheets.Sparklines.SparklineSetting();
          setting.options.seriesColor = "Text 2";
          setting.options.lineWeight = 1;
          setting.options.showLow = true;
          setting.options.showHigh = true;
          setting.options.lowMarkerColor = "Text 2";
          setting.options.highMarkerColor = "Text 1";

          之后,我們調用 setSparkline 方法并指定:

          1. 迷你圖的位置
          2. 數據的位置
          3. 迷你圖的方向
          4. 迷你圖的類型
          5. 我們創建的設置

          sheet.setSparkline(11, 2, data, GC.Spread.Sheets.Sparklines.DataOrientation.horizontal, GC.Spread.Sheets.Sparklines.SparklineType.line, setting);

          如果您現在嘗試運行代碼,它可能看起來有點慢,因為每次更改數據和添加樣式時工作簿都會重新繪制。為了顯著加快速度并提高性能,Spread.Sheets 提供了暫停繪畫和計算服務的能力。讓我們在添加一行及其數據之前添加代碼以暫停兩者,然后在之后恢復兩者:

          workbook.suspendPaint();
          workbook.suspendCalcService();
          //...
          workbook.resumeCalcService();
          workbook.resumePaint();

          添加該代碼后,我們可以在 Web 瀏覽器中打開該頁面,并查看 Excel 文件加載到 Spread.Sheets 中并添加了收入行。重要提示:請記住,出于安全考慮,Chrome 不允許您打開本地文件,因此您需要使用 Firefox 等網絡瀏覽器才能成功運行此代碼。或者,從網站 URL 加載文件應該可以在任何瀏覽器中正常打開。

          5. 添加 Excel 導出代碼

          最后,我們可以添加一個按鈕來導出包含添加行的文件。為此,我們可以使用 Spread.Sheets 中內置的客戶端 ExcelIO 代碼:

          function ExportFile() {
          var fileName = $("#exportFileName").val();
          if (fileName.substr(-5, 5) !== '.xlsx') {
          fileName += '.xlsx';
          }
          var json = JSON.stringify(workbook.toJSON());
          
          excelIO.save(json, function (blob) {
          saveAs(blob, fileName);
          }, function (e) {
          if (e.errorCode === 1) {
          alert(e.errorMessage);
          }
          });
          }

          該代碼從 exportFileName 輸入元素獲取導出文件名。我們可以定義它并讓用戶像這樣命名文件:

          <input type="text" id="exportFileName" placeholder="Export file name" value="export.xlsx" />

          然后我們可以添加一個按鈕來調用這個函數:

          <button id="export">Export File</button>
          document.getElementById("export").onclick = function () {
          ExportFile();
          }

          添加收入行后,您可以使用“導出文件”按鈕導出文件。確保添加 FileSaver 外部庫以允許用戶將文件保存在他們想要的位置:

          <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>

          成功導出文件后,您可以在 Excel 中打開它,并查看文件與導入時的外觀相同,只是現在我們添加了額外的收入行。

          這只是一個示例,說明如何使用 SpreadJS JavaScript 電子表格將數據添加到 Excel 文件,然后使用簡單的 JavaScript 代碼將它們導出回 Excel。

          本文內容源自葡萄城


          主站蜘蛛池模板: 精品一区二区三区视频 | 久久精品亚洲一区二区| 亚洲国产成人久久一区WWW | 久久亚洲一区二区| 无码乱码av天堂一区二区| 91在线一区二区| 在线精品一区二区三区电影| 美女AV一区二区三区| 日本不卡免费新一区二区三区| 亚洲蜜芽在线精品一区| 成人免费视频一区二区三区| 精品在线一区二区三区| 国产suv精品一区二区33| 亚洲爆乳精品无码一区二区 | 国产福利一区二区在线视频| 国产一区二区三区高清视频| 亚洲国产美女福利直播秀一区二区| 国产乱码精品一区二区三区| 99久久精品国产免看国产一区| 人体内射精一区二区三区| 日韩a无吗一区二区三区| 久草新视频一区二区三区| 手机福利视频一区二区| 99精品国产一区二区三区| 亚洲大尺度无码无码专线一区| 一区二区在线视频免费观看| 88国产精品视频一区二区三区| 国产日韩精品一区二区三区 | AV无码精品一区二区三区宅噜噜 | 免费视频精品一区二区三区| 国产精品香蕉在线一区| 国产午夜毛片一区二区三区| 日韩最新视频一区二区三| 四虎成人精品一区二区免费网站| 国产一区内射最近更新| 国产免费一区二区三区| 国产福利电影一区二区三区,亚洲国模精品一区 | 男人免费视频一区二区在线观看 | 麻豆va一区二区三区久久浪| 少妇无码一区二区二三区| 小泽玛丽无码视频一区|