日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

浏览器眼中的0

發(fā)布時間:2023/12/4 HTML 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浏览器眼中的0 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

0作為一個特殊的符號,經(jīng)常會跟瀏覽器打交道,在不同的場景下,0代表的意思不盡相同,因此瀏覽器眼中的0不一定就是符合人們感官上的認(rèn)識,那究竟瀏覽器會怎么對待它呢,今天我們就來探究一下各種場景中0的含義及瀏覽器的處理方式。

1.setTimeout

setTimeout在js中常用來推遲任務(wù)的執(zhí)行,可以通過第二個參數(shù)設(shè)置延遲的毫秒數(shù)(如果不設(shè)置,默認(rèn)為0),在一些代碼中,可以看到delay=0的情況,如下:

window.setTimeout(() => { ...... }, 0);

了解js的同學(xué)應(yīng)該知道,setTimeout的回調(diào)函數(shù)不會在定時器超時后立即執(zhí)行,如果delay大于0,比較好理解,但delay是0的時候呢,瀏覽器會怎么對待呢,這里要分兩種情況:
1.)timer嵌套
'Timers can be nested; after five such nested timers, however, the interval is forced to be at least four milliseconds.'也就是setTimeout嵌套超過5層的,并且延遲不到4ms,才會變成4ms,同樣適用于setInterval,因此在這種情況下,delay=0其實(shí)會被設(shè)置成4;
2.)timer沒有嵌套
在沒有嵌套情況下,對于chrome來說,delay=0也會設(shè)置成1;
說完瀏覽器的處理方式之后,我們來看看網(wǎng)上搬過來的一個例子吧:

setTimeout(()=>{console.log(5)},5)setTimeout(()=>{console.log(4)},4)setTimeout(()=>{console.log(3)},3)setTimeout(()=>{console.log(2)},2)setTimeout(()=>{console.log(1)},1)setTimeout(()=>{console.log(0)},0)

chrome打印結(jié)果:1 0 2 3 4 5;
firefox打印結(jié)果:0 1 2 3 4 5;
edge打印結(jié)果:1 2 0 3 4 5;
qq瀏覽器打印結(jié)果:1 0 2 3 4 5;
360瀏覽器打印結(jié)果:1 0 2 3 4 5;
從上面的打印結(jié)果來看,firefox是符合代碼預(yù)期的,edge打印與chrome稍有不同,應(yīng)該是edge處理delay=0情況稍有不同(設(shè)置成了2),qq和360瀏覽器跟chrome保持一致。
0ms定時器
在MDN文檔上,還說到一種實(shí)現(xiàn)0ms延時的定時器的實(shí)現(xiàn)方案,大體思路是自定義一個setZeroTimeout?方法,通過?postMessage?來觸發(fā)定時回調(diào)的執(zhí)行,具體可看?https://dbaron.org/log/20100309-faster-timeouts?;
node的setTimeout
說完瀏覽器中的setTimeout,我們再來看看nodejs中的是否一樣呢,可以通過nodejs的源代碼窺探一二:

// https://github.com/nodejs/node/blob/master/lib/internal/timers.jsfunction Timeout(callback, after, args, isRepeat, isRefed) {after *= 1; // Coalesce to number or NaNif (!(after >= 1 && after <= TIMEOUT_MAX)) { // const TIMEOUT_MAX = 2 ** 31 - 1;if (after > TIMEOUT_MAX) {process.emitWarning(`${after} does not fit into` +' a 32-bit signed integer.' + '\nTimeout duration was set t 1.', 'TimeoutOverflowWarning');}after = 1; // Schedule on next tick, follows browser behavior}

看過源代碼后,就知道node的處理策略了:如果delay=0,會設(shè)置為1,注釋也說得很清楚了,是為了遵循瀏覽器的行為。

2.+0&-0

雖然很少用到,但是js中確是存在+0和-0的,那么有什么區(qū)別呢:

+0 === -0; // true+0 === 0; // true-0 === 0; // true

可以看到,通過全等比較,+0,-0和0都是相等的,那是否就可以認(rèn)為這三者就是一樣的呢,還不能這么輕易下結(jié)論,有時候很有必要區(qū)分三者,那么如何判斷呢,es6新增了一個方法Object.is(value1, value2),可以用來判斷,具體效果如下:

Object.is(0, -0); // falseObject.is(+0, -0); // falseObject.is(+0, 0); // true

這里還需要說明的一點(diǎn)就是+0和0其實(shí)就是一樣的,因?yàn)?#43;0等效Number(0),因此Object.is(+0, 0)是符合預(yù)期的,這里順帶說一下Object.is的比較邏輯,根據(jù)MDN文檔描述,
Object.is()?方法判斷兩個值是否為同一個值。如果滿足以下條件則兩個值相等:

  • 都是?undefined

  • 都是?null

  • 都是?true?或?false

  • 都是相同長度的字符串且相同字符按相同順序排列

  • 都是相同對象(意味著每個對象有同一個引用)

  • 都是數(shù)字且

    • 都是?+0

    • 都是?-0

    • 都是?NaN

    • 或都是非零而且非?NaN?且為同一個值

與==?運(yùn)算不同。?==?運(yùn)算符在判斷相等前對兩邊的變量(如果它們不是同一類型) 進(jìn)行強(qiáng)制轉(zhuǎn)換 (這種行為的結(jié)果會將?"" == false?判斷為?true?), 而?Object.is?不會強(qiáng)制轉(zhuǎn)換兩邊的值。
與===?運(yùn)算也不相同。?===?運(yùn)算符 (也包括?==?運(yùn)算符) 將數(shù)字?-0?和?+0?視為相等 ,而將Number.NaN?與NaN視為不相等.

最后來看下如何生成-0和+0吧:

1/-Infinity; // -00*-1;// -01/+Infinity;// +00*+1;// +0

3. +[]

由于存在類型轉(zhuǎn)換,因此在判斷相等時,會有這樣的情況:

'' == 0; // true[] == 0; // true+[] == 0; // true

這里我們說一下+[]的情況,很容易理解,+相當(dāng)于Number([]),最終會轉(zhuǎn)換成0,這沒什么大不了,如果是下面這段代碼呢:

(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]]

其實(shí)代表的就是alert(1),?http://www.jsfuck.com/?這個奇葩網(wǎng)站專門干這事的,原理就是使用的類型轉(zhuǎn)換,把我們熟悉的代碼變成了這樣,真是騷操作。

4.font-size

font-size在css中使用頻繁,瀏覽器通常會默認(rèn)設(shè)置成14px或者16px。如果設(shè)置成0呢?

.foo {font-size: 0;}<span class="foo">foo</span>

文字真的就沒有了,這符合預(yù)期,但如果設(shè)置的值小于12(非負(fù)),各瀏覽器處理稍有不同,chrome/edge瀏覽器會設(shè)置最小字體為12px,firefox嚴(yán)格按照給定的值來顯示。
font-size:0的用處
在布局過程中,經(jīng)常會生成空白字符,例如:

<div class="box1"><span>a</span><span>b</span></div><div class="box2"><img src="xxx.jpg"></div>

box1和box2高度其實(shí)是略高于實(shí)際的內(nèi)容的,而且box1的兩個span中間有間隙,沒有緊挨著,因?yàn)榭瞻鬃址脑?#xff0c;引用css規(guī)范說明:On a block container element?whose content is composed of?inline-level?elements, ‘line-height’ specifies the minimal height of line boxes within the element. The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element’s font and line height properties. We call that imaginary box a “strut.”,大意就是一個塊級容器元素內(nèi)容區(qū)域由inline-level元素組成的;而這些linline-level元素被放在每一行的line-box里面,line-box高度是由它所有子元素的高度計(jì)算得出的。瀏覽器會計(jì)算這一行里每個子元素的高度,再得出 line-box 的高度(具體來說就是從子元素的最高點(diǎn)到最低點(diǎn)的高度)。默認(rèn)情況下,一個 line-box 總是有足夠的高度來容納它的子元素,而每一個行框可以想象為默認(rèn)會有一個寬度為0的空白節(jié)點(diǎn),字體大小和行高會影響該節(jié)點(diǎn),具體規(guī)范可查看?https://www.w3.org/TR/CSS2/visudet.html#line-height。
說完規(guī)范后,再來分析一下box1和box2的效果,為了便于理解,下面的代碼手動加入了一個[x]符號,代表strut:

<div class="box1"><span>a</span> <span>b</span>[x]</div><div class="box2"><img src="xxx.jpg">[x]</div>

box1的兩個span發(fā)生了換行,相當(dāng)于中間有個空格,因此會有間隙,如果span不換行,那么中間的空隙也就沒有了。由于存在[x],而且vertical-align:baseline的緣故,span/img和[x]的baseline對齊之后,[x]處于baseline以下的部分會撐開整個line-box的高度,因此會外部塊級容器的高度會略高一些,說得不清楚,我們還是上一張圖來說明吧:


粉色的線是圖片的baseline,紅色的線是strut的baseline,對齊之后strut的baseline下面還有一部分高度,box的最終高度就是img的頂部到strut底部之間的距離。分析完成因后,終于可以使用font-size:0來解決問題了,在box上設(shè)置font-size:0后,strut就相當(dāng)于沒有了,因此就不存在高度撐開的問題了,當(dāng)然這里還可以改變img的vertical-align屬性來修復(fù)這個問題,比如img{ vertical-align:bottom; }那么img的粉色線就跟strut的底部對齊了,也就不會撐開容器高度了,這里說了box2,box1原理差不多,這里涉及到vertical-align的知識了,可查閱https://www.w3.org/TR/CSS2/visudet.html#vertical-align?進(jìn)行了解。

5.width&height

width和height也是可以設(shè)置成0的,效果也是符合我們預(yù)期的,但如果我們的意圖是想通過設(shè)置0把元素隱藏的話,一般情況下會采用如下方案:

.visually-hidden {clip: rect(0 0 0 0);clip-path: inset(50%);height: 1px;width: 1px;overflow: hidden;position: absolute;white-space: nowrap;}

有些屏幕閱讀器會忽略width和height等于0的元素,因此這里特意設(shè)置成1px,當(dāng)然關(guān)于元素的隱藏還有很多實(shí)現(xiàn)方案,有興趣可參考【1】;

6.line-height

line-height及行高,原意是baseline之間的高度,在css中就是一行的高度。默認(rèn)情況下,line-height是跟具體字體定義相關(guān)聯(lián)的,一般都是font-size的1.x倍,如果設(shè)置成0,在不同類型元素上的情況是不一樣的,可分為如下三種情況:
1.)非置換行類元素
line-height定義的是最終參與計(jì)算line-box(行盒)的高度的值,而不會影響non-replaced inline element(非置換行類元素)的實(shí)際高度;

<style>.foo {line-height:0;}</style><div><span class="foo">a</span> // class為foo的span高度不會受樣式影響</div>

2.)行類塊級元素
會影響元素高度,如果line-height設(shè)置為0,那么該元素高度就變成了0,如果設(shè)置了height,那么height將會起作用;
3.)塊級元素
當(dāng)塊級元素包含inline-level(display:inline|inline-block)元素時, 行高定義的每一個line-box(行盒)的最小高度,此外height也能影響塊級元素的最終高度,height比line-height有更高優(yōu)先級,當(dāng)沒有height情況下,line-height起作用;
上面提到了line-box,如果有不了解的同學(xué),可以看一下文末的鏈接【2】;

7.transform

transform常用來做樣式變化和動畫,在有時候,會設(shè)置成如下形式:

transform: translateZ(0);

這其實(shí)是為了啟用GPU加速渲染,元素會單獨(dú)在一個繪制層(Layer)里進(jìn)行繪制,而不會對其他層產(chǎn)生影響,因此也就少了很多計(jì)算和合成的功能,而且不會阻塞主線程,動畫會更加流暢,當(dāng)然元素設(shè)置太多會導(dǎo)致性能降低,因?yàn)樾枰獌?nèi)存的維護(hù)。

參考資料:

【1】https://css-tricks.com/comparing-various-ways-to-hide-things-in-css/
【2】https://www.w3.org/TR/CSS2/visuren.html#line-box

總結(jié)

以上是生活随笔為你收集整理的浏览器眼中的0的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。