從一行CSS調(diào)試代碼中學(xué)習(xí)JavaScript

CSS Layout Debugger

https://gist.github.com/addyosmani/fd3999ea7fce242756b1

現(xiàn)在到處都是JavaScript爆阶,每天都能知道點(diǎn)新東西寿桨。一旦你入了門劈伴,你總能從這里或是那里領(lǐng)悟到很多知識(shí)痕支。一旦我發(fā)現(xiàn)一些有意思的東西搬素,我喜歡去感覺他們的源代碼,看一看它是怎么辦到的闯冷。

今天我想分享Addy Osmani的一行代碼 铐维,這行代碼對于你調(diào)試你的CSS是很有用的。為了可讀性童叠,我把它變成了3行框喳。

[].forEach.call($$("*"),function(a){
    a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
})

*注:Addy Osmani 是Google Chrome開發(fā)工程師,他前幾天開發(fā)的字符串解析模板, 馬上被兼容最新ES6標(biāo)準(zhǔn)的io.js采納拯钻。 *

嘗試在你瀏覽器的Console(F12)中運(yùn)行一下帖努,你會(huì)發(fā)現(xiàn)頁面被不同的顏色塊高亮了,這個(gè)方法非常簡單粪般,但是你自己寫的話可能產(chǎn)生非常多的代碼拼余,讓我們來研究一下它是怎么實(shí)現(xiàn)的。

Tested from Chrome DevTools

選擇一個(gè)頁面上的所有元素

我們首先需要選擇頁面上的所有元素亩歹。Addy使用了只能在console調(diào)試工具中使用的$$函數(shù)匙监,你可以在console中輸入$$('a')自己試一下凡橱。它會(huì)返回當(dāng)前頁面的所有anchor(鏈接)元素。

$$document.querySelectorAll是等價(jià)的亭姥。所以$$('*')document.querySelectorAll('*')是等價(jià)的稼钩,有興趣的話可以看看$ $和$選擇器的歷史

對于我來說达罗,$$的使用已經(jīng)讓我學(xué)到了很多坝撑。但是選擇頁面上的所有元素的知識(shí)還有很多。Mathias Bynens就在評論中指出document.all 其實(shí)也能選取選用元素粮揉,而且兼容所有主流瀏覽器巡李。

遍歷所有的元素

現(xiàn)在我們有了一個(gè)所有元素的節(jié)點(diǎn)列表(NodeList),現(xiàn)在我們想遍歷它們,并給他們加上有顏色的邊框扶认。我們先看看能從這行代碼里發(fā)現(xiàn)什么:

[].forEach.call( $$('*'), function( element ) { /* And the modification code here */ });

NodeList看起來像一個(gè)Array(數(shù)組)侨拦,你可以使用中括號來訪問他們的節(jié)點(diǎn),而且你還可以通過length屬性知道它有多少元素辐宾。但是它并沒有實(shí)現(xiàn)Array的所有接口狱从,因此使用 $$('*').forEach 會(huì)返回錯(cuò)誤。

在JavaScript的世界里叠纹,有一堆看起來像Array但其實(shí)不是的對象季研。如function中的arguments對象。因此在他們身上通過callapply來應(yīng)用數(shù)組的方法是非常有用的吊洼。我之前寫過一篇文章來解析它們的用法训貌,下面是一個(gè)例子:

function say(name) {
 console.log( this + ' ' + name );
}

say.call( 'hola', 'Mike' ); // 打印輸出 'hola Mike'

// Also you can use it on the arguments object
function example( arg1, arg2, arg3 ) {
    return Array.prototype.slice.call(arguments, 1); // Returns [arg2, arg3]
}

之前的一行代碼使用[].forEach.call 代替 Array.prototype.forEach.call 減少了代碼的編寫量 ( 另外一個(gè)很有意思的地方 );如果$$('*')返回是個(gè)數(shù)組的話冒窍,它與$$('*').forEach是等價(jià)的。如果你看看評論豺鼻,還有人使用for(i=0;A=$$('*');)讓代碼變得更短综液,但是它在全局對象中注入了變量。你可以帶上var聲明儒飒,如

for(var i=0,B=document.querySelectorAll('*');A=B[i++];){ /* your code here */ }

其中iB將只聲明在console的上下文中谬莹。

改變元素的顏色

讓元素有一個(gè)漂亮的邊框,這行代碼使用了CSS的outline屬性桩了。有一點(diǎn)你可能不知道附帽,在CSS渲染的盒子模型(Box Model)中,outline并不會(huì)改變元素及其布局的位置井誉。因此這比使用border屬性要好得多蕉扮,所以這一部分其實(shí)并不難理解

a.style.outline="1px solid #" + color

怎樣定義顏色值其實(shí)是比較有意思的~~

(Math.random()*(1<<24))).toString(16);

我們想構(gòu)造的其實(shí)是一個(gè)16進(jìn)制的顏色值,像白色FFFFFF颗圣,藍(lán)色0000FF等等喳钟。首先我們學(xué)到了可以使用數(shù)字類型的toString()方法進(jìn)行十進(jìn)制到16進(jìn)制的轉(zhuǎn)換屁使。其實(shí)你可以用它進(jìn)行任意進(jìn)制的轉(zhuǎn)換:

(30).toString();   // "30"
(30).toString(10); // "30"
(30).toString(16); // "1e" 16進(jìn)制
(30).toString(2); // "11110" 二進(jìn)制
(30).toString(36); // "u" 36 是最大允許的進(jìn)制

另一方面,你可以使用parseInt()方法的第二個(gè)參數(shù)奔则,將十六進(jìn)制數(shù)轉(zhuǎn)換為十進(jìn)制:

parseInt("30"); // "30"
parseInt("30", 10); // "30"
parseInt("1e", 16); // "30"
parseInt("11110", 2); // "30"
parseInt("u", 36); // "30"

我們需要一個(gè)在0到ffffff之間的十六進(jìn)制數(shù)蛮寂,也就是parseInt("ffffff", 16) == 16777215,16777215正是2^24 - 1的值易茬。

二進(jìn)制中酬蹋,每次在1的右面加0,實(shí)際就是在做2^n運(yùn)算抽莱,n就是0的個(gè)數(shù)范抓。

1 // 1 == 2^0
100 // 4 == 2^2
10000 // 16 == 2^4
1000000000000000000000000 // 16777216 == 2^24

左移運(yùn)算 x << n 就是在二進(jìn)制數(shù) x 的右邊添加 n 個(gè) 0,1 << 24就是16777216的簡便寫法岸蜗。

Math.random() 返回取值范圍 [ 0 , 1 ) 內(nèi)的偽隨機(jī)數(shù)尉咕。

var a = Math.random()*2+1  //設(shè)置一個(gè)隨機(jī)1到3 (取不到3) 的變量

Math.random()*(1<<24)就可以得到一個(gè) 0 到 16777216之間的值。

但是Math.random返回的是一個(gè)浮點(diǎn)數(shù)字璃岳,我們只需要整數(shù)部年缎,這里使用了“~”操作符(按位取反操作)。

這里并不關(guān)心正負(fù)值铃慷,它利用“”按位操作丟棄小數(shù)部分单芜。因此通過兩次取反就可以得到純整數(shù)部,我們還可以將“~”視為parseInt的簡寫:

var a = 12.34; // ~~a = 12
var b = -1231.8754; // ~~b = -1231
var c = 3213.000001; // ~~c = 3213

~~a == parseInt(a, 10); // true
~~b == parseInt(b, 10); // true
~~c == parseInt(c, 10); // true

如果你仔細(xì)看原文評論犁柜,你會(huì)知道使用 按位或 "|"操作符也可以去掉小數(shù)部分洲鸠。

~~a == 0|a == parseInt(a, 10);
~~b == 0|b == parseInt(b, 10);
~~c == 0|c == parseInt(c, 10);

我們最終得到了一個(gè) 0 到 16777216之間的隨機(jī)數(shù),也就是需要的隨機(jī)顏色馋缅,使用toString(16)轉(zhuǎn)換成16進(jìn)制就可以運(yùn)行了扒腕。

github:Addy Osmani,原文鏈接:arqex.com萤悴,翻譯鏈接:ourjs.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘾腰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子覆履,更是在濱河造成了極大的恐慌蹋盆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硝全,死亡現(xiàn)場離奇詭異栖雾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)伟众,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進(jìn)店門析藕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赂鲤,你說我怎么就攤上這事噪径≈簦” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵找爱,是天一觀的道長梗顺。 經(jīng)常有香客問我,道長车摄,這世上最難降的妖魔是什么寺谤? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮吮播,結(jié)果婚禮上变屁,老公的妹妹穿的比我還像新娘。我一直安慰自己意狠,他們只是感情好粟关,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著环戈,像睡著了一般闷板。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上院塞,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天遮晚,我揣著相機(jī)與錄音,去河邊找鬼拦止。 笑死县遣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的汹族。 我是一名探鬼主播萧求,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼顶瞒!你這毒婦竟也來了饭聚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤搁拙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后法绵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箕速,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年朋譬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盐茎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,664評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡徙赢,死狀恐怖字柠,靈堂內(nèi)的尸體忽然破棺而出探越,到底是詐尸還是另有隱情,我是刑警寧澤窑业,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布钦幔,位于F島的核電站,受9級特大地震影響常柄,放射性物質(zhì)發(fā)生泄漏鲤氢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一西潘、第九天 我趴在偏房一處隱蔽的房頂上張望卷玉。 院中可真熱鬧,春花似錦喷市、人聲如沸相种。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寝并。三九已至,卻和暖如春缭黔,著一層夾襖步出監(jiān)牢的瞬間食茎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工馏谨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留别渔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓惧互,卻偏偏與公主長得像哎媚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子喊儡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內(nèi)容