摘要:摘要從一行代碼里面學(xué)點(diǎn),現(xiàn)如今,無處不在,因此關(guān)于的新知識(shí)也是層出不窮。全部代碼只有三行,但是你絕對可以把它放在一行里面完成現(xiàn)在,在你的瀏覽器的控制臺(tái)中輸入這段代碼,你會(huì)發(fā)現(xiàn)不同層都被使用不同的顏色添加了一個(gè)高亮的邊框。
摘要:從一行代碼里面學(xué)點(diǎn)JavaScript,現(xiàn)如今,JavaScript無處不在,因此關(guān)于JavaScript的新知識(shí)也是層出不窮。JavaScript的特點(diǎn)在于,要學(xué)習(xí)它的語法入門簡簡單,但是要精通使用它的方式卻是一件不容易的事。
現(xiàn)如今,JavaScript無處不在,因此關(guān)于JavaScript的新知識(shí)也是層出不窮。JavaScript的特點(diǎn)在于,要學(xué)習(xí)它的語法入門簡簡單,但是要精通使用它的方式卻是一件不容易的事。
來看看下面的這段代碼,它來自于谷歌“名猿”Addy Osmani在幾天前貼出的一段代碼,它的作用是用來調(diào)試你的CSS層。全部代碼只有三行,但是你絕對可以把它放在一行里面完成:
[].forEach.call($$("*"),function(a){ a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16) })
現(xiàn)在,在你的Chrome瀏覽器的控制臺(tái)中輸入這段代碼,你會(huì)發(fā)現(xiàn)不同HTML層都被使用不同的顏色添加了一個(gè)高亮的邊框。是不是非常酷?但是,簡單來說,這段代碼只是首先獲取了所有的頁面元素,然后使用一個(gè)不同的顏色為它們添加了一個(gè)1ps的邊框。想法很簡單,但是真要實(shí)現(xiàn)起來卻不是那么容易的一件事。在下面的內(nèi)容中,我們將一起一步一步學(xué)習(xí)如何理解上面的這段代碼。
選擇頁面中所有的元素我們需要做的第一件事情是獲取頁面中所有的元素,在上面的代碼中,Addy使用了一個(gè)Chrome瀏覽器中特有的函數(shù) $$。你可以在你的Chrome瀏覽器控制臺(tái)中輸入 $$("a"),然后你就能得到一個(gè)當(dāng)前頁面中所有錨元素的列表。
$$函數(shù)是許多現(xiàn)代瀏覽器命令行API中的一個(gè)部分,它等價(jià)于 document.querySelectorAll,你可以將一個(gè)CSS選擇器作為這個(gè)函數(shù)的參數(shù),然后你就能夠獲得當(dāng)前頁面中所有匹配這個(gè)CSS選擇器的元素列表。如果你在瀏覽器控制臺(tái)以外的地方,你可以使用 document.querySelectorAll("*") 來代替 $$("*")。更多關(guān)于 $$ 函數(shù)的詳細(xì)內(nèi)容可以查看Chrome開發(fā)者工具的文檔。
當(dāng)然,除了使用$$函數(shù)之外,我們還有一種更簡單的方法,document.all,雖然這并不是一種很規(guī)范的使用方法,但是它幾乎在每一個(gè)瀏覽器中都能運(yùn)行成功。
迭代所有的元素經(jīng)過第一步,我們已經(jīng)獲得了頁面內(nèi)所有的元素,現(xiàn)在我們想做的事情是遍歷每一個(gè)元素,然后為它們添加一個(gè)彩色邊邊框。但是上面的代碼究竟是怎么一回事呢?
[].forEach.call( $$("*"), function( element ) { /* 在這里修改顏色 */ });
首先,我們通過選擇器獲得的列表是一個(gè)NodeLists對象,它和JavaScript中的數(shù)組有點(diǎn)像,你可以使用方括號(hào)來獲取其中的節(jié)點(diǎn),你也可以檢查它其中包含多少個(gè)元素,但是它并沒有實(shí)現(xiàn)數(shù)組包含的所有方法,因此我們并不能使用$$("*").forEach()來進(jìn)行迭代。在JavaScript中,有好幾個(gè)類似于數(shù)組但是并不是數(shù)組的對象,除了前面的NodeLists,還有函數(shù)的參數(shù)集合arguments,在這里我們可以使用call或apply函數(shù)將函數(shù)的方法運(yùn)用到這些對象上。例如下面的例子:
function say(name) { console.log( this + " " + name ); } say.call( "hola", "Mike" ); // 打印 "hola Mike" // 你也可以將這種方法有用在arguments對象上 function example( arg1, arg2, arg3 ) { return Array.prototype.slice.call(arguments, 1); // Returns [arg2, arg3] }
在Addy的代碼中,使用了[].forEach.call而不是Array.prototype.forEach.call,二者等價(jià),但是前者可以節(jié)省幾個(gè)字節(jié)。
為元素添加顏色為了讓元素都有一個(gè)漂亮的邊框,我們在上面的代碼中使用了CSS屬性outline。outline屬性位于CSS盒模型之外,因此它并不影響元素的屬性或者元素在布局中的位置,這對于我們來說非常有用。這個(gè)屬性和修改border屬性非常類似,因此下面的代碼應(yīng)該不會(huì)很難理解:
a.style.outline="1px solid #" + color
真正有趣的地方在于定義顏色部分:
~~(Math.random()*(1<<24))).toString(16)
天吶,上面的代碼是什么意思?在JavaScript中,比特操作符并不是經(jīng)常被使用,因此這里可能會(huì)讓很多程序員感到很疑惑。
我們想達(dá)到的目的是活的一個(gè)十六進(jìn)制格式的顏色例如白色對應(yīng)的是FFFFFF,藍(lán)色對應(yīng)的是0000FF,或者隨便一個(gè)顏色37f9ac。雖然我們?nèi)祟愊矚g十進(jìn)制,但是我們的代碼常常會(huì)需要十六進(jìn)制的東西。
我們首先要學(xué)會(huì)如何使用toString函數(shù)將一個(gè)十進(jìn)制的數(shù)組轉(zhuǎn)換為一個(gè)十六進(jìn)制整數(shù)。這個(gè)函數(shù)可以接受一個(gè)參數(shù),如果參數(shù)缺省,默認(rèn)為十進(jìn)制,但是你完全可以使用別的數(shù)組:
(30).toString(); // "30" (30).toString(10); // "30" (30).toString(16); // "1e" 十六進(jìn)制 (30).toString(2); // "11110" 二進(jìn)制 (30).toString(36); // "u" 36是允許的最大參數(shù)值
除此之外,你可以使用parseInt函數(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"
因此,我們現(xiàn)在只需要一個(gè)位于0和ffffff之間的十六進(jìn)制數(shù),由于:
parseInt("ffffff", 16) == 16777215
而這里的16777215實(shí)際上是2^24-1。
如果你對二進(jìn)制數(shù)學(xué)熟悉的話,你可能會(huì)知道1<<24 == 16777216。
再進(jìn)一步,你每在1后面添加一個(gè)0,你就相當(dāng)于多做了一次2的乘方:
1 // 1 == 2^0 100 // 4 == 2^2 10000 // 16 == 2^4 1000000000000000000000000 // 16777216 == 2^24
因此,在這里我們可以知道Math.random()*(1<<24)表示一個(gè)位于0和16777216之間的數(shù)。
但是這里并沒有結(jié)束,因?yàn)镸ath.random返回的是一個(gè)浮點(diǎn)數(shù),但是我們只想要整數(shù)部分。我們的代碼中使用波浪號(hào)操作符來完成這件事。波浪操作符在JavaScript中被用來對一個(gè)變量進(jìn)行取反。
但是我們在這里并不關(guān)心取反,我們指向獲取整數(shù)部分。因此我們還可以知道兩次取反可以去掉一個(gè)浮點(diǎn)數(shù)的小數(shù)部分,因此~~的作用相當(dāng)于parseInt:
var a = 12.34, // ~~a = 12 b = -1231.8754, // ~~b = -1231 c = 3213.000001 // ~~c = 3213 ; ~~a == parseInt(a, 10); // true ~~b == parseInt(b, 10); // true ~~c == parseInt(c, 10); // true
當(dāng)然,我們還有一種更加簡潔的方法,使用OR操作符:
~~a == 0|a == parseInt(a, 10) ~~b == 0|b == parseInt(b, 10) ~~c == 0|c == parseInt(c, 10)
最終,我們獲得了一個(gè)位于0和16777216之間的隨機(jī)整數(shù),也就是我們想要的隨機(jī)顏色。此時(shí)我們只需要使用toString(16)將它轉(zhuǎn)化為十六進(jìn)制數(shù)即可。
總結(jié)現(xiàn)在,你已經(jīng)完全理解了前面的這一行代碼中的各個(gè)部分。作為一個(gè)程序員,我們應(yīng)該在完成工作之后多問自己幾遍為什么,還有沒有更好更簡潔的方法。當(dāng)然,最應(yīng)該做的事情當(dāng)然是多閱讀程序代碼,也許你就能從某一行代碼中學(xué)到很多新東西。
作者:野狗
原文鏈接:Learning much javascript from one line of code
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90943.html
摘要:起因是看到一道題目的另外一種解法特別有意思,同時(shí)也做一點(diǎn)正則的筆記,好理解。 這是一篇普通的教程,同時(shí)也是我的一篇筆記。起因是看到一道題目的另外一種解法特別有意思,同時(shí)也做一點(diǎn)正則的筆記,好理解。 題目 我印象中的這道題目是:有一組數(shù)組為[1,1,2,3,3,3,3,4,5,5,5,6,6]使用js把它變成[[1,1],2,[3,3,3],4,[5,5,5].[6,6]] 解法有很多,...
摘要:我是布小禪,一枚自學(xué)萌新,跟著我每天進(jìn)步一點(diǎn)點(diǎn)吧說了這么多暫時(shí)也就夠了,那么就告辭吧 文章目錄 ?? 前言 ??? 作者簡介 ??文件操作?1??、open函數(shù)...
摘要:但是,構(gòu)造函數(shù)注意是大寫的有點(diǎn)特別。構(gòu)造函數(shù)接受的參數(shù)中,第一個(gè)是要傳入的參數(shù)名,第二個(gè)是函數(shù)內(nèi)的代碼用字符串來表示。 Javascript是一門很吊的語言,我可能學(xué)了假的JavaScript,哈哈,大家還有什么推薦的,補(bǔ)充送那啥邀請碼。 本文秉承著:你看不懂是你SB,我寫的代碼就要牛逼。 1、單行寫一個(gè)評級組件 ★★★★★☆☆☆☆☆.slice(5 - rate, 10 - rate...
摘要:但是,構(gòu)造函數(shù)注意是大寫的有點(diǎn)特別。構(gòu)造函數(shù)接受的參數(shù)中,第一個(gè)是要傳入的參數(shù)名,第二個(gè)是函數(shù)內(nèi)的代碼用字符串來表示。 Javascript是一門很吊的語言,我可能學(xué)了假的JavaScript,哈哈,大家還有什么推薦的,補(bǔ)充送那啥邀請碼。 本文秉承著:你看不懂是你SB,我寫的代碼就要牛逼。 1、單行寫一個(gè)評級組件 ★★★★★☆☆☆☆☆.slice(5 - rate, 10 - rate...
閱讀 3687·2021-11-23 09:51
閱讀 1685·2021-10-22 09:53
閱讀 1362·2021-10-09 09:56
閱讀 868·2019-08-30 13:47
閱讀 2165·2019-08-30 12:55
閱讀 1611·2019-08-30 12:46
閱讀 1125·2019-08-30 10:51
閱讀 2422·2019-08-29 12:43