整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          前端入門教程JavaScript Array(數(shù)組)

          前端入門教程JavaScript Array(數(shù)組)對象

          avaScript 數(shù)組用于在單一變量中存儲(chǔ)多個(gè)值。

          實(shí)例

          var cars=["Saab", "Volvo", "BMW"];

          什么是數(shù)組?

          數(shù)組是一種特殊的變量,它能夠一次存放一個(gè)以上的值。

          如果您有一個(gè)項(xiàng)目清單(例如,汽車品牌列表),在單個(gè)變量中存儲(chǔ)汽車品牌應(yīng)該是這樣的:

          var car1="Saab";
          var car2="Volvo";
          var car3="BMW";

          不過,假如您希望遍歷所有汽車并找到一個(gè)特定的值?假如不是三個(gè)汽車品牌而是三百個(gè)呢?

          解決方法就是數(shù)組!

          數(shù)組可以用一個(gè)單一的名稱存放很多值,并且還可以通過引用索引號來訪問這些值。

          創(chuàng)建數(shù)組

          使用數(shù)組文本是創(chuàng)建 JavaScript 數(shù)組最簡單的方法。

          語法:

          var array-name=[item1, item2, ...];

          實(shí)例

          var cars=["Saab", "Volvo", "BMW"];

          空格和折行并不重要。聲明可橫跨多行:

          實(shí)例

          var cars=[
              "Saab",
              "Volvo",
              "BMW"
          ];

          請不要最后一個(gè)元素之后寫逗號(比如 "BMW",)。

          可能存在跨瀏覽器兼容性問題。

          使用 JavaScript 關(guān)鍵詞 new

          下面的例子也會(huì)創(chuàng)建數(shù)組,并為其賦值:

          實(shí)例

          var cars=new Array("Saab", "Volvo", "BMW");

          以上兩個(gè)例子效果完全一樣。無需使用 new Array()。

          出于簡潔、可讀性和執(zhí)行速度的考慮,請使用第一種方法(數(shù)組文本方法)。

          訪問數(shù)組元素

          我們通過引用索引號(下標(biāo)號)來引用某個(gè)數(shù)組元素。

          這條語句訪問 cars 中的首個(gè)元素的值:

          var name=cars[0];

          這條語句修改 cars 中的首個(gè)元素:

          cars[0]="Opel";

          實(shí)例

          var cars=["Saab", "Volvo", "BMW"];
          document.getElementById("demo").innerHTML=cars[0];

          [0] 是數(shù)組中的第一個(gè)元素。[1] 是第二個(gè)。數(shù)組索引從 0 開始。

          改變數(shù)組元素

          這條語句修改了 cars 中第一個(gè)元素的值:

          cars[0]="Opel";

          實(shí)例

          var cars=["Saab", "Volvo", "BMW"];
          cars[0]="Opel";
          document.getElementById("demo").innerHTML=cars[0];

          訪問完整數(shù)組

          通過 JavaScript,可通過引用數(shù)組名來訪問完整數(shù)組:

          實(shí)例

          var cars=["Saab", "Volvo", "BMW"];
          document.getElementById("demo").innerHTML=cars;

          數(shù)組是對象

          數(shù)組是一種特殊類型的對象。在 JavaScript 中對數(shù)組使用 typeof 運(yùn)算符會(huì)返回 "object"。

          但是,JavaScript 數(shù)組最好以數(shù)組來描述。

          數(shù)組使用數(shù)字來訪問其“元素”。在本例中,person[0] 返回 Bill:

          數(shù)組:

          var person=["Bill", "Gates", 62];

          對象使用名稱來訪問其“成員”。在本例中,person.firstName 返回 Bill:

          對象:

          var person={firstName:"Bill", lastName:"Gates", age:19};

          數(shù)組元素可以是對象

          JavaScript 變量可以是對象。數(shù)組是特殊類型的對象。

          正因如此,您可以在相同數(shù)組中存放不同類型的變量。

          您可以在數(shù)組保存對象。您可以在數(shù)組中保存函數(shù)。你甚至可以在數(shù)組中保存數(shù)組:

          myArray[0]=Date.now;
          myArray[1]=myFunction;
          myArray[2]=myCars;

          數(shù)組屬性和方法

          JavaScript 數(shù)組的真實(shí)力量隱藏在數(shù)組的屬性和方法中:

          實(shí)例

          var x=cars.length;   // length 屬性返回元素的數(shù)量
          var y=cars.sort();   // sort() 方法對數(shù)組進(jìn)行排序

          我們將在下一章學(xué)習(xí)數(shù)組方法。

          length 屬性

          length 屬性返回?cái)?shù)組的長度(數(shù)組元素的數(shù)目)。

          實(shí)例

          var fruits=["Banana", "Orange", "Apple", "Mango"];
          fruits.length;                       // fruits 的長度是 4

          length 屬性始終大于最高數(shù)組索引(下標(biāo))。

          訪問第一個(gè)數(shù)組元素

          實(shí)例

          fruits=["Banana", "Orange", "Apple", "Mango"];
          var first=fruits[0];

          訪問最后一個(gè)數(shù)組元素

          實(shí)例

          fruits=["Banana", "Orange", "Apple", "Mango"];
          var last=fruits[fruits.length - 1];

          遍歷數(shù)組元素

          遍歷數(shù)組的最安全方法是使用 "for" 循環(huán):

          實(shí)例

          var fruits, text, fLen, i;
          
          fruits=["Banana", "Orange", "Apple", "Mango"];
          fLen=fruits.length;
          text="<ul>";
          for (i=0; i < fLen; i++) {
               text +="<li>" + fruits[i] + "</li>";
          }

          您也可以使用 Array.foreach() 函數(shù):

          實(shí)例

          var fruits, text;
          fruits=["Banana", "Orange", "Apple", "Mango"];
          
          text="<ul>";
          fruits.forEach(myFunction);
          text +="</ul>";
          
          function myFunction(value) {
            text +="<li>" + value + "</li>";
          }

          添加數(shù)組元素

          向數(shù)組添加新元素的最佳方法是使用 push() 方法:

          實(shí)例

          var fruits=["Banana", "Orange", "Apple", "Mango"];
          fruits.push("Lemon");                // 向 fruits 添加一個(gè)新元素 (Lemon)

          也可以使用 length 屬性向數(shù)組添加新元素:

          實(shí)例

          var fruits=["Banana", "Orange", "Apple", "Mango"];
          fruits[fruits.length]="Lemon";     // 向 fruits 添加一個(gè)新元素 (Lemon)

          警告!

          添加最高索引的元素可在數(shù)組中創(chuàng)建未定義的“洞”:

          實(shí)例

          var fruits=["Banana", "Orange", "Apple", "Mango"];
          fruits[6]="Lemon";                 // 向 fruits 添加一個(gè)新元素 (Lemon)

          關(guān)聯(lián)數(shù)組

          很多編程元素支持命名索引的數(shù)組。

          具有命名索引的數(shù)組被稱為關(guān)聯(lián)數(shù)組(或散列)。

          JavaScript 不支持命名索引的數(shù)組。

          在 JavaScript 中,數(shù)組只能使用數(shù)字索引

          實(shí)例

          var person=[];
          person[0]="Bill";
          person[1]="Gates";
          person[2]=62;
          var x=person.length;          // person.length 返回 3
          var y=person[0];              // person[0] 返回 "Bill"

          警告!

          假如您使用命名索引,JavaScript 會(huì)把數(shù)組重定義為標(biāo)準(zhǔn)對象。

          之后,所有數(shù)組的方法和屬性將產(chǎn)生非正確結(jié)果。

          實(shí)例:

          var person=[];
          person["firstName"]="Bill";
          person["lastName"]="Gates";
          person["age"]=62;
          var x=person.length;         // person.length 將返回 0
          var y=person[0];              // person[0] 將返回 undefined

          數(shù)組和對象的區(qū)別

          在 JavaScript 中,數(shù)組使用數(shù)字索引

          在 JavaScript 中,對象使用命名索引

          數(shù)組是特殊類型的對象,具有數(shù)字索引。

          何時(shí)使用數(shù)組,何時(shí)使用對象?

          • JavaScript 不支持關(guān)聯(lián)數(shù)組
          • 如果希望元素名為字符串(文本)則應(yīng)該使用對象
          • 如果希望元素名為數(shù)字則應(yīng)該使用數(shù)組

          避免 new Array()

          沒有必要使用 JavaScript 的內(nèi)建數(shù)組構(gòu)造器 new Array()。

          請使用 [] 取而代之!

          下面兩條不同的語句創(chuàng)建了名為 points 的新的空數(shù)組:

          var points=new Array();         // 差
          var points=[];                  // 優(yōu)

          下面兩條不同的語句創(chuàng)建包含六個(gè)數(shù)字的新數(shù)組:

          var points=new Array(40, 100, 1, 5, 25, 10); // 差
          var points=[40, 100, 1, 5, 25, 10];          // 優(yōu)

          new 關(guān)鍵詞只會(huì)使代碼復(fù)雜化。它還會(huì)產(chǎn)生某些不可預(yù)期的結(jié)果:

          var points=new Array(40, 100);  // 創(chuàng)建包含兩個(gè)元素的數(shù)組(40 和 100)

          假如刪除其中一個(gè)元素會(huì)怎么樣?

          var points=new Array(40);       // 創(chuàng)建包含 40 個(gè)未定義元素的數(shù)組!!!

          如何識別數(shù)組

          常見的問題是:我如何知曉某個(gè)變量是否是數(shù)組?

          問題在于 JavaScript 運(yùn)算符 typeof 返回 "object":

          var fruits=["Banana", "Orange", "Apple", "Mango"];
          
          typeof fruits;             // 返回 object

          typeof 運(yùn)算符返回 "object",因?yàn)?JavaScript 數(shù)組屬于對象。

          解決方案 1:

          為了解決這個(gè)問題,ECMAScript 5 定義了新方法 Array.isArray():

          Array.isArray(fruits);     // 返回 true

          此方案的問題在于 ECMAScript 5 不支持老的瀏覽器

          解決方案 2:

          創(chuàng)建您自己的 isArray() 函數(shù)以解決此問題:

          function isArray(x) {
              return x.constructor.toString().indexOf("Array") > -1;
          }

          假如參數(shù)為數(shù)組,則上面的函數(shù)始終返回 true。

          或者更準(zhǔn)確的解釋是:假如對象原型包含單詞 "Array" 則返回 true。

          解決方案 3:

          假如對象由給定的構(gòu)造器創(chuàng)建,則 instanceof 運(yùn)算符返回 true:

          var fruits=["Banana", "Orange", "Apple", "Mango"];
           
          fruits instanceof Array     // 返回 true


          實(shí)例

          創(chuàng)建數(shù)組

          創(chuàng)建數(shù)組,為其賦值,然后輸出這些值。

          <html>
          <body>
          
          <script type="text/javascript">
          var mycars=new Array()
          mycars[0]="Saab"
          mycars[1]="Volvo"
          mycars[2]="BMW"
          
          for (i=0;i<mycars.length;i++)
          {
          document.write(mycars[i] + "<br />")
          }
          </script>
          
          </body>
          </html>

          For...In 聲明

          使用 for...in 聲明來循環(huán)輸出數(shù)組中的元素。

          <html>
          <body>
          <script type="text/javascript">
          var x
          var mycars=new Array()
          mycars[0]="Saab"
          mycars[1]="Volvo"
          mycars[2]="BMW"
          
          for (x in mycars)
          {
          document.write(mycars[x] + "<br />")
          }
          </script>
          </body>
          </html>

          合并兩個(gè)數(shù)組 - concat()

          如何使用 concat() 方法來合并兩個(gè)數(shù)組。

          <html>
          <body>
          
          <script type="text/javascript">
          
          var arr=new Array(3)
          arr[0]="George"
          arr[1]="John"
          arr[2]="Thomas"
          
          var arr2=new Array(3)
          arr2[0]="James"
          arr2[1]="Adrew"
          arr2[2]="Martin"
          
          document.write(arr.concat(arr2))
          
          </script>
          
          </body>
          </html>

          用數(shù)組的元素組成字符串 - join()

          如何使用 join() 方法將數(shù)組的所有元素組成一個(gè)字符串。

          <html>
          <body>
          
          <script type="text/javascript">
          
          var arr=new Array(3);
          arr[0]="George"
          arr[1]="John"
          arr[2]="Thomas"
          
          document.write(arr.join());
          
          document.write("<br />");
          
          document.write(arr.join("."));
          
          </script>
          
          </body>
          </html>

          文字?jǐn)?shù)組 - sort()

          如何使用 sort() 方法從字面上對數(shù)組進(jìn)行排序。

          <html>
          <body>
          
          <script type="text/javascript">
          
          var arr=new Array(6)
          arr[0]="George"
          arr[1]="John"
          arr[2]="Thomas"
          arr[3]="James"
          arr[4]="Adrew"
          arr[5]="Martin"
          
          document.write(arr + "<br />")
          document.write(arr.sort())
          
          </script>
          
          </body>
          </html>

          數(shù)字?jǐn)?shù)組 - sort()

          如何使用 sort() 方法從數(shù)值上對數(shù)組進(jìn)行排序。

          <html>
          <body>
          
          <script type="text/javascript">
          
          function sortNumber(a, b)
          {
          return a - b
          }
          
          var arr=new Array(6)
          arr[0]="10"
          arr[1]="5"
          arr[2]="40"
          arr[3]="25"
          arr[4]="1000"
          arr[5]="1"
          
          document.write(arr + "<br />")
          document.write(arr.sort(sortNumber))
          
          </script>
          
          </body>
          </html>

          定義數(shù)組

          數(shù)組對象用來在單獨(dú)的變量名中存儲(chǔ)一系列的值。

          我們使用關(guān)鍵詞 new 來創(chuàng)建數(shù)組對象。下面的代碼定義了一個(gè)名為 myArray 的數(shù)組對象:

          var myArray=new Array()

          有兩種向數(shù)組賦值的方法(你可以添加任意多的值,就像你可以定義你需要的任意多的變量一樣)。

          1:

          var mycars=`new Array()`
          mycars[0]="Saab"
          mycars[1]="Volvo"
          mycars[2]="BMW"

          也可以使用一個(gè)整數(shù)自變量來控制數(shù)組的容量:

          var mycars=`new Array(3)`
          mycars[0]="Saab"
          mycars[1]="Volvo"
          mycars[2]="BMW"

          2:

          var mycars=`new Array("Saab","Volvo","BMW")`

          注意:如果你需要在數(shù)組內(nèi)指定數(shù)值或者邏輯值,那么變量類型應(yīng)該是數(shù)值變量或者布爾變量,而不是字符變量。

          訪問數(shù)組

          通過指定數(shù)組名以及索引號碼,你可以訪問某個(gè)特定的元素。

          下面是代碼行:

          document.write(mycars[0])

          下面是輸出:

          Saab

          修改已有數(shù)組中的值

          如需修改已有數(shù)組中的值,只要向指定下標(biāo)號添加一個(gè)新值即可:

          mycars[0]="Opel";

          現(xiàn)在,以上代碼:

          document.write(mycars[0]);

          將輸出:

          Opel

          我建了一個(gè)【前端學(xué)習(xí)群】,【免費(fèi)領(lǐng)取學(xué)習(xí)資料】或?qū)W習(xí)的同學(xué)可以關(guān)注我:

          前端學(xué)習(xí)交流 - 知乎

          內(nèi)容是《Web前端開發(fā)之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學(xué)習(xí)。

          Element.innerHTML屬性:

          操作元素內(nèi)HTML內(nèi)容,即可設(shè)置或獲取使用HTML代碼表示的元素的后代;

          在讀取時(shí),該屬性返回與調(diào)用元素的所有子節(jié)點(diǎn)(包括元素、注釋和文本節(jié)點(diǎn))對應(yīng)的HTML代碼字會(huì)串,如:

          <div id="mydiv">
              <h2>零點(diǎn)程序員</h2>
              <ul id="myList">
                  <li>HTML</li>
                  <li class="current">CSS</li>
                  <li>JavaScript</li>
              </ul>
          </div>
          <script>
          var mydiv=document.getElementById("mydiv");
          console.log(mydiv.innerHTML);
          </script>

          注:不同瀏覽器返回的文本格式有可能不同,比如,部分低版本會(huì)把所有標(biāo)簽轉(zhuǎn)換為大寫;另外,瀏覽器會(huì)按照原先文檔的格式返回,包括空格和縮進(jìn);

          在寫入時(shí),會(huì)將給定的字符串解析為DOM子樹,將用這個(gè)DOM子樹替換調(diào)用元素原先的所有子節(jié)點(diǎn);如果設(shè)置的值是文本沒有HTML標(biāo)簽,其結(jié)果就是純文本,也就是文本節(jié)點(diǎn),此時(shí),如果該文本節(jié)點(diǎn)包含字符&、<或>, innerHTML將這些字符分別返回為&、<和>;

          mydiv.innerHTML="零點(diǎn)程序員 & zeronetwork 主講><b>\"王唯\"</b>";
          console.log(mydiv.innerHTML);
          mydiv.innerHTML="零點(diǎn)程序員";

          設(shè)置元素的innerHTML屬性將會(huì)刪除該元素的所有后代,因此,如果要保留原來的內(nèi)容,可以在innerHTML屬性的基礎(chǔ)上,可以使用+=進(jìn)行賦值,也就達(dá)到了追加內(nèi)容的效果;

          mydiv.innerHTML +="<b>大師哥王唯</b>";

          如果設(shè)置innerHTML屬性時(shí),使用了不合法的HTML代碼,瀏覽器會(huì)自動(dòng)修正,但要避免出現(xiàn)這種問題;

          另外,不允許document對象使用該屬性,如果使用了,會(huì)靜默失敗;

          設(shè)置了innerHTML屬性后,可以像訪問文檔中的其他節(jié)點(diǎn)一樣訪問新創(chuàng)建的節(jié)點(diǎn);

          console.log(mydiv.childNodes);

          從本質(zhì)上來看,設(shè)置innerHTML屬性,瀏覽器會(huì)把給定的值被解析為HTML或者XML,結(jié)果就是一個(gè)DocumentFragment對象,其中保存著代表元素的DOM節(jié)點(diǎn),然后再append到元素中;

          innerHTML也有一些限制,在多數(shù)瀏覽器中,通過innerHTML插入的<script> 元素不會(huì)被執(zhí)行,因?yàn)橛锌赡軙?huì)產(chǎn)生潛在的安全問題;

          var content=document.getElementById("content");
          content.innerHTML="<script>alert('wangwei');<\/script>";

          即使如此,使用innerHTML屬性也不能消除潛在的風(fēng)險(xiǎn),比如,繞過<script>標(biāo)簽,把腳本綁定到相關(guān)的事件中;

          mydiv.innerHTML="<img src='nourl' onerror='alert(\"加載圖片出錯(cuò)啦\")'>";

          通過innerHTML寫入<style>元素就可以運(yùn)行;如:

          mydiv.innerHTML="<style>body{background-color:purple;}</style>";
          // 放在head中
          document.head.innerHTML +="<style>body{background-color:purple;}</style>";
          console.log(document.head.innerHTML);

          在設(shè)置innerHTML屬性時(shí),雖然元素的所有子元素被替換,其仍被保存在內(nèi)存中,如果事先有變量在引用這些子元素,在設(shè)置innerHTML后,這些變量仍將保持對原始子元素的引用;

          var mydiv=document.getElementById("mydiv");
          var h2=mydiv.querySelector("h2");
          mydiv.innerHTML="新內(nèi)容";
          console.log(h2);
          mydiv.appendChild(h2);

          并不是所有元素都有innerHTML屬性,不支持的有<col> <colgroup> <frameset> <head> <html> <style> <table> <tbody> <thead> <tfoot> <title> <tr>

          無論什么時(shí)候插入外界的HTML內(nèi)容時(shí),都應(yīng)該對HTML進(jìn)行無害化處理,IE8提供了window.toStaticHTML()方法,接受一個(gè)HTM字符串,返回一個(gè)經(jīng)過無害化處理后的版本;

          var mydiv=document.getElementById("mydiv");
          var text="<a href='#' onclick='alert(\"hi\")'>zeronetwork</a>";
          // mydiv.innerHTML=text;
          var sanitized=window.toStaticHTML(text);  // [?s?n?ta?zd]
          console.log(sanitized);  // 非IE會(huì)拋出異常
          mydiv.innerHTML=sanitized;

          小示例:

          使用innerHTML創(chuàng)建一種機(jī)制用于將消息記錄到頁面中的一個(gè)元素中;

          <style>
          .box{width: 600px;height: 300px;
          border:1px solid black; padding: 2em; overflow: hidden scroll;}
          </style>
          <div class="box">
              <h2>日志:</h2>
              <div class="log"></div>
          </div>
          <script>
          function log(msg){
              var logEle=document.querySelector(".log");
              var time=new Date().toLocaleTimeString();
              logEle.innerHTML +=time + ": " + msg + "<br/>"; 
          }
          // log("打印一些數(shù)據(jù)");
          // 定義一個(gè)事件處理程序
          function logEvent(event){
              var msg="Event <strong>" + event.type + "</strong> at <em>" + 
                  event.clientX + "," + event.clientY + "</em>";
              log(msg);
          }
          // 綁定事件處理程序
          var boxEle=document.querySelector(".box");
          boxEle.addEventListener("mousedown", logEvent);
          boxEle.addEventListener("mouseup", logEvent);
          boxEle.addEventListener("click", logEvent);
          boxEle.addEventListener("mouseenter", logEvent);
          boxEle.addEventListener("mouseleave", logEvent);
          </script>

          Element.outerHTML屬性:

          與innerHTML屬性基本一致,不同點(diǎn)是,innerHTML是訪問和設(shè)置元素的所有子節(jié)點(diǎn),而outerHTML屬性不僅包括它的所有子節(jié)點(diǎn),也包括它本身;

          console.log(mydiv.outerHTML);
          mydiv.outerHTML="<p><h2>零點(diǎn)網(wǎng)絡(luò)</h2></p>";

          如果元素沒有父元素,即如果它是文檔的根元素,在設(shè)置其outerHTML屬性將拋出異常,如:

          document.documentElement.outerHTML="content"; // 異常

          這個(gè)屬性應(yīng)用的機(jī)會(huì)非常少;

          HTMLElement.innerText屬性:

          可以操作元素中包含的所有文本,最初是由IE實(shí)現(xiàn)的,后來被納入標(biāo)準(zhǔn)中;

          var mydiv=document.getElementById("mydiv");
          console.log(mydiv.innerText);
          mydiv.innerText="零點(diǎn)程序員";
          console.log(mydiv.innerText);

          輸出一個(gè)文檔樹時(shí),無論文本位于文檔樹中的什么位置,會(huì)按照由淺入深的順序,將子文檔樹中的所有文本拼接起來;

          <div id="content">
              <p>零點(diǎn)網(wǎng)絡(luò)<strong>zerontwork</strong>是一家從事IT教育的公司</p>
              <ul>
                  <li>HTML</li>
                  <li>CSS</li>
                  <li>Javascript</li>
              </ul>
          </div>
          <script>
          var content=document.getElementById("content");
          console.log(content.innerText);
          // 返回
          // 零點(diǎn)網(wǎng)絡(luò)zerontwork是一家從事IT教育的公司
          //
          // HTML/
          // CSS
          // Javascript
          </script>

          由于不同瀏覽器處理空白字符的方式不同,因此輸出的文本可能會(huì)也可能不會(huì)包含原始的HTML代碼中的縮進(jìn);

          使用innerText屬性設(shè)置內(nèi)容時(shí),會(huì)移除原先所有的子節(jié)點(diǎn),將永遠(yuǎn)只會(huì)生成當(dāng)前節(jié)點(diǎn)的一個(gè)子文本節(jié)點(diǎn);如果設(shè)置的內(nèi)容包括HTML標(biāo)簽,會(huì)自動(dòng)被轉(zhuǎn)碼,也就是說,會(huì)對所有出現(xiàn)在文本中的HTML語法字符進(jìn)行編碼(>、<、”、&);

          mydiv.innerText="<h2>wangwei</h2>";  // < > 會(huì)被轉(zhuǎn)義

          因?yàn)樵谠L問innerText屬性時(shí),其會(huì)過濾掉html標(biāo)簽,所以可以利用它的這個(gè)特點(diǎn),快速過濾掉元素的HTML標(biāo)簽,即把innerText設(shè)置為innerText;

          content.innerText=content.innerText;
          console.log(content.innerText);

          如果在設(shè)置innerHTML屬性時(shí),賦給的就是純文本字符串,那它就與innerText屬性作用一樣了;

          var mydiv=document.getElementById("mydiv");
          mydiv.innerText="零點(diǎn)網(wǎng)絡(luò) zeronetwork";
          mydiv.innerHTML="零點(diǎn)網(wǎng)絡(luò) zeronetwork";
          mydiv.innerText="零點(diǎn)網(wǎng)絡(luò)\nzeronetwork";  // 有br
          mydiv.innerHTML="零點(diǎn)網(wǎng)絡(luò)\nzeronetwork";  // 無br,但源碼格式有換行

          因?yàn)閕nnerHTML是解析html標(biāo)簽的,而\n不是標(biāo)簽,所以當(dāng)作空格被忽略了;但在innerText中,瀏覽器遇到\n,就會(huì)執(zhí)行換行,所以把它解析為<br>;

          在實(shí)際使用中,如果要過濾html標(biāo)簽,可以使用正則,如:

          // 去除html標(biāo)簽可以使用正則
          content.innerHTML=content.innerHTML.replace(/<.+?>/img,"");
          console.log(content.innerText);  // 沒有格式<br>
          console.log(content.innerHTML);  // 沒有格式<br>

          HTMLElement.outerText屬性:

          與innerText一樣,只不過替換的是元素(包括子節(jié)點(diǎn))本身;其是一個(gè)非標(biāo)準(zhǔn)屬性;

          var mydiv=document.getElementById("mydiv");
          console.log(mydiv.innerText);
          console.log(mydiv.outerText); // 返回值與innerText一致

          在讀取文本值時(shí),outerText和innerText的結(jié)果完全一樣;

          但在寫模式下,outerText就完全不同了,其本身都會(huì)被新的文本節(jié)點(diǎn)都替代,從文檔中被刪除,但其仍然被保存在內(nèi)存中,如果有變量引用,還可以再利用;

          mydiv.outerText="零點(diǎn)程序員";
          console.log(mydiv);  // 依然保留著原有的引用

          FF不支持outerText屬性,如:

          mydiv.outerText="零點(diǎn)程序員";  // 在FF中失效
          // 在FF中返回undefined,如果有上一行,會(huì)打印出“零點(diǎn)程序員”,但這和內(nèi)置的outerText沒有關(guān)系
          console.log(mydiv.outerText);

          在實(shí)際使用中,只會(huì)用到innerHTML和innerText,其他兩個(gè)一般不用,也沒有多大的實(shí)際意義;

          Node.textContent屬性:

          DOM3規(guī)定了一個(gè)屬性textContent,該屬性被定義在Node接口中,它的作用類似innerText屬性,返回一個(gè)節(jié)點(diǎn)及其后代的所有文本內(nèi)容;

          var mydiv=document.getElementById("mydiv");
          console.log(mydiv.innerText);
          console.log(mydiv.textContent); // 返回值與innerText基本一致,但格式不一樣

          如果設(shè)置textContent屬性,會(huì)刪除該元素的所有子節(jié)點(diǎn),并被替換為包含指定字符串的一個(gè)單獨(dú)的文本節(jié)點(diǎn);

          var mydiv=document.getElementById("mydiv");
          mydiv.textContent="大師哥王唯";
          mydiv.textContent="<h3>大師哥王唯</h3>";  // 會(huì)被轉(zhuǎn)碼
          console.log(mydiv.textContent);
          console.log(mydiv.childNodes);  // NodeList [text]

          如果節(jié)點(diǎn)是文本節(jié)點(diǎn),此屬性可用于取代 nodeValue 屬性,如;

          var h2=document.querySelector("h2").firstChild; // 取得文本節(jié)點(diǎn)
          console.log(h2.textContent); // zeronetwork
          console.log(h2.nodeValue);   // zeronetwork
          h2.nodeValue="零點(diǎn)程序員";
          console.log(h2.textContent); // 零點(diǎn)程序員
          console.log(h2.nodeValue);   // 零點(diǎn)程序員

          可以看出,兩者是聯(lián)動(dòng)的;

          如果事先有變量引用著它的后代節(jié)點(diǎn),即使節(jié)點(diǎn)使用該方法移除所有后代節(jié)點(diǎn),但被引用的后代節(jié)點(diǎn)依然存在,可以被再次利用;

          var content=document.getElementById("content");
          var h2=content.querySelector("h2");  // content中的h2
          content.textContent="王唯";
          console.log(content.textContent);
          console.log(h2);  // <h2>zeronetwork</h2>
          console.log(h2.parentElement);  // null
          var mydiv=document.getElementById("mydiv");
          mydiv.appendChild(h2);

          與innerText屬性的區(qū)別:

          兩者的返回的內(nèi)容并不完全一樣,比如在輸出的格式上其與innerText是不同的,其會(huì)保留代碼中的空白符;同時(shí),innerText針對表格,會(huì)試圖保留表格的格式;

          var mytable=document.getElementById("mytable");
          console.log(mytable.innerText);
          console.log(mytable.textContent);

          textContent屬性會(huì)返回元素的所有內(nèi)容,包括其中的樣式和腳本代碼,而innerText只返回能呈現(xiàn)在頁面上的元素;

          // 在mydiv中添加<style>和<script>標(biāo)簽
          var mydiv=document.getElementById("mydiv");
          console.log(mydiv.innerText); // 不包括<style>和<script>
          // 包括<style>和<script>標(biāo)簽內(nèi)的內(nèi)容,但該標(biāo)簽被過濾了
          console.log(mydiv.textContent);

          既然innerText只返回能呈現(xiàn)在頁面上的元素,所以它的返回值會(huì)受CSS樣式的影響,不會(huì)返回被CSS隱藏的元素的文本;

          <!-- textContent返回值沒有變化,但innerText不包括"HTML"和"CSS" -->
          <ul id="mylist">
              <li style="visibility: hidden;">HTML</li>
              <li style="display: none;">CSS</li>
              <li>JavaScript</li>
          </ul>

          textContent屬性能返回文本節(jié)點(diǎn)的文本內(nèi)容,而innerText會(huì)返回undefined;如果是文本節(jié)點(diǎn)調(diào)用textContent屬性,其返回值與nodeValue一致;

          innerHTML有可能會(huì)引發(fā)安全問題,但textConent卻不會(huì);

          mydiv.innerHTML="<img src='nourl' onerror='alert(\"加載圖片出錯(cuò)啦\")'>";
          mydiv.textContent="<img src='nourl' onerror='alert(\"加載圖片出錯(cuò)啦\")'>";
          console.log(mydiv.childNodes);  // index.html:20 NodeList [text]

          第一行的onerror會(huì)被執(zhí)行,第二行不會(huì)執(zhí)行,并且其被解析為文本節(jié)點(diǎn),如此,textContent不會(huì)引發(fā)安全問題;

          所有主流的瀏覽器都支持textContent屬性,但I(xiàn)E8及以下不支持,可以包裝一個(gè)兼容的函數(shù):

          function getInnerText(element){
              return (typeof element.textContent=="string") ? element.textContent : element.innerText;
          }
          function setInnerText(element, text){
              if(typeof element.textContent=="string")
                  element.textContent=text;
              else
                  element.innerText=text;
          }
          document.write(getInnerText(content));
          setInnerText(content, "零點(diǎn)程序員");

          或者直接定義在Node.prototype中:

          if(Object.defineProperty 
              && Object.getOwnPropertyDescriptor
              && !Object.getOwnPropertyDescriptor(Node.prototype, "textContent")){
              (function(){
                  var innerText=Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerText");
                  Object.defineProperty(Node.prototype, "textContent",{
                      get: function(){
                          return innerText.get.call(this);
                      },
                      set: function(s){
                          return innerText.set.call(this, s);
                      }
                  });
              })();
          }

          <script>元素中的文本:

          內(nèi)聯(lián)的<script>元素有一個(gè)text屬性用來獲取它們的文本;

          <script>
              console.log("function");
              function func(){return true;}
          </script>
          <script>
          var script=document.getElementsByTagName("script")[0];
          console.log(script.innerText);
          console.log(script.textContent);
          console.log(script.text);  // 三者輸出一致
          </script>

          如果將<script>元素的type屬性設(shè)置為”text/x-custom-data”,就表明了腳本為不可執(zhí)行的Javascript代碼,如此,Javascript解析器將忽略該腳本,這也使得<script>元素可以被用來嵌入任意文本內(nèi)容;

          <script type="text/x-custom-data">
              console.log("function");
              function func(){return true;}
          </script>
          <script>
          var script=document.getElementsByTagName("script")[0];
          console.log(script.innerText);
          console.log(script.textContent);
          console.log(script.text);  // 三者輸出一致
          </script>
          <script type="text/x-custom-data">
          <div style="border:1px solid red; width:300px;">
              <h2>視頻教程</h2>
          </div>
          </script>
          <script>
          var script=document.getElementsByTagName("script")[0];
          var mydiv=document.getElementById("mydiv");
          mydiv.innerHTML=script.text;
          </script>

          Element.insertAdjacentHTML(position, text)方法:

          該方法會(huì)將任意的HTML字符串text解析為Element元素,并將結(jié)果節(jié)點(diǎn)插入到DOM樹中的指定的元素”相鄰”的position位置;該方法最早是在IE4中出現(xiàn)的;它接收兩個(gè)參數(shù):插入位置和要插入的HTML文本;

          第一個(gè)參數(shù)position的可能值:

          • beforebegin:在當(dāng)前元素之前插入一個(gè)緊鄰的同輩元素;
          • afterbegin:在當(dāng)前元素之下插入一個(gè)新的子元素或在第一個(gè)子元素之前插入新的子元素;
          • beforeend:在當(dāng)前元素之下插入一個(gè)新的子元素或在最后一個(gè)子元素之后插入新的子元素;
          • afterend:在當(dāng)前元素之后插入一個(gè)緊鄰的同輩元素;

          第二個(gè)參數(shù)text為HTML字符串,如果瀏覽器無法解析,會(huì)拋出錯(cuò)誤,如;

          var mydiv=document.getElementById("mydiv");
          mydiv.insertAdjacentHTML("beforebegin","<p>前一個(gè)同輩元素</p>");
          mydiv.insertAdjacentHTML("afterbegin","<p>作為第一個(gè)子元素</p>");
          mydiv.insertAdjacentHTML("beforeend","<p>最后一個(gè)子元素</p>");
          mydiv.insertAdjacentHTML("afterend","<p>后一個(gè)同輩元素</p>");

          insertAdjacentHTML()方法同innerHTML屬性一樣,會(huì)遇到安全問題,在使用該屬性插入HTML內(nèi)容時(shí),需要轉(zhuǎn)義之后才能使用;

          另外,如果元素沒有子元素的時(shí)候,其和innerHTML就非常相像了;

          var newdiv=document.createElement("div");
          newdiv.insertAdjacentHTML("afterbegin", "<p>零點(diǎn)程序員</p>");
          // 同以下
          newdiv.innerHTML="<p>零點(diǎn)程序員</p>";
          document.body.appendChild(newdiv);

          需要注意的是,如果position為beforebegin或afterend,那該元素必須具有一個(gè)parent元素;

          var newdiv=document.createElement("div");
          // 異常:The element has no parent,此時(shí)newdiv并沒有被添加到DOM樹中,它并沒有父節(jié)點(diǎn),但是如果把下面行互換一下,就可以了;
          newdiv.insertAdjacentHTML("afterend", "<p>零點(diǎn)程序員</p>");
          document.body.appendChild(newdiv);

          基于insertAdjacentHTML()方法定義一個(gè)更符合語義邏輯的一個(gè)對象,如:

          // Insert.before()、Insert.after()、Insert.atStart()和Insert.atEnd()
          var Insert={
              before: function(e,h) {
                  if(e.parentElement)
                      e.insertAdjacentHTML("beforebegin", h);
              },
              after: function(e,h) {
                  if(e.parentElement)
                      e.insertAdjacentHTML("afterend", h);
              },
              atStart: function(e,h) {e.insertAdjacentHTML("afterbegin", h);},
              atEnd: function(e,h) {e.insertAdjacentHTML("beforeend", h);}
          };
          var mydiv=document.getElementById("mydiv");
          Insert.before(mydiv, "<h2>zeronetwork</h2>");
          // 或者
          // 假定where值為before、after、innerfirst和innerlast
          function insertHTML(el, where, html){
              if(!el) return false;
              var _where="beforeend";
              switch(where){
                  case "before":
                      _where="beforebegin";
                      break;
                  case "after":
                      _where="afterend";
                      break;
                  case "innerfirst":
                      _where="afterbegin";
                      break;
                  case "innerlast":
                      _where="beforeend";
                      break;
                  default:
                      _where="beforeend";
                      break;
              }
              if(_where=="beforebegin" || _where=="afterend"){
                  if(!el.parentElement)
                      return false;
              }
              el.insertAdjacentHTML(_where, html);
          }
          var mydiv=document.getElementById("mydiv");
          insertHTML(mydiv, "innerfirst", "<h2>zeronetwork</h2>");

          小示例,添加商品:

          <div class="container">
              <div class="formdiv">
                  <label>商品:</label><input type="text" id="product" /><br/>
                  <label>價(jià)格:</label><input type="text" id="price" /><br/>
                  <label>數(shù)量:</label><input type="text" id="quantity" /><br/>
                  <button id="btnAdd">添加</button>
              </div>
              <table class="table">
                  <thead>
                      <tr>
                          <th>序號</th><th>商品</th><th>價(jià)格</th><th>數(shù)量</th><th>金額</th>
                      </tr>
                  </thead>
                  <tbody id="data"></tbody>
              </table>
          </div>
          <script>
          var id=1;
          var btnAdd=document.getElementById("btnAdd");
          btnAdd.addEventListener("click",function(e){
              var content=document.getElementById("data");
              
              var product=document.getElementById("product").value;
              var price=document.getElementById("price").value;
              var quantity=document.getElementById("quantity").value;
              var total=price * quantity;
              var newEntry="<tr>" + 
                  "<td>" + id + "</td>" + 
                  "<td>" + product + "</td>" + 
                  "<td>" + price + "</td>" + 
                  "<td>" + quantity + "</td>" + 
                  "<td>" + total + "</td>" + 
                  "</tr>";
              content.insertAdjacentHTML('afterbegin', newEntry);
              id++;
          },false);
          </script>

          Element.insertAdjacentText(position, text)方法:

          該方法與insertAdjacentHTML()類似,只不過插入的是純文本內(nèi)容,它的作用是將一個(gè)給定的文本text插入到相對于被調(diào)用的元素的給定position位置;

          position的值insertAdjacentHTML()中的position是一樣的;

          var mydiv=document.getElementById("mydiv");
          mydiv.insertAdjacentText("afterbegin","王唯");
          mydiv.insertAdjacentText("afterend","zeronetwork");

          如果text是html字符串,也會(huì)被當(dāng)作純文本進(jìn)行處理,如:

          // 頁面輸出:<h2>王唯</h2>
          mydiv.insertAdjacentText("afterbegin","<h2>王唯</h2>");

          Element. insertAdjacentElement(position, element)方法:

          將一個(gè)給定的元素節(jié)點(diǎn)插入到相對于被調(diào)用的元素的給定的position位置;與insertAdjacentHTML()方法類似,只不過插入的是一個(gè)節(jié)點(diǎn)對象;該方法會(huì)返回一個(gè)Element對象;

          var mydiv=document.getElementById("mydiv");
          var div=document.createElement("div");
          div.innerHTML="<h2>zeronetwork</h2>";
          div.style.width="200px";
          div.style.height="100px";
          div.style.backgroundColor="lightgray";
          var newdiv=mydiv.insertAdjacentElement("beforeend", div);
          console.log(div===newdiv); // true

          github上有人分享了一個(gè)包裝的方法,就是利用以上原生的方法;

          // 把一個(gè)節(jié)點(diǎn)插入到DOM樹中的一個(gè)位置
          function dominsert(parent, child, position){
              var pos=position || 'beforeend';
              if(typeof child==='string')
                  dominsert.html(parent, child, pos);
              else
                  dominsert.element(parent, child, pos);
          }
          // 使用原生的insertAdjacentHTML()方法
          dominsert.html=function(parent, child, position){
              parent.insertAdjacentHTML(position, child);
          };
          // 使用原生的insertAdjacentElement()或insertBefore()方法
          dominsert.element=function(parent, child, position){
              if(parent.insertAdjacentElement)
                  parent.insertAdjacentElement(position, child);
              else{
                  switch (position){
                      case "beforebegin":
                          parent.parentNode.insertBefore(child, parent);
                          break;
                      case "afterbegin":
                          parent.insertBefore(child, parent.firstChild);
                          break;
                      case "beforeend":
                          parent.appendChild(child);
                          break;
                      case "afterend":
                          parent.parentNode.insertBefore(child, parent.nextSibling);
                          break;
                  }
              }
          };
          var mydiv=document.getElementById("mydiv");
          dominsert(mydiv,"<span>web前端</span>");
          dominsert(mydiv, "<b>零點(diǎn)程序員</b>", 'beforebegin');
          console.log(mydiv);

          內(nèi)存和性能問題:

          使用以上的方法替換子節(jié)點(diǎn)可能會(huì)導(dǎo)致瀏覽器的內(nèi)存占用問題,尤其是在IE中,問題更加明顯;

          如果被刪除的子樹中的元素設(shè)置了事件處理程序或者引用了一個(gè)Javascript對象作為屬性,被刪除的元素與事件處理程序或引用的JS對象之間的綁定關(guān)系在內(nèi)存中并沒有一并刪除;如果這種情況頻繁出現(xiàn),頁面占用的內(nèi)存數(shù)量就會(huì)明顯增加;因此,在使用innerHTML、outerHTML屬性和insertAdjacentHTML()方法時(shí),最好手工先移除要被替換的元素的所有事件處理程序和JS對象屬性;

          不要反復(fù)地使用innerHTML插入HTML;

          var arr=["HTML","CSS","JavaScript"];
          var ul=document.getElementById("myList");
          for(var i=0,len=arr.length; i < len; i++){
              ul.innerHTML +="<li>" + arr[i] + "</li>"; 
          }

          ,最好的做法是:單獨(dú)構(gòu)建字符串變量,再一次性的把結(jié)果賦給innerHTML;

          console.time("insert");
          var lisHTML="";
          for(var i=0,len=arr.length; i<len;i++){
              lisHTML +="<li>" + arr[i] + "</li>";
          }
          ul.innerHTML=lisHTML;
          console.timeEnd("insert");

          adjacent三個(gè)方法與insertBefore()、appendChild()和innerHTML的比較;

          在某些時(shí)候,這些方法屬性都可以達(dá)到同樣的目的,但在實(shí)際開發(fā)中,要針對當(dāng)時(shí)的情況,選擇一個(gè)合適的方法,沒有哪個(gè)方法就一定比另外的方法更好,只有相對的合適;

          同時(shí),這三個(gè)方法的性能雖然不一樣,但相差不大,幾乎可以忽略;

          insertAdjacentHTML()與innerHTML屬性的性能:

          insertAdjacentHTML()方法不會(huì)重新解析它正在使用的元素,因此它不會(huì)破壞元素內(nèi)的現(xiàn)有元素,這就避免了額外的序列化步驟,但使用innerHTML時(shí),特別是在原有的基礎(chǔ)上追加元素時(shí),都會(huì)對原有的元素重新序列化,因此,前者比后者效率更快;

          appendChild()與insertAdjacentHTML()方法的性能;

          // time 10ms
          console.time("append");
          for(var i=0; i<1000; i++)
              mydiv.appendChild(document.createElement("div"));
          console.timeEnd("append");
          // tim 30ms
          console.time("adjacent");
          for(var i=0; i<1000; i++)
              mydiv.insertAdjacentHTML("beforeend","<div></div>");
          console.timeEnd("adjacent");

          可以看到appendChild()方法比insertAdjacentHTML()方法快很多,但是改進(jìn)以上代碼后,為其添加有文本內(nèi)容的元素,如;

          // time 30ms多
          console.time("append");
          for(var i=0; i<1000; i++){
              var div=document.createElement("div");
              var h2=document.createElement("h2");
              h2.appendChild(document.createTextNode("零點(diǎn)程序員"));
              div.appendChild(h2);
              var p=document.createElement("p");
              p.appendChild(document.createTextNode("由大師哥王唯主講"));
              div.appendChild(p);
              mydiv.appendChild(div);
          }
          console.timeEnd("append");
          // time 40ms多
          console.time("adjacent");
          for(var i=0; i<1000; i++)
              mydiv.insertAdjacentHTML("beforeend","<div><h2>零點(diǎn)程序員</h2><p>由大師哥王唯主講</p></div>");
          console.timeEnd("adjacent");

          可以看到,兩者相差10ms,幾乎可以忽略不計(jì);

          比較appendChild()與insertAdjacentElement方法的性能;

          如:把測試appendChild()方法中的mydiv.appendChild(div)改成mydiv.insertAdjacentElement("beforeend", div);即可;

          發(fā)現(xiàn)兩者幾乎相同;

          比較insertBefore()與以上兩者的性能;

          如:把測試appendChild()方法中的mydiv.appendChild(div),改成mydiv.insertBefore(div, mydiv.lastChild);,結(jié)束也大同小異;

          小實(shí)例,排序表格;

          基于表格指定列中單元格的值來進(jìn)行排序;

          <table id="mytable"  border="1">
              <thead>
                  <tr>
                      <th>ID</th><th>Name</th><th>Sex</th>
                  </tr>
              </thead>
              <tbody>
              <tr>
                  <td>1</td><td>wangwei</td><td>女</td>
              </tr>
              <tr>
                  <td>2</td><td>jingjing</td><td>男</td>
              </tr>
              <tr>
                  <td>3</td><td>juanjuan</td><td>女</td>
              </tr>
          </tbody>
          </table>
          <script>
          // 根據(jù)指定表格每行第n個(gè)單元格的值,對第一個(gè)<tbody>中的行進(jìn)行排序
          // 如果存在comparator函數(shù)則使用它,否則按字母表順序比較
          function sortrows(table, n, comparator){
              var tbody=table.tBodies[0];  // 第一個(gè)<tbody>,可能是隱式創(chuàng)建的
              var rows=tbody.getElementsByTagName("tr");  // tbody中所有行
              rows=Array.prototype.slice.call(rows, 0);  // 變成數(shù)組
              // 基于第n個(gè)<td>元素的值進(jìn)行排序
              rows.sort(function(row1, row2){
                  var cell1=row1.getElementsByTagName("td")[n];  // 獲得第n個(gè)單元格
                  var cell2=row2.getElementsByTagName("td")[n];  // 同上
                  var val1=cell1.textContent || cell1.innerText; // 獲得文本內(nèi)容
                  var val2=cell2.textContent || cell2.innerText;
                  if(comparator) return comparator(val1,val2);  // 進(jìn)行排序
                  if(val1 < val2) return -1;
                  else if(val1 > val2) return 1;
                  else return 0;
              });
              // rows中已經(jīng)排好序,在tbody中按它們的順序把行添加到最后
              // 這將自動(dòng)把它們從當(dāng)前位置移走,并不是刪除,而是移動(dòng)
              for(var i=0; i<rows.length; i++){
                  tbody.appendChild(rows[i]);
              }
          }
          // 查找元素的<th>元素,讓它們可單擊,可以按該列排序
          function makeSortable(table){
              var headers=table.getElementsByTagName("th");
              for(var i=0; i<headers.length; i++){
                  (function(n){
                      headers[i].onclick=function() {
                          sortrows(table, n);
                      };
                  }(i));
              }
          }
          var mytable=document.getElementById("mytable");
          makeSortable(mytable);
          </script>

          小實(shí)例,生成目錄表:

          <style>
          #TOC{border:solid black 1px; margin:10px; padding: 10px;}
          .TOCEntry{}
          .TOCEntry a{text-decoration: none;}
          .TOCLevel1{font-size: 2em;}
          .TOCLevel2{font-size: 1.5em; margin-left: 1em;}
          .TOCSectNum::after{content: ": ";}
          </style>
          <script>
          // 當(dāng)執(zhí)行這個(gè)函數(shù)時(shí)會(huì)去文檔中查找id為"TOC"的元素;
          // 如果這個(gè)元素不存在,就創(chuàng)建一個(gè)元素
          // 生成的TOC目錄應(yīng)當(dāng)具有自己的CSS樣式,整個(gè)目錄區(qū)域的樣式className設(shè)置為"TOCEntry";
          // 為不同層級的目錄標(biāo)題定義不同的樣式,<h1>標(biāo)簽生成的標(biāo)題className為"TOCLevel1",
          // <h2>標(biāo)簽生成的標(biāo)題className為”TOCLevel2“,以此類推;段編號的樣式為"TOCSectNum"
          function createToc(){
              // 查找TOC容器元素,如果不存在,則在文檔開頭處創(chuàng)建一個(gè)
              var toc=document.getElementById("TOC");
              if(!toc){
                  toc=document.createElement("div");
                  toc.id="TOC";
                  document.body.insertBefore(toc, document.body.firstChild);
              }
              // 查找所有的標(biāo)題元素
              var headings;
              if(document.querySelectorAll)
                  headings=document.querySelectorAll("h1,h2,h3,h4,h5,h6");
              else
                  headings=findHeadings(document.body, []);
              // 遞歸遍歷document的body,查找標(biāo)題元素
              function findHeadings(orrt, sects){
                  for(var c=root.firstChild; c!=null; c=c.nextSibling){
                      if(c.nodeType !==1) continue;
                      if(c.tagName.length==2 && c.tagName.charAt(0)=="H")
                          sects.push(c);
                      else
                          findHeadings(c, sects);
                  }
                  return sects;
              }
              // 初始化一個(gè)數(shù)組來保存跟蹤章節(jié)號
              var sectionNumbers=[0,0,0,0,0,0];
              // 循環(huán)找到所有標(biāo)題元素
              for(var h=0; h<headings.length; h++){
                  var heading=headings[h];
                  // 跳過在TOC容器中的標(biāo)題元素
                  if(heading.parentNode==toc) continue;
                  // 獲取標(biāo)題的級別
                  var level=parseInt(heading.tagName.charAt(1));
                  if(isNaN(level) || level < 1 || level > 6) continue;
                  // 對于該標(biāo)題級別增加sectionNumbers對應(yīng)的數(shù)字
                  // 并重置所有標(biāo)題比它級別低的數(shù)字為零
                  sectionNumbers[level-1]++;
                  for(var i=level; i<6; i++) sectionNumbers[i]=0;
                  // 將所有標(biāo)題級的章節(jié)號組合產(chǎn)生一個(gè)章節(jié)號,如2.3.1
                  var sectionNumber=sectionNumbers.slice(0, level).join(".");
                  // 為標(biāo)題級別增加章節(jié)號
                  // 把數(shù)字放在<span>中,使得其可以秀樣式修飾
                  var span=document.createElement("span");
                  span.className="TOCSectNum";
                  span.innerHTML=sectionNumber;
                  heading.insertBefore(span, heading.firstChild);
                  // 用命名的錨點(diǎn)將標(biāo)題包起來,以便為它增加鏈接
                  var anchor=document.createElement("a");
                  anchor.name="TOC" + sectionNumber;
                  heading.parentNode.insertBefore(anchor, heading);
                  anchor.appendChild(heading);
                  // 為該節(jié)創(chuàng)建一個(gè)鏈接
                  var link=document.createElement("a");
                  link.href="#TOC" + sectionNumber; // 鏈接目標(biāo)地址
                  link.innerHTML=heading.innerHTML; // 鏈接文本與實(shí)際標(biāo)題一致
                  // 將鏈接放在一個(gè)div中,div用基于級別名字的樣式修飾
                  var entry=document.createElement("div");
                  entry.className="TOCEntry TOCLevel" + level;
                  entry.appendChild(link);
                  // 該div添加到TOC容器中
                  toc.appendChild(entry);
              }
          };
          window.onload=function(){createToc();}
          </script>

          Web前端開發(fā)之Javascript

          信息爆炸的大數(shù)據(jù)時(shí)代,我們每天都被無數(shù)的數(shù)據(jù)包圍。如何在這茫茫的數(shù)字海洋中迅速找到自己所需的信息?傳統(tǒng)的搜索方式或許已經(jīng)無法滿足我們的需求。此時(shí),一種名為“爬蟲”的技術(shù)逐漸嶄露頭角,成為了大數(shù)據(jù)時(shí)代中不可或缺的利器。

          下面舉個(gè)小例子講講爬蟲可以做什么?以Python工具爬取王者榮耀官網(wǎng)的英雄人物頭像為例,將網(wǎng)頁上的圖片爬取并保存,Python爬蟲爬取網(wǎng)頁圖片可以分為四步:明確目的、發(fā)送請求、數(shù)據(jù)解析、保存數(shù)據(jù),具體實(shí)例操作如下。

          1.爬蟲案例

          1.1 明確目的

          打開王者榮耀英雄介紹主頁,該主頁包含很多種英雄的頭像圖片,主頁網(wǎng)址鏈接如下。

          官網(wǎng)地址:https://pvp.qq.com/web201605/herolist.shtml

          1.2 發(fā)送請求

          使用requests庫發(fā)送請求,返回狀態(tài)碼顯示為200,服務(wù)器連接正常。

          import requests
          u='https://pvp.qq.com/web201605/herolist.shtml'
          response=requests.get(u)
          print('狀態(tài)碼:{}'.format(response.status_code))
          if response.status_code !=200:
              pass
          else:
              print("服務(wù)器連接正常")

          1.3 數(shù)據(jù)解析

          在數(shù)據(jù)解析之前,需要提前安裝pyquery,pyquery庫類似于Beautiful Soup庫,初始化的時(shí)候,需要傳入HTML文本來初始化一個(gè)PyQuery對象,它的初始化方式包括直接傳入字符串,傳入U(xiǎn)RL,傳入文件名等等,這里傳入U(xiǎn)RL,并且查找節(jié)點(diǎn)。

          #解析數(shù)據(jù)
          from pyquery import PyQuery
          
          doc=PyQuery(html)
          items=doc('.herolist>li')#.items()
          print(items)

          同時(shí)遍歷,使用find函數(shù)查找子節(jié)點(diǎn),遍歷爬取圖片URL和圖片名。

          for item in items:
              url=item.find('img').attr('src')
              #print(url)
              urls='http:'+url
              name=item.find('a').text()
              #print(name)
              url_content=requests.get(urls).content

          1.4 保存數(shù)據(jù)

          最后保存數(shù)據(jù),需要提前新建一個(gè)文件夾用于數(shù)據(jù)存儲(chǔ),同時(shí),存儲(chǔ)數(shù)據(jù)的代碼需要寫在for循環(huán)里面,不然只會(huì)保存一張圖片。

          with open('C:/Users/尚天強(qiáng)/Desktop/王者榮耀picture/'+name+'.jpg','wb') as file:
                  file.write(url_content)
                  print("正在下載%s......%s"%(name,urls))

          同時(shí)加一個(gè)計(jì)時(shí)器,用于計(jì)時(shí)圖片爬取的時(shí)長,這里顯示圖片爬取共計(jì)耗時(shí)7.03秒。

          import time
          start=time.time()
          …
          end=time.time()
          print('圖片爬取共計(jì)耗時(shí){:.2f}秒'.format(end-start))

          爬取過程動(dòng)態(tài)演示如下,運(yùn)行過程很快。

          以上我們成功將王者榮耀的英雄人物頭像爬取下來,代碼文件中有高清頭像。

          Bright Data

          爬蟲,這個(gè)看似高深莫測的詞匯,實(shí)則卻是我們應(yīng)對大數(shù)據(jù)挑戰(zhàn)的得力助手。在這個(gè)數(shù)據(jù)無限增長的時(shí)代,爬蟲為我們開辟了一條快速、高效獲取信息的道路,上面的實(shí)例需要編程基礎(chǔ),這里給大家介紹使用Bright Data無編程爬取數(shù)據(jù)。

          2.1 Bright Data 注冊

          要使用Bright Data的功能,首先我們要在其官網(wǎng)注冊,使用個(gè)人郵箱即可注冊,注冊完成后的界面如下所示。

          官網(wǎng)地址:https://get.brightdata.com/dhsjfx

          2.2 主要功能

          登錄官網(wǎng)后,可以看到在主界面中已經(jīng)展示了常用的功能:代理&爬蟲基礎(chǔ)設(shè)施與數(shù)據(jù)集和Web Scraper IDE,分別介紹其功能。

          代理&爬蟲基礎(chǔ)設(shè)施:最快且穩(wěn)定的代理網(wǎng)絡(luò),靜態(tài)動(dòng)態(tài)IP覆蓋全球195個(gè)國家,告別反爬限制和封鎖。包括:

          • 代理網(wǎng)絡(luò):動(dòng)態(tài)住宅,靜態(tài)住宅ISP,機(jī)房代理和移動(dòng)代理。
          • 亮網(wǎng)絡(luò)解鎖器:全方位自動(dòng)解鎖
          • 試用SERP API輕松解鎖搜索引擎結(jié)果

          數(shù)據(jù)集和Web Scraper IDE:不管是完整豐富的大數(shù)據(jù)集,還是大規(guī)模輕松開發(fā)數(shù)據(jù)挖掘抓取工具,都能在此找到。包括:

          • 數(shù)據(jù)集
          • 訂制數(shù)據(jù)集
          • Web scraper IDE/網(wǎng)頁爬蟲IDE

          2.3 代理&爬蟲基礎(chǔ)設(shè)施

          在進(jìn)行網(wǎng)絡(luò)爬蟲工作時(shí),許多網(wǎng)站會(huì)采取一些措施來限制或阻止來自特定 IP 地址的訪問。這主要是為了防止過度抓取和保護(hù)網(wǎng)站數(shù)據(jù)的隱私。因此,如果你使用的是固定的 IP 地址進(jìn)行爬蟲操作,很可能會(huì)遇到訪問受限的問題。

          為了避免該情況,許多爬蟲開發(fā)者選擇使用代理 IP。代理 IP 是一種隱藏真實(shí) IP 地址的方法,通過代理服務(wù)器進(jìn)行數(shù)據(jù)傳輸。當(dāng)你使用代理 IP 進(jìn)行爬蟲操作時(shí),網(wǎng)站服務(wù)器接收到的請求會(huì)顯示為代理服務(wù)器的 IP 地址,而不是你的真實(shí) IP,Bright Data含有多種代理IP功能。

          使用代理 IP 的好處在于,你可以更換不同的代理 IP 來訪問目標(biāo)網(wǎng)站,這樣即使某個(gè)代理 IP 被限制或封禁,你仍然可以通過其他可用的代理 IP 繼續(xù)進(jìn)行爬蟲操作。此外,使用真實(shí)的代理 IP 還可以幫助你更好地模擬真實(shí)用戶的訪問行為,提高爬蟲的效率和成功率。

          2.4 數(shù)據(jù)集和Web Scraper IDE

          在數(shù)據(jù)科學(xué)和機(jī)器學(xué)習(xí)的世界里,一個(gè)龐大的數(shù)據(jù)集是必不可少的。有時(shí)候,為了獲得所需的數(shù)據(jù),我們需要從網(wǎng)站上抓取信息。而這個(gè)過程,雖然必要,但往往也是耗時(shí)和復(fù)雜的。幸運(yùn)的是,一些平臺和工具已經(jīng)為我們提供了方便的解決方案。

          在Web Scraper IDE中,官方為我們提供了許多知名站點(diǎn)的爬取數(shù)據(jù)。這意味著,你不需要從零開始,手動(dòng)地抓取每一個(gè)網(wǎng)站。你可以直接使用這些已經(jīng)爬好的數(shù)據(jù)集,節(jié)省大量的時(shí)間和精力。

          這些數(shù)據(jù)集通常覆蓋了各種領(lǐng)域,從社交媒體、新聞網(wǎng)站到電子商務(wù)平臺等。無論你是在進(jìn)行市場分析、內(nèi)容生成還是模式識別,都可以在這些數(shù)據(jù)集中找到你需要的數(shù)據(jù)。

          更令人興奮的是,這些數(shù)據(jù)集的質(zhì)量都是經(jīng)過嚴(yán)格篩選和清洗的,確保了數(shù)據(jù)的準(zhǔn)確性和完整性。你可以放心地使用這些數(shù)據(jù),而無需擔(dān)心數(shù)據(jù)的缺失或錯(cuò)誤。

          使用Web Scraper IDE提供的數(shù)據(jù)集,可以大大簡化數(shù)據(jù)抓取的過程,使你能夠更快地進(jìn)入數(shù)據(jù)分析的核心工作。如果你需要快速獲取高質(zhì)量的數(shù)據(jù),那么這些官方提供的數(shù)據(jù)集無疑是你的最佳選擇。

          2.5 Web Scraper IDE

          Bright Data還提供了 web 端的 IDE 工具,并提供了相關(guān)的示例代碼,你可以直接使用模板和對應(yīng)的代碼!也可以自己自定義爬蟲,可以按照你的需求來定制數(shù)據(jù)集,點(diǎn)擊制定按鈕即可進(jìn)入自定義數(shù)據(jù)集的界面。

          這里以爬取豆瓣電影TOP250的數(shù)據(jù)為例,按照提示的要求填入對應(yīng)的信息,填寫示例的URL時(shí),需要填寫至少兩條URL的鏈接,這樣才能爬取數(shù)據(jù)。

          接著,對于網(wǎng)頁返回的字段可以編輯字段名稱、數(shù)據(jù)類型等,限于爬取的數(shù)據(jù)信息,并且,返回的數(shù)據(jù)字段可以做預(yù)覽,提前查看爬取的數(shù)據(jù)結(jié)果。

          數(shù)據(jù)字段設(shè)置好后,就可以點(diǎn)擊下載按鈕將數(shù)據(jù)下來下來,這里有JSON和CSV兩種數(shù)據(jù)保存格式,通過預(yù)覽我們就可以看到爬取的基本數(shù)據(jù)信息,使用自定義爬取數(shù)據(jù)也很簡單。

          借助爬蟲,我們可以輕松抓取和整理數(shù)據(jù),無論你是需要大規(guī)模收集數(shù)據(jù),還是需要突破網(wǎng)站封鎖,或需要管理你的代理,Bright Data都能為你提供優(yōu)質(zhì)的服務(wù),如果你想學(xué)習(xí)Bright Data更多數(shù)據(jù)爬取功能,點(diǎn)擊閱讀原文,申請還可以免費(fèi)試用,開啟你的爬蟲之旅!


          主站蜘蛛池模板: 国产一区二区草草影院| 国产在线视频一区| 日韩内射美女人妻一区二区三区| 日本高清一区二区三区| 久久久91精品国产一区二区| 无码人妻精品一区二区蜜桃百度| 国产福利91精品一区二区| 久草新视频一区二区三区| 亚洲一区二区视频在线观看| 精品国产一区二区三区久| 中文字幕无线码一区二区| 人妻无码第一区二区三区| 精品一区二区久久久久久久网站| 精品久久国产一区二区三区香蕉| 无码精品前田一区二区| 无码精品不卡一区二区三区| 综合无码一区二区三区四区五区| 国产成人精品日本亚洲专一区| 亚洲国产老鸭窝一区二区三区| 久久精品一区二区三区AV| 日韩国产精品无码一区二区三区| 国产在线一区二区| 无码人妻一区二区三区在线视频| 日本成人一区二区| 3d动漫精品成人一区二区三| 任你躁国语自产一区在| 3d动漫精品一区视频在线观看| 无码AV中文一区二区三区| 精品国产一区二区三区四区 | 奇米精品视频一区二区三区| 免费日本一区二区| 一区二区三区午夜视频| 91成人爽a毛片一区二区| 亚洲一区精彩视频| 日韩精品中文字幕视频一区| 日本精品少妇一区二区三区 | 久久se精品一区二区| 亚洲AV日韩AV天堂一区二区三区| 精品无码人妻一区二区三区| 无码午夜人妻一区二区不卡视频| 激情爆乳一区二区三区|