[].forEach.call($$("*"),function(a){
a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
})
尝试在你浏览器的Console(F12)中运行一下,你会发现页面被不同的颜色块高亮了,这个方法非常简单,但是你自己写的话可能产生非常多的代码,让我们来研究一下它是怎么实现的。
一 选择一个页面上的所有元素
我们首先需要选择页面上的所有元素。这里使用了只能在console调试工具中使用的$$函数,你可以在console中输入$$('a')自己试一下。它会返回当前页面的所有anchor(链接)元素。
$$与document.querySelectorAll是等价的。所以$$('*')与 document.querySelectorAll('*')是等价的,document.all 其实也能选取选用元素,而且兼容所有主流浏览器。。
二 遍历所有的元素
现在我们有了一个所有元素的节点列表(NodeList),现在我们想遍历它们,并给他们加上有颜色的边框。
[].forEach.call( $$('*'), function( element ) { /* code here */ });
涉及知识:类数组对象和数组有什么区别
常见的类数组对象有两种:arguments 和 nodeList。
典型的类数组对象:
var arrayLike = {'0': 'a', '1': 'b', '2': 'c', length:3};
类数组对象和数组的区别:
1.数组自动更新 length 属性
2.数组设置一个较小的 length 值,将截断数组
3.数组从 Array.prototype 继承了一些方法
4.数组的类型为 Array,类数组对象的类型为 Object
如何判断一个变量是 Array 类型
[] instanceof Array; // true;
var arr = [];
arr.constructor === Array; // true;
Object.prototype.toString.call([]) === "[object Array]"; // true
三 改变元素的颜色
让元素有一个漂亮的边框,这行代码使用了CSS的outline属性。有一点你可能不知道,在CSS渲染的盒子模型(Box Model)中,outline并不会改变元素及其布局的位置。因此这比使用border属性要好得多,所以这一部分其实并不难理解:
a.style.outline="1px solid #" + color
怎样定义颜色值其实是比较有意思的
~~(Math.random()*(1<<24))).toString(16)
这里涉及位运算,我们想构造的其实是一个16进制的颜色值,像白色FFFFFF,蓝色0000FF等等。
可以使用数字类型的toString方法进行十进制到16进制的转换。
其实你可以用它进行任意进制的转换:
(30).toString(); // "30"
(30).toString(10); // "30"
(30).toString(16); // "1e" 16进制
(30).toString(2); // "11110" 二进制
(30).toString(36); // "u" 36 是最大允许的进制
因此16进制中的ffffff其实是 parseInt("ffffff", 16) == 16777215,16777215是2^24 - 1的值
因此左位移操作乖以一个随机数 Math.random()*(1<<24) 可以得到一个0 到 16777216之间的值
但是还不够,Math.random返回的是一个浮点数字,我们只需要整数部,这里使用了“~”操作符(按位取反操作)。
这行代码并不关心正负值。因此通过两次取返就可以得到纯整数部,我们还可以将~~视为parseInt的简写。