ccforward / cc

Code & Blog
1.59k stars 193 forks source link

2.CSS Layout debug #3

Open ccforward opened 9 years ago

ccforward commented 9 years ago

一行代码调试 CSS

github代码地址

一、代码

108字节

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

131字节

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

更短的版本:82字节版本

使用hsl颜色 for(i=0;A=$$("*")[i++];)A.style.outline="solid hsl("+(A+A).length*9+",99%,50%)1px"

二、源码解读

代码先转成三行

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

1、选取页面所有DOM元素

函数$$();在现代浏览器的API中几乎都有支持,等价于 document.querySelectorAll();

2、迭代DOM元素

$$('')将所有DOM元素转成NodeList对象,但这并不是一个JS数组,所以不能用`$$('').forEach()`方法来迭代,所以使用call或者apply方法来使用foreach

[].forEach.call 等价于 Array.prototype.forEach.call 不过前者字节更少

3、给元素添加ouline

首先,为什么使用outline 而不是 border?
因为border是在元素的CSS盒模型之内,outline在CSS盒模型之外,所以添加outline之后不会影响布局。

然后最有趣的部分:随机生成颜色函数 (~~(Math.random()*(1<<24))).toString(16)

我们使用十六进制的的颜色 0~ffffff
并且 parseInt('ffffff',16) == 16777215 == 2^24-1

位运算 1>>24 == 16777216

Math.random()*(1<<24) 返回 (0,16777216)之间的 _浮点数, 等于十六进制的 0~ffffff

使用~取反,~~连续取反可以去掉浮点数的小数部分,所以~~等价于parseInt()

    ~12.3 == -13
    ~~12.3 == 12
    ~-12.98 == 11
    ~~12.98 == 12

使用toString(16)转换成16进制数(颜色)

其他

这篇原文下面的评论也很有意思,歪果仁写了更多版本的代码。

zhuiyings commented 6 years ago

~~第四个例子错了 ~~12.98 == 12