整合營銷服務商

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

          免費咨詢熱線:

          單線程的 JavaScript 是怎么實現(xiàn)異步的?

          單線程的 JavaScript 是怎么實現(xiàn)異步的?

          眾所周知,JavaScript是單線程的,但是不可避免的,JavaScript也需要進行一些異步任務,比如下面這個例子

          function foo() {
              console.log("first");
              setTimeout(( function(){
                  console.log( 'second' );
              }),5);
          }
           
          for (var i=0; i < 1000000; i++) {
              foo();
          }
          復制代碼

          上面這個例子,執(zhí)行結果會首先全部輸出first,然后全部輸出second,而不是交替執(zhí)行
          在這個過程中,很明顯發(fā)生了并發(fā)的異步任務,那么問題來了,單線程的
          JavaScript是怎么實現(xiàn)異步的?

          JavaScript為什么是單線程的?

          作為一個Java程序員,在知道了JavaScript是單線程之后,首先的反應就是不解,為什么一種語言會被設計成單線程的呢? 它為什么不能使用多線程來提高效率呢?

          JavaScript的單線程,與它的用途有關。作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復雜的同步問題。比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節(jié)點上添加內容,另一個線程刪除了這個節(jié)點,這時瀏覽器應該以哪個線程為準?

          所以,為了避免復雜性,從一誕生,JavaScript就是單線程,這已經成了這門語言的核心特征,將來也不會改變。

          JavaScript怎么實現(xiàn)異步?

          現(xiàn)在我們已經了解了JavaScript為什么是單線程的了,那么它又是怎么實現(xiàn)異步的呢?
          JavaScript的異步能力主要是由運行環(huán)境提供的

          JavaScript的運行環(huán)境

          JavaScript Runtime也就是JavaScript代碼運行的地方。比如JavaScript 可以在 chrome 中執(zhí)行,也可以在node中執(zhí)行,chromenode都是JavaScript Runtime

          由上圖可知,JavaScript Runtime主要包括Js EngineWebAPI等內容
          Js Engine將我們編寫的 JavaScript 轉換為更高效的機器碼,以實現(xiàn)更好的性能。
          chrome 瀏覽器中的 JavaScriptV8 引擎處理。V8引擎主要包括內存堆與執(zhí)行棧兩個部分

          • 內存堆:用于分配 JavaScript 程序使用的內存。
          • 執(zhí)行棧:在執(zhí)行棧中,您的 JS 代碼被讀取并逐行執(zhí)行。

          除了引擎,JavaScript Runtime也提供了WebAPIJS代碼調用,WebAPI提供了網絡請求,定時器,事件監(jiān)聽等多種能力
          因為
          JS Runtime并不是單線程的,而是持有一個線程池,因此WebAPI中的代碼是運行在其他線程的,自然也就提供了異步的能力

          事件循環(huán)機制

          • JS分為同步任務和異步任務,同步任務都在主線程上執(zhí)行,形成一個執(zhí)行棧
          • 棧中的代碼調用WebAPI時也就異步任務,異步任務執(zhí)行完成后,它們會在事件隊列中添加各種事件
          • 而棧中的代碼執(zhí)行完畢,就會讀取事件隊列中的事件,去執(zhí)行那些回調
          • 執(zhí)行棧與任務隊列如此循環(huán),也就是事件循環(huán)機制

          需要注意的是,一旦執(zhí)行棧中的所有同步任務執(zhí)行完畢(此時JS引擎空閑),系統(tǒng)就會讀取任務隊列,將可運行的異步任務添加到可執(zhí)行棧中
          因此
          setTimeout設置的時間并不是準確的,可能在它推入到事件列表時,主線程還不空閑,正在執(zhí)行其它代碼,因此存在誤差。

          總結

          JavaScript本質上是運行在瀏覽器里的腳本語言,為了簡單與避免操作DOM時引入同步問題,所以JavaScript被設計成了單線程的語言。
          JavaScript的異步能力是由運行環(huán)境提供的,通過WebAPI與事件循環(huán)機制,單線程的JS也可以執(zhí)行異步任務。

          最后

          如果你覺得此文對你有一丁點幫助,點個贊。或者可以加入我的開發(fā)交流群:1025263163相互學習,我們會有專業(yè)的技術答疑解惑

          如果你覺得這篇文章對你有點用的話,麻煩請給我們的開源項目點點star:http://github.crmeb.net/u/defu不勝感激 !

          完整源碼下載地址:https://market.cloud.tencent.com/products/33396

          PHP學習手冊:https://doc.crmeb.com
          技術交流論壇:https://q.crmeb.com

          者:vivo 互聯(lián)網前端團隊 - Zhang Jiqi


          本文主要講述了CSS中的級聯(lián)層(CSS@layer),討論了級聯(lián)以及級聯(lián)層的創(chuàng)建、嵌套、排序和瀏覽器支持情況。級聯(lián)層可以用于避免樣式沖突,提高代碼可讀性和可維護性。


          一、什么是級聯(lián)層(Cascade Layers)?


          1.1 級聯(lián)層的官方定義


          我們參看Cascading and Inheritance Level 5(13 January 2022) 中6.4節(jié)所述:

          級聯(lián)層提供了一種結構化的方式來組織和平衡單個起源中的問題。單個級聯(lián)層內的規(guī)則級聯(lián)在一起,不與層外的樣式規(guī)則交錯。


          開發(fā)者可以創(chuàng)建層來表現(xiàn)元素默認值、第三方庫、主題、組件、覆蓋和其他樣式問題,并且能夠以顯式方式重新排序層級,而無需更改每個層內的選擇器或特異性,或依賴源順序來解決跨層的沖突。


          單純看官方定義和概括可能比較晦澀,下面我們會結合案例來說清楚。


          1.2 級聯(lián)層為了解決什么問題?


          簡而言之:級聯(lián)層的出現(xiàn)就是為了使 CSS 開發(fā)者可以更簡單直接地控制級聯(lián)。


          我們來假設日常開發(fā)中的一個場景,從場景去理解級聯(lián)層在解決什么問題。


          如下圖:


          我們原來的'display'文案是紅色,當我們引入了一個第三方組件庫,第三方庫中有以下樣式。

          /* 開發(fā)者樣式 */
            .item {
              color: red;
            }
           
          /* 第三方庫 */
            #app .item {
              color: green;
              border: 5px solid green;
              font-size: 1.3em;
              padding: 0.5em;
              width: 120px;
            }


          就會導致'display'文案變成綠色。


          我們想要將'display'文案的顏色由綠色改成紅色一般的手段是增加選擇器特異性(優(yōu)先級)。比如在開發(fā)頁面中對開發(fā)者樣式進行修改:

           /* 開發(fā)者樣式 */
            #app div.item {
              color: red;
            }
           /* 第三方庫 */
            #app .item {
              color: green;
              border: 5px solid green;
              font-size: 1.3em;
              padding: 0.5em;
              width: 120px;
            }


          或者借助級聯(lián)中出場順序對優(yōu)先級的影響在用戶頁面中重寫

           /* 第三方庫 */
            #app .item {
              color: green;
              border: 5px solid green;
              font-size: 1.3em;
              padding: 0.5em;
              width: 120px;
            }
           /* 開發(fā)者樣式 */
            #app .item {
              color: red;
            }


          效果如下:


          再舉個例子:

          比如有可能第三方組件寫了

          a { color: blue; }


          那項目開發(fā)中由于引入這個第三方組件 就會導致樣式污染,因為第三方庫的樣式往往都在項目設置的通用樣式比如common.css后加載。


          如果后面想在代碼中覆蓋某些屬性,使用高特異性選擇器的語句就可能會導致問題。然后因為有問題就會選擇更高特異性的擇器的語句或使用!important,這會使代碼變得冗長也可能會帶來副作用。低特異性選擇器的語句很容易被后面出現(xiàn)在代碼中的語句覆蓋。在自己的代碼之后加載第三方 CSS 時特別會出現(xiàn)這種問題。


          所以級聯(lián)層就是為了解決以上場景出現(xiàn)的,級聯(lián)層在級聯(lián)中的的位置是在內聯(lián)樣式和選擇器特異性之間。當有些css聲明就是設置要低優(yōu)先級且不受選擇器特異性影響那么使用級聯(lián)層再合適不過。


          運用級聯(lián)層解決第一個日常開發(fā)場景痛點的css代碼如下:

          /* 排序層 */
          @layer reset, lib;
          /* 通用樣式 */
          @layer reset {
            #app .item {
              color: black;
              width: 100px;
              padding: 1em;
            }
          }
          /* 第三方庫樣式 */
          /*我們將第三方庫的樣式全部放到lib層*/
          /*這里一般使用@import導入的方式*/
          /*為了示例簡單我們簡化了操作*/
          
          
          @layer lib {
            #app .item {
              color: green;
              border: 5px solid green;
              font-size: 1.3em;
              width: 130px;
            }
          }
          /* 開發(fā)者樣式 */
          .item {
            color: red;
          }


          為了知道為什么上面的css代碼能解決沖突問題,更好地理解級聯(lián)層的作用,理解一些現(xiàn)象背后的根因,了解級聯(lián)層和級聯(lián)的關系,我們繼續(xù)往下看。


          二、理解級聯(lián)層的前提——級聯(lián)(cascade)


          2.1 什么是級聯(lián)?


          CSS中有兩個重要的基礎規(guī)則,一個是繼承,一個是級聯(lián)。


          繼承

          指的是類似 color,font-family,font-size,line-height 等屬性父元素設置后,子元素會繼承的特性。


          級聯(lián)

          可以簡單理解為是CSS 用來解決要應用于元素的具體樣式的算法。也就是基于一些優(yōu)先級排序輸出給給定元素上屬性值一個級聯(lián)值。級聯(lián)值是級聯(lián)的結果。


          2.2 當前級聯(lián)的排序標準


          我們參看Cascading and Inheritance Level 5(13 January 2022) 中6.1節(jié),

          相比于Cascading and Inheritance Level 4(14 January 2016) 中的定義有明顯變化。


          最重要的變化就是增加了級聯(lián)層。由此級聯(lián)排序變成:

          1. 起源和重要性(Origin and Importance)
          2. 上下文(Context)
          3. 樣式屬性(Element-Attached Styles)
          4. 層(Layers)
          5. 特異性(Specificity)
          6. 出場順序(又名源代碼順序)(Order of Appearance)


          瀏覽器在確定最終元素樣式呈現(xiàn)的時候,會依據這些準則按照優(yōu)先權從高到低排序,并且會一個一個的檢查,直到確定最終樣式。


          2.3 級聯(lián)起源(Cascading Origins)


          2.3.1 三個核心起源


          css中每個樣式規(guī)則有三個核心起源,它決定了它進入級聯(lián)的位置,理解起源優(yōu)先級是理解級聯(lián)的關鍵。

          • 用戶代理來源(瀏覽器內置樣式)
          • 用戶來源(瀏覽器的用戶設置 )
          • 作者來源(Web開發(fā)者)


          2.3.2 起源的優(yōu)先級


          Css聲明的起源取決于它來自哪里,重要性在于它是否用!important聲明。


          各種起源的優(yōu)先級按降序排列:

          1. 過渡
          2. 重要的用戶代理
          3. 重要用戶
          4. 重要作者
          5. 動畫
          6. 普通作者
          7. 普通用戶
          8. 普通用戶代理


          越靠前來源的聲明優(yōu)先級越高。過渡和動畫我們可以暫時忽略。


          2.4 熟悉又陌生的 !important


          通常作為開發(fā)者,!important會被我們視為一種增加特異性的方法,用以覆蓋內聯(lián)樣式或特異性較高的選擇器。


          但是!important設計出來的初衷是作為整體級聯(lián)中的一個特性,來平衡開發(fā)者、用戶設置和瀏覽器內置之間對css優(yōu)先級的影響能力。


          默認情況下三者的優(yōu)先級是:作者來源> 用戶來源>用戶代理來源(可以參看上文起源優(yōu)先級中6-8的排序)。但是當css聲明添加!important之后會使它們的優(yōu)先順序顛倒(參看上文起源優(yōu)先級中2-4的排序)。


          如果站在瀏覽器和用戶的角度看!important提供了在必要時重獲優(yōu)先級控制權的能力,而非只是簡單的增加特異性。


          舉個例子:

          瀏覽器默認樣式表包含我們開發(fā)者無法覆蓋的重要樣式。


          瀏覽器對具有'hidden'類型的input輸入框設置了默認的展示屬性并且將其聲明為重要。

          input[type=hidden i] { display: none !important; }


          看下面兩張圖例:


          第一張可以看出我們對具有'hidden'類型的input輸入框的展示屬性設置成了顯示并且聲明為重要


          第二張是樣式最終計算結果:隱藏


          從上面的瀏覽器表現(xiàn)可以看到我們作為開發(fā)者在作者樣式表中設置的規(guī)則沒能覆蓋用戶代理樣式表中的相同規(guī)則。


          這驗證了上面說的:在級聯(lián)中!important會顛倒三大核心起源默認優(yōu)先順序。


          驗證的過程中還發(fā)現(xiàn)了一個chrome控制臺這邊的bug,看上面的第一張圖例:沒生效的規(guī)則不劃刪除線,生效的反而劃刪除線了。


          再看一個官方文檔的例子加強一下理解:


          圖片來源:w3.org


          font-size的值最終是‘12pt ’。

          因為作者樣式表中添加!important的規(guī)則優(yōu)先權高于用戶樣式表中普通規(guī)則。


          text-indent的值最終是‘1em’。

          因為雖然兩個樣式表都標注了!important,但是標注!important用戶聲明優(yōu)先級大于標注!important作者聲明。


          2.5 一張圖帶你理解級聯(lián)


          下圖可以幫助我們直觀的理解級聯(lián)以及級聯(lián)層在級聯(lián)中的位置:


          圖片來源:css-tricks


          我們會發(fā)現(xiàn)平時操作最多的選擇器特異性(selector specificity)只是級聯(lián)中的一小部分。也輕松地理解了為什么內聯(lián)樣式優(yōu)先級天然高。同時我們會發(fā)現(xiàn)!important在級聯(lián)中有特殊地位。他穿插在級聯(lián)規(guī)則的各個階段并能顛倒優(yōu)先級。


          三、級聯(lián)層(CSS@layer) 使用探索


          3.1 @layer 是什么?


          我們來看MDN上的定義:

          The @layer CSS at-rule is used to declare a cascade layer and can also be used to define the order of precedence in case of multiple cascade layers.

          也就是說 @layer 這個at-rule(AT規(guī)則) 用于聲明級聯(lián)層(cascade layer),也能用于定義多個級聯(lián)層的優(yōu)先級。


          At-rules 是什么?

          At-rules是指導 CSS 如何表現(xiàn)的CSS 語句。它們以 at 符號 ' @' ( U+0040 COMMERCIAL AT) 開頭,后跟一個標識符,包括下一個分號 ' ;' ( U+003B SEMICOLON) 或下一個CSS 塊之前的所有內容。


          我們開發(fā)常見的at-rule有@charset、@media、@font-face 、@keyframes 等。


          3.2 @layer的句法規(guī)則


          @layer的句法如下:

          @layer layer-name {rules}
          @layer layer-name;
          @layer layer-name, layer-name, layer-name;
          @layer {rules}


          3.3 如何創(chuàng)建級聯(lián)層


          可以通過多種方式創(chuàng)建級聯(lián)層。


          第一種方法是:創(chuàng)建命名的級聯(lián)層,其中包含該層的 CSS 規(guī)則,如下所示:

          @layer green {
            .item {
              color: green;
              border: 5px solid green;
              font-size: 1.3em;
              padding: 0.5em;
              width: 120px;
            }
          }
           
          @layer special {
            .item {
              color: rebeccapurple;
            }
          }


          第二種方法是:創(chuàng)建一個命名的級聯(lián)層而不分配任何樣式。這可以是單層,如下所示:

          @layer green;


          可以一次定義多個層,如下:

          @layer green, special


          一次定義多個層有什么好處呢?

          因為聲明層的初始順序決定了層的優(yōu)先級。與聲明一樣,如果在多個層中找到聲明,最后定義的層聲明將最終生效。看下面代碼:

          @layer green,special;
           
          @layer green {
            #app .item {
              color: green;
              border: 5px solid green;
              font-size: 1.3em;
              padding: 0.5em;
              width: 120px;
            }
          }
          @layer special {
            .item {
              color: rebeccapurple;
            }
          }


          效果如下圖:


          special層中item樣式規(guī)則將被應用即使它的特異性低于 green層中的規(guī)則。這是因為一旦層順序定義完成,就會忽略選擇器特異性。


          同樣也會忽略出現(xiàn)的順序:

          我們聲明層名稱并設置它們的順序后,可以通過重新聲明名稱來將 CSS 規(guī)則添加到圖層。然后將樣式附加到層,并且層順序不會更改。比如如下代碼雖然@layer green重新聲明了并在文件后方但是由于順序一開始已經設置所以字體顏色還是紫色:

          @layer green,special;
           
          @layer special {
            .item {
              color: rebeccapurple;
            }
          }
           
          @layer green {
            .item {
              color: green;
              border: 5px solid green;
              font-size: 1.3em;
              padding: 0.5em;
              width: 120px;
            }
          }


          效果如下:


          忽略選擇器特異性和代碼出現(xiàn)順序可以讓我們創(chuàng)建更簡單的 CSS 選擇器,并使代碼優(yōu)雅,因為不必確保選擇器具有足夠高的特異性來覆蓋其他css規(guī)則,只需要確保它出現(xiàn)在后面的層中。


          第三種方法是:創(chuàng)建一個沒有名稱的級聯(lián)層。例如:

          @layer {
            .item {
              color: black;
            }
          }


          這將創(chuàng)建一個匿名級聯(lián)層,該層功能與命名層相同。但是使用匿名層有如下缺點:

          1. 可讀性較差:匿名層沒有名稱,會導致樣式表不易閱讀和理解。特別是在大型項目中,可能會出現(xiàn)樣式不斷增加,難以跟蹤和管理的問題。
          2. 難以擴展:如果稍后想要更改特定樣式或組合,也會很難找到特定的代碼塊。
          3. 不可復用性:匿名層中的樣式不能在其他地方重復使用或引用。這樣會使樣式表更難以管理和維護。


          平時我們盡量避免使用匿名層。但當我們是樣式庫的作者,并想將某些css代碼不被使用者修改可以借助匿名層做到這一點。


          第四種方法是:使用@import。CSS 原生支持 @import 導入其他 CSS 文件。

          @import url(index.css) layer(index);


          同時,也支持匿名引入,例如:

          @import url(index.css) layer;


          我們在使用@import時候需要放在除@charset之外的樣式規(guī)則前,否則無法導入。


          可能的第五種方式仍在討論中:通過元素上的屬性。請參閱[css-cascade] Provide an attribute for assigning ato a cascade layer #5853。


          3.4 層的嵌套規(guī)則


          圖層可以嵌套。例如:

          @layer base {
            p { max-width: 70ch; }
          }
           
          @layer framework {
            @layer base {
              p { margin-block: 0.75em; }
            }
           
            @layer theme {
              p { color: #222; }
            }
          }


          生成的層可以表示為一棵樹:

          1.base

          • framework
          • base

          2.theme


          或可以用扁平列表表示

          1. base
          2. framework.base
          3. framework.theme


          要將樣式附加到嵌套層,您需要使用以下全名來引用它:

          @layer framework {
            @layer default {
               p { margin-block: 0.75em; }
            }
           
            @layer theme {
              p { color: #222; }
            }
          }
           
          @layer framework.theme {
            /* 這些樣式會被添加到framework層里面的theme層 */
            blockquote { color: rebeccapurple; }
          }


          看效果:


          3.5 層的排序規(guī)則


          級聯(lián)層按照它們聲明的順序排序。第一層優(yōu)先級最低,最后一層優(yōu)先級最高。但是,未分層的樣式具有最高優(yōu)先級:

          /* 未分層 */a { color: green; }
          @layer layer-1 { a { color: red; } }
          @layer layer-2 { a { color: orange; } }
          @layer layer-3 { a { color: yellow; } }


          優(yōu)先級順序如下:

          1. 未分層樣式
          2. layer-3
          3. layer-2
          4. layer-1


          看下圖示例:


          層可以在一個地方被定義圖層(以建立圖層順序),然后在任何地方添加樣式

          /* 定義在一個地方 */
          @layer my-layer;
          /* 其他樣式*/
          ...
          /* 在某個地方添加樣式 */
          @layer my-layer { a { color: red; } }


          3.6 加上!important之后的排序規(guī)則


          /* 未分層 */ a { color: green !important; }
          @layer layer-1 { a { color: red !important; } }
          @layer layer-2 { a { color: orange !important; } }
          @layer layer-3 { a { color: yellow !important; } }


          任何加上重要聲明的樣式都以相反的順序應用


          優(yōu)先級順序如下:

          1. !important layer-1
          2. !important layer-2
          3. !important layer-3
          4. !important 未分層樣式


          看下圖示例:


          這里我們看到對應規(guī)則在chrome瀏覽器的顯示是正確的。但是在開發(fā)者控制臺中的樣式一欄規(guī)則顯示有問題。應該是chrome瀏覽器開發(fā)者控制臺的bug。


          3.7 嵌套層的排序規(guī)則


          @layer layer-1 { a { color: red; } }
          @layer layer-2 { a { color: orange; } }
          @layer layer-3 {
            @layer sub-layer-1 { a { color: yellow; } }
            @layer sub-layer-2 { a { color: green; } }
            /* 未嵌套 */ a { color: blue; }
          }
          /* 未分層 樣式 */ a { color: black; }
          
          


          優(yōu)先級順序如下:

          1. 未分層 樣式
          2. layer-3
          3. -layer-3 未嵌套
          4. -layer-3 sub-layer-2
          5. -layer-3 sub-layer-1
          6. layer-2
          7. layer-1



          3.8 媒體查詢對層排序的影響


          以下層順序將取決于匹配的媒體條件:


          例如:

          @media (min-width: 600px) {
             @layer layout {
               .item {
                 font-size: x-large;
               }
             }
           }
           
          @media (prefers-color-scheme: dark) {
            @layer theme {
               .item {
                  color: red;
               }
             }
          }


          如果兩個媒體查詢的規(guī)則中匹配一個那么對應的級聯(lián)層生效。如果兩者都匹配,那么圖層順序將為layout, theme都生效。如果兩個都不匹配則不定義層。下圖是兩者都匹配的場景。


          四、現(xiàn)在就能使用級聯(lián)層嗎?


          4.1 目前瀏覽器支持程度



          圖片來源:developer.mozilla.org


          目前所有現(xiàn)代瀏覽器均已經支持 @layer 規(guī)則。所有瀏覽器廠商都支持的特性未來一定比較實用。


          4.2 W3C 鼓勵可以作為日常使用


          SS 的標準化流程由 W3C Cascading Style Sheets Working Group (CSSWG)——W3C層疊樣式列表小組以及獨立CSS專家組成。W3C 本身并不制定標準,而是作為一個論壇式的平臺,接收來自小組成員的提交,并通過會議來商討制定標準,所有的提交以及討論都是公開透明的,可以在 W3C 網站上看到會議的記錄,可以簡單分為4個大階段:

          • 工作草案( WD )
          • 候選人推薦( CR )
          • 提議的建議( PR )
          • W3C 推薦( REC )


          下圖可以幫助理解:



          圖片來源:w3.org


          W3C 通過狀態(tài)碼表示規(guī)范的成熟度。成熟度從低到高排序如下圖。


          圖片來源:w3.org


          再看下圖:包含layer概念的標準討論已經到達CR階段。


          圖片來源:w3.org


          W3C 鼓勵從 CR階段的標準 開始可以作為日常使用。


          五、總結


          最后,我們回到通過級聯(lián)層如何解決“引入了一個第三方組件庫導致樣式覆蓋“的問題上。


          css代碼如下:

          /* 排序層 */
          @layer reset, lib;
          /* 通用樣式 */
          @layer reset {
            #app .item {
              color: black;
              width: 100px;
              padding: 1em;
            }
          }
          /* 第三方庫樣式 */
          /*我們將第三方庫的樣式全部放到lib層,這里一般使用@import導入的方式,為了示例簡單我們簡化了操作*/
          @layer lib {
            #app .item {
              color: green;
              border: 5px solid green;
              font-size: 1.3em;
              width: 130px;
            }
          }
          /* 開發(fā)者樣式 */
          .item {
            color: red;
          }



          我們將第三方庫的樣式全部放到lib層,將需要重置的一些樣式放到reset層,自己開發(fā)的樣式不放入層中(當然你也可以放入到一層然后排序在最后)。由此我們實現(xiàn)了樣式的分層解決了第三方組件庫導致樣式覆蓋的問題,而且做到開發(fā)者樣式簡單不冗長。


          效果如下:


          級聯(lián)層(CSS@layer)已經歷概念提出到到瀏覽器全面支持的階段。也許在不久的將來大家都會普遍使用它,期望本文能給大家?guī)硪欢◣椭?/span>


          參考資料:

          1. CSS Cascading and Inheritance Level 5
          2. A Complete Guide to CSS Cascade Layers
          3. The Future of CSS: Cascade Layers (CSS @layer)
          4. CSS必學基礎:理解CSS中的級聯(lián)規(guī)則
          5. 詳解日后定會大規(guī)模使用的CSS @layer 規(guī)則
          6. W3C Process Document
          7. Cascade Layers Explainer

          作者:Zhang Jiqi

          來源:微信公眾號:vivo互聯(lián)網技術

          出處:https://mp.weixin.qq.com/s/4M-RvnTq8rJuKDC3VZOONQ

          于網頁視頻下載,前段時間我分享過一篇博文:如何下載微信公眾號文章中的視頻,其原理是利用IDM的嗅探功能找到網頁視頻的真實地址然后下載。這個方法適用于大部分網站,也就是說個別網站不適用,因為有的網站會把視頻分成若干段,下載后要自己合并,更過分的是有的網站每幾百KB就分一段,下載完成后有時會有數百個片段需要合并,令人崩潰。還有的網站雖然能嗅探到真實地址,使用IDM下載一段時間后速度就成0了,看來是服務器端對下載工具進行了限制。更令人頭大的是,這樣的“個別網站”有越來越多的趨勢。

          為了能解決這些“個別網站”的視頻下載問題,我嘗試了github上的許多開源工具,如youtube-dl、you-get、annie等,這些工具都很強大,但每一個都不能覆蓋大部分網站,而且都是命令行方式運行的,對于小白很不友好。

          后來我終于找到一個集眾家之長的軟件:CR TubeGet,它集成了youtube-dl、you-get、annie三大開源視頻下載工具,可以輕松下載各大視頻網站中的視頻,對國內外常見的視頻網站均支持良好,IDM不能下載的幾個網站都能順利下載。CR TubeGet使用方法簡單,只要粘貼視頻頁的網址或者是將視頻頁網址拖拽至界面中就可以進行下載,支持多個任務同時下載,沒有速度限制。軟件集成了格式轉換工具,可以根據自己的需要將下載的視頻轉換成不同格式。

          CR TubeGet最新版本:1.6.4

          安裝包下載:http://crtubeget01.bj01.bdysite.com/softs/crtubeget_full.exe

          綠色包下載:http://crtubeget01.bj01.bdysite.com/softs/crtubeget.rar

          需要注意的是,CR TubeGet不注冊的話會有下載數量限制,只能免費下載99個視頻,想繼續(xù)使用可以購買授權碼,有包月、季度、包年、終身等幾種類型可選,價格從19到299不等,打開軟件后按照菜單指示操作即可完成注冊。

          如果不想花錢,也可以使用免費版(v0923),但是舊版只集成了youtube-dl,沒有you-get、annie支持,不過解析能力依舊很強,原生youtube-dl不支持的網站,實測v0923版的CR TubeGet照舊可以解析并下載。

          v0.9.2.3_免費版下載:http://www.cr-soft.net/v0923.html

          我最近下載過視頻的網站有好看視頻、西瓜視頻、騰訊視頻、優(yōu)酷、bilibili等,經測試,這款CR TubeGet都可以完美下載,有些甚至可以下載到沒有角標的高清版,可以說目前這款軟件是視頻下載的終極解決方案了。


          主站蜘蛛池模板: AV怡红院一区二区三区| 亚洲视频一区二区三区四区| 国产精品成人国产乱一区| 国产精品538一区二区在线| 国产精品一区二区AV麻豆| 福利一区二区三区视频午夜观看| 国产在线aaa片一区二区99| 色综合视频一区中文字幕| 亚洲综合无码一区二区三区| 无码人妻一区二区三区在线视频 | 国产免费私拍一区二区三区| 蜜臀Av午夜一区二区三区| 中文字幕精品一区二区| 国产在线精品一区二区夜色| 久久国产三级无码一区二区| 精品无码一区二区三区亚洲桃色| 国产一区二区三区不卡AV| 亚洲国产精品一区二区三区久久| 国产精品免费大片一区二区| 精品一区二区三区AV天堂| 伊人久久精品一区二区三区| 性色AV一区二区三区| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 精彩视频一区二区| 日韩精品无码一区二区三区免费| 中文字幕一区精品| 亚洲AV午夜福利精品一区二区| 深田咏美AV一区二区三区| 亚洲永久无码3D动漫一区| 影院成人区精品一区二区婷婷丽春院影视| 国产一区在线视频| 久久免费国产精品一区二区| 国产一区二区成人| 国产午夜三级一区二区三| 亚无码乱人伦一区二区| 亚洲日本一区二区| 国产精品区一区二区三| 韩国精品一区二区三区无码视频 | 国产乱码精品一区二区三| 伊人久久精品无码av一区| 亚无码乱人伦一区二区|