Chrome冷知识&黑科技

Chrome浏览器是开发人员的最爱,也在浏览器市场上占有较高的份额,但是他还有很多潜力等着我们去开发,现在最新的V51版本已经基本支持ES6的语法了,根据新闻消息谷歌还声称其将在V52版本提供ES7的支持,所以今天就来聊聊谷歌浏览器中的冷知识吧~

HTML篇


在浏览器地址栏中运行JS代码

在浏览器地址栏可以直接运行JavaScript代码,做法是以javascript:开头后跟要执行的语句.比如:

1
javascript:alert('hello from address bar :)');

将以上代码贴到浏览器地址栏回车后alert正常执行,一个弹窗神现.
需要注意的是如果是通过copy paste代码到浏览器地址栏的话,IE及Chrome会自动去掉代码开头的javascript:,所以需要手动添加起来才能正确执行,而Firefox中虽然不会自动去掉,但它根本就不支持在地址栏运行JS代码

浏览器地址栏运行HTML代码

在非IE内核的浏览器地址栏可以直接运行HTML代码!在地址栏输入以下代码然后回车运行,会出现指定的页面内容。

1
data:text/html,<h1>Hello, world!</h1>

浏览器也能当编辑器使

将以下代码贴到地址栏运行后浏览器变成了一个原始而简单的编辑器,与Windows自带的notepad一样,就问你怕不怕。

1
data:text/html, <html contenteditable>

归根结底都是因为HTML5中新加的contenteditable属性,当元素指定了该属性后,元素的内容成为可编辑状态。
同样的道理,将以下代码放到console执行后,整个页面将变得可编辑,随意践踏吧~

1
document.body.contentEditable='true';

页面拥有ID的元素会创建全局变量

在一张HTML页面中,所有设置了ID属性的元素会在JavaScript的执行环境中创建对应的全局变量,这意味着document.getElementById像人的阑尾一样显得多余了。但实际项目中最好老老实实该怎么写就怎么写,毕竟常规代码出乱子的机会要小得多。

1
2
3
4
<div id="sample"></div>
<script type="text/javascript">
console.log(sample); //输出DOM节点
</script>

加载CDN文件时,可以省掉HTTP标识

现在很流行的CDN即从专门的服务器加载一些通用的JS和CSS文件,出于安全考虑有的CDN服务器使用HTTPS方式连接,而有的是传统的HTTP,其实我们在使用时可以忽略掉这个,将它从URL中省去。

1
<script src="//domain.com/path/to/script.js"></script>

利用script标签保存任意信息

将script标签设置为type='text'然后可以在里面保存任意信息,之后可以在JavaScript代码中很方便地获取。

1
2
3
<script type="text" id="template">
<h1>This won't display</h1>
</script>

1
var text = document.getElementById('template').innerHTML

Console篇


大家都会用log,但鲜有人很好地利用console.error , console.warn等将输出到控制台的信息进行分类整理。
他们功能区别不大,意义在于将输出到控制台的信息进行归类,或者说让它们更语义化。
各个所代表的语义如下:

  • console.log:普通信息
  • console.info:提示类信息
  • console.error:错误信息
  • console.warn:警示信息

当合理使用上述log方法后,可以很方便地在控制台选择查看特定类型的信息。

特技,全都是特技

关于console.log,早已被玩儿坏了。一切都源于Chrome提供了这么一个API:第一个参数可以包含一些格式化的指令比如%c。

1
console.log('%chello world','font-size:25px;color:red;');

没错后面尾行的就是CSS属性,你可以大肆的用牛逼的CSS特效来展示,无论是渐变色还是关键帧动画!

官方给出的表格

Format Specifier Description
%s Formats the value as a string.
%d or %i Formats the value as an integer.
%f Formats the value as a floating point value.
%o Formats the value as an expandable DOM element (as in the Elements panel).
%O Formats the value as an expandable JavaScript object.
%c Formats the output string according to CSS styles you provide.

不过只是有文字怎么够玩,我们可以再加一点图片什么的

1
2
3
4
5
6
console.log(
"%c",
"padding:50px 300px;
line-height:120px;
background:url("giligili.gif") no-repeat;"
);

除此,console.table 更是直接以表格的形式将数据输出,挺好玩的!

1
2
3
var data = [{'品名': '杜雷斯', '数量': 4}, {'品名': '冈本', '数量': 3}]; 
console.table(data);
);

其实console还有其他一些方法,但是用的都比较少了,大家感兴趣可以去看看博文chrome控制台膜法师
还有一个神奇的方法获取页面元素,就是在控制台中使用$$选择器,这就相当于是原生querySelectorAll的方法

1
$$("body");

操作实例


1.shadow dom(是什么,封装组件)
2.不可描述

读Javascript高程之笔记

早期学习Javascript高程的一些笔记

1.<button>标签的默认type等同于input里面的submit,所以非常容易出现问题

2.对于不支持Script标签的浏览器,在里面用注释

<script><!--
..........
//--></script>

3.如果没有<!Doctype>的标签,浏览器默认进入混杂模式,并且DTD是外部引入的;

4.JS标识符的开头可以是字母,_和$;

5.注释中可以声明一些版权,或者变量的相关信息

/**
 * @copyright Redstar
 * @param temp A temporary variable
 */

6.在函数内部未用var定义的变量会升级为全局变量,在严格模式下会抛出错误

7.数字的科学计数表示只可用于十进制,八进制,十六进制都不行(其中十六进制是会把e认做14);

8.Number()方法可以读各进制的纯数字字符串为整数(浮点数),ParseInt()可以在字符串中把不能识别字符前边的读为数字,String()也类似;

9.瞧一瞧看一看

ParseInt(“AF”,16) = ParseInt(“0xAF”);   
ParseInt(“AF”) = NaN;

10.toLocalString()方法会执行对象的toString方法(如果设置了的话),toString()会把对象和子对象的toString都执行一遍;

11.计算时不难发现:

a)1 + 2 + “a” = “3a”;
b)“a” + 1 + 2 = ”a12”;
c)“a” + (1 + 2) = “a3”;

12.for循环判断体中设置的变量之后还是可以使用的

For(var i = 0;i < 3;i ++){
    Alert(123);
}
Alert(i);    //show the number “3”

13.循环体可以用一个名字在外做标签(label),之后用来break掉

Count:
For(var i = 0;i < 2;i ++){
    Alert(i ++);
    If(i == 1){
        Break count;
    }
}

14.with相当于创建了一个外部框架,其内可以直接使用他的属性,并且会建立自己的作用域,所以不建议使用;

15.Javascript中就算有setTimeOutsetInterval,他仍然不是多线程的;

16.发现了switch的一种非常奇特的用法

Var num = 25;
Switch(true){
    Case num > 0:
        Alert(123);
    Case num > 10:
        Alert(456);
    Default :
        Alert(789);
)

17.JS中没有重载这一个概念,因为它的函数参数都可以是不确定的,多次复写一个函数只会把它进行替换;

18.对象无法被直接拷贝,以下做法都是错误的示范:

Var o = new Object();
Var obj = o; //只是让指针指向同一块内存,并没有拷贝
Var obj = new Object(o); //同上

正确的做法是把对象的属性一个一个的对应在另一个对象之中单独建立,这样才能能够避免指向同一块内存的问题;

19.非常的奇怪哈,在函数中传入对象,对对象的属性进行操作后,会直接改变其属性,并不会因为函数执行完毕时内存的消除而失去效果。但是对于其他的数组,数字等等则不会有效果,证明对象的存储机制有待探究;

Function a (obj){
    Obj.num = 2;
}

Var o = new Object({
    Num = 0;
});

A(o);
Alert(o.num);  //结果出人意料的为2

20.全局变量的作用域其实就是window,所有全局变量和函数都是window的属性和方法;

21.Eval()函数会极大的影响js的性能;

var sum = 0;
console.log(new Date());
for(var t = 0;t < 1000000;t ++){
    sum += t;
}
console.log(new Date());
eval("for(var t = 0;t < 1000000;t ++){sum += t;}");
console.log(new Date());
for(t = 0;t < 1000000;t ++){
    eval("sum += t");
}
console.log(new Date());

得到的测试结果是:

Date 2015-12-08T08:27:10.777Z 0z
Date 2015-12-08T08:27:10.788Z 0.011z
Date 2015-12-08T08:27:11.155Z 0.367z
Date 2015-12-08T08:27:12.856Z 1.701z

可见在耗时的增长基本与eval的使用次数是成比例的,使用的时候千万不要把eval放到循环体里面;

22.在if,with块中声明的变量在执行完过后并不会被销毁:

If(true){
    Var a = 0;
}
Alert(a); // a = 0;

23.要让JS自带的垃圾清理机制清除一个变量只需要将他的值手动设为null;

24.new出来的String或者是Array等,使用typeof得到的都是”Object”;

25.数组的定义方式多种多样,甚至可以只打逗号

Var a = [,,,];  //length = 3
Var b = [1,2,];  //length = 2
Var c = [1,2,,];  //length = 3

26.数组的join方法返回一个由传入字符串分隔的字符串(这只是数组的方法)

Var arr = [1,2,3];
Alert(arr.join(“0”));  //10203

这一点应该可以用于输出标签上,比如每两个之间用
隔开

27.可以通过pop和push方法操作数组,他们是在数组尾部进行操作,能够做到堆栈一样的效果,push返回参数为数组长度,pop返回出栈元素;

28.和上面相似的还有shift和unshift方法,他们在数组的头部进行操作,如果用unshift传入多个参数的话,他们在数组中的顺序不会改变;

29.IE7及以前的浏览器对于unshift的返回值不是新的长度,而是undefined;

30.自带的sort排序函数比较鬼畜,是把所有东西都按照类似字符串排序的方法来的(数字也不例外),比如0,10,11,5就是一个排序后的结果;如果要让他按照需求来排序就得传入一个排序判断函数,话不多说剩下的自己百度;

31.Slice方法可以方便的从数组中截取一段。Splice方法依次传入删除起始位置,删除数目,添加项目可实现删除,替换的功能;

32.IE8+和其他一些的浏览器支持querySelector的方法,这个方法比getElementById更加高效也更简便,用法和CSS选择器基本一致(但是不能选择伪类如”:hvoer”),并且效率更高

Date 2015-12-09T13:55:06.928Z 0z
Date 2015-12-09T13:55:06.934Z 0.006z
Date 2015-12-09T13:55:06.935Z 0.001z

第一个是用的getElementById,第二个是querySelector,执行1E7次,效果很明显;

33.在IE9+等浏览器中IndexOf获取元素在数组中第一次出现的位置,IndexLastOf则是最后一次出现;

34.数组有几个迭代方法非常有意思,有时间要探究一下他们的兼容性

  1. Every对于所有元素执行后的返回值都为true才返回true
  2. Filter将执行后的返回结果的值为true的元素进行返回,返回的是一个数组
  3. Foreach仅仅执行函数,不返回任何值
  4. Some对于所有函数的返回值只要存在一个为true结果即为true
  5. Map返回一个执行后的结果数组

这几种方法只需要传入函数的参数名,在执行的函数中可以通过形参获取数据的值,三个值分别为item,index,array;

35.Date的构造函数可以传入两种参数,传入字符串或以逗号分隔开的ISO-608格式的时间

36.Date的now方法可以获取到现在的时间(以毫秒计算),对于IE9之前的浏览器,可以在前面添上一个+号;

37.有很多种方法可以格式化输出时间,其中有Date的输出的只是日期,有Time的输出的只是当日中的具体时间,输出格式依据浏览器而定(FF输出PM为下午);

38.正则表达式有两种定义方法,可以直接定义不需要加引号在//外写上搜索模式,i,g,m三种可以组合;如果使用RegExp定义的话则要使用引号扩起来,并且将匹配模式单独做参数传入;

39.Test方法可以检测出字符串中是否有匹配成功的部分,如果有则返回true,否则false;exec方法在正则对象是global方式时可以遍历整个字符串,并且将匹配成功的部分存到外部,但是需要手动设置循环;

40.每一次执行test或者exec过后,RegExp对象的属性都会进行更新,可以获取到一系列的值

var text = “this has been a short summer”;
var pattern = /(.)hort/g;

if (pattern.test(text)){
    alert(RegExp.input);         //this has been a short summer
    alert(RegExp.leftContext);     //this has been a
    alert(RegExp.rightContext);     // summer
    alert(RegExp.lastMatch);     //short
    alert(RegExp.lastParen);     //s
    alert(RegExp.multiline);     //false
}

41.超级鬼畜的函数定义方法

var sum = new Function(“num1”, “num2”, “return num1 + num2”);

42.使用var定义的函数时,必须实现通过var声明或定义,但是用function定义的可以放在下面;

43.对于函数来说有几个属性非常实用,最主要的this可以获取到父对象,Argument.callee可以获取到函数自身进行递归,避免了改变函数名时带来的不必要的麻烦;还有caller可以获取到调用当前函数的父函数;

44.函数的length属性得到的值就是设置函数时需要传入的参数个数;

45.使用new新创建的数字,字符串等得到的typeof都是object,并且instanceof原型的值返回true;

46.Number的toString方法可以把传入参数作为基,输出数字在此基上的值(无前缀);

47.Number还有一个toFix方法,可以将数字输出为小数点后保留参数个的位数;

48.另外还有toExprotentialtoPrecision方法,分别是输出科学计数法的表达和有效位数的表达;

49.substr方法的第二个参数是截出的长度,substring方法的第二个参数是截止的位置;

50.CharAt方法可以得到一定位置的字符,而charCodeAt可以获得字符的Unicode十进制编码,反过来有一个函数是fromCharCode,可以将十进制的编码转换为字符串;

51.在JS中字符是当作单字节存储的,中文也不例外

Var str = “6六6”;
//Str.length = 3;
//Str.charat(1) = “六”;

52.与 toUpperCase()不同的是,toLocaleUpperCase()方法按照本地方式把字符串转换为大写。只有几种语言(如土耳其语)具有地方特有的大小写映射,所以最好还是用Local的方法;

53.字符串的match方法等同于正则表达式的exec方法;

54.同理的,字符串也有使用正则表达式进行筛选替换的方法

var text = “cat, bat, sat, fat”;
var result = text.replace(“at”, “ond”);
alert(result);
//”cond, bat, sat, fat”
result = text.replace(/at/g, “ond”);
alert(result); 
//”cond, bond, sond, fond”

替换的时候还有些特别厉害的$符号开头的替换属性,自行百度;

55.encodeURL会把字符串中的域名后面的部分中非标准字符转换成他对应的UTF-8码,而encodeURLComponent会把全部的非ASCII转变成UTF-8编嘛(.-_?~()’这些除外),当然可想而知有对应的解码方法decodeURL

56.Math的max方法可以选出传入参数中的最大值,然而我们要用数组时就会显得心有余而力不足,这个时候有一种特别厉害的方法值得记住,因为apply的第二个参数就是把参数当作数组传入,实现了巧妙的转换

var values = [1, 2, 3, 4, 5, 6, 7, 8];
var max = Math.max.apply(Math, values); //8

57.ceil,floor,round分别是对一个数向上取整,向下取整和四舍五入;

58.defineProperty可以对对象的某一个属性进行细致的设置,不过要注意他前面可是Object:

var person = {};
Object.defineProperty(person, “name”, {
configurable: false,    //还有writable,enumerable,set,get属性   一共就6个
value: “Nicholas”
});

59.如果是对一个已经定义好的对象属性添加set,get方法,那么就要用到defineSetter,和defineGetter来实现了:

Date.prototype.__defineGetter__('year',function() {
return this.getFullYear();
}); 

60.Object的create方法可以有效的复制对象,传入参数为原型对象;

61.在闭包中使用this指针并不会直接指向看起来存在的对象,而是会直接指向window,获得的变量将会是全局变量,如果要使用的话可以先存起来:

Var object = {
    Name: ”wanlei”,
    getName: function(){
        Var that = this;
        Return function(){
            Return that.name;
        };
    }
}

这样的话执行object.getName得到的值就是wanlei了;

62.同为全局变量,但是name不可以通过delete操作,而window.name可以使用delete删除掉;

63.chrome提供了关于console的一些API,可以指定格式输出字符串,还可以用CSS来修饰,做出动画等等;

64.不知道是不是我的问题,但是在setInterval中传入的函数只要加了括号他就会当时就运行一次(理论上来说应该是隔了指定时间过后运行的);

65.没有设置宽度时span标签里面的汉字有可能会自动换行,一定要记住设置CSS属性white-space:nowrap;

66.设施图片、脚本,CSS的onload事件一定要在设置src(href)之前,并且图片在设置src后即会开始下载;但是其他的则是添加进文档才开始下载;

67.在Firefox中,出现在条件语句中的代码块不做活动对象初始化的处理,但是在其他的浏览器中会检索全局进行初始化,而IE会把对象作为局部变量处理;

Function a(b){
If(b){Function c (){Alert(2333);}
};}

68.需要特别注意的是,由于浏览器端使用时是使用ajax来拉取.less文件,因此直接在本机文件系统打开(即地址是file://开头)或者是有跨域的情况下会拉取不到.less文件,导致样式无法生效;

69.giligili eye!!! giligili mind!!! 大家一起吸毒吧!!!

主要关于Canvas和Node的一些笔记

9.获取鼠标移动的位置,兼容各大主流浏览器(当然没有IE,他才不算主流,哼)

1 document.addEventListener("mousemove", function(e) {
2   var movementX = e.movementX   ||
3   e.mozMovementX||
4   e.webkitMovementX ||
5   0,
6   movementY = e.movementY   ||
7   e.mozMovementY||
8   e.webkitMovementY ||
9   0;
10 
11   // Print the mouse movement delta values
12   console.log("movementX=" + movementX, "movementY=" + movementY);
13 }, false);

IE和FF的定位有个1px的差别,实际上,IE的定位从0开始,FF的定位从1开始,FF永远会比IE大1px,需要根据实际情况处理。

10.currentColor属性可以用于CSS中替代当前选择其中文字的颜色,可以应用到一些小ICON的使用上面,对应的做法就是将显示部分做成一个蒙版,透过蒙版可以看到背景色,这时我们设置文字的hover改变颜色就可以很方便的改变icon的颜色了。

11.background:#f00 url(background.gif) no-repeat fixed 0 0/100px 100px;
“ / ”前面的0 0,就是background-position, 后面的100px 100px, 就是background-size的值,这种格式下,
background-position的值不能省略。

12.在canvas中使用socket即时通讯画图,使用越粗的线就会越卡,在线粗相同的情况下,实用的阴影越大也会更加卡,不过原因尚不清楚。

13.有的智障编辑器是不会提示拼写错误的,今天早上就把block写成了blcok调试了一个小时的bug没发现问题

14.在node里面进行路由操作的时候,一定不要把socket的connect事件加入到路由里面,不然会出现刷新一次多一个socket的情况。

15.在node里面使用res.writeHead会发生报错的情况,不能够在发送出消息后设置头部,但是使用setHead不会产生这种错误,如果想要获取到cookie的话使用req.headers.cookie可以获取到
“schoolid=1;schoolName=%E9%87%8D%E5%BA%86%E9%82%AE%E7%94%B5%E5%A4%A7%E5%AD%A6; _ga=GA1.1.1329053600.1463749095; a=000”
这种形式的字符串,可以手动解析,也可以使用parse-cookie的中间件。并且,在set-cookie的时候如果不配置max-age的话,将使用默认的session属性;当max-age为负数或者零时,cookie将不起任何作用。

16.(题外话)百度搜索的最近搜索全部存在localstorage里面的BDSUGSTORED数据,JSON格式哦。

17.cookie的domain,代表了其作用域,即有效范围。

一般是对应的http地址的最开始那部分的值。

比如对于访问http://login.live.com//xxxx 来说,cookie的domain是.live.com的话,那么就是和此网页相匹配,和此网页的Host=login.live.com相匹配,是有效的。

尤其需要注意的是,cookie的domain所代表的含义。

举例来说,如果一个cookie的domain是.live.com的话,那么对于去访问.users.storage.live.com

或.storage.live.com类型的地址的话,是无效的,因为.live.com,其作用域,只是xxx.live.com,而并不包括xxx.users.storage.live.com或xxx.storage.live.com类型的地址。

page新建页面

最近逛博客看到的有关性能优化的东西

包括两个部分,一部分是有关于CSS动画这一方面的,另一部分是关于js性能方面的

1.使用 transform3d api 代替 transform api,可以强制开启 GPU 加速,提升网站动画渲染性能;

2.使用 CSS3 will-change 提高页面滚动、动画等渲染性能;

3.chrome对于渲染很多大尺寸图片(尤其是alpha透明度PNG24图片)方面有先天的不足,从它版本10+的时候就有开发者在官方平台报过这个Bug,如今chrome已经更新至版本30+,却依旧没有完美解决这个顽疾。

通过-webkit-transform:transition3d/translateZ开启GPU硬件加速之后,有些时候可能会导致浏览器频繁闪烁或抖动,可以尝试以下办法解决之:
-webkit-backface-visibility:hidden;
-webkit-perspective:1000;

4.不要重构对象

重构对象是很昂贵的操作,遵循下面的建议来避免:

不使用 delete 操作符

删除一个属性,用 delete 会比通过 null 赋值慢很多,在火狐和 Chrome 中,
null 赋值会快 99%,因为它不会修改对象的结构,但是 delete 会。

不要添加属性

定义对象后,不要随后给对象添加属性,而是一开始就应该定义好对象的结构模式,
这样运行速度会快很多(火狐上快 100%,Chrome 上快 89%)。

5.声明 & 传递局部作用域变量

当调用一个函数时,浏览器会进行 作用域查找 ,这个时间花销跟浏览器要查找的作用域数有关。不要依赖全局/高层作用域变量,而是创建局部作用域变量,然后传递给函数。查找的作用域数越少,就运行更快。

6.对于耗时任务,使用 Web Workers

如果你有非常耗时的计算任务,如图像处理,最好使用 Web Workers 让浏览器在后台线程中运行这个任务,并且异步返回处理结果,而不是挂起线程。

7.jquery中各个事件执行顺序如下:

1.ajaxStart(全局事件)
2.beforeSend
3.ajaxSend(全局事件)
4.success
5.ajaxSuccess(全局事件)
6.error
7.ajaxError (全局事件)
8.complete
9.ajaxComplete(全局事件)
10.ajaxStop(全局事件)

8.firefox中的canvas对于颜色的渲染有一定的问题,阴影的边界颜色混合会变得很深。
有图有真相:
image
image

前面一张是在chrome里面看到的效果,后面一张是在firefox里看到的效果。

9.让渲染方法极大提升的3个小tips:

background-attachment: fixed改成 position: fixed,因为前面这玩意滚动实时计算重绘;
背景图片所在的元素替换为::before伪元素;
使用了CSS3 will-change 加速;