总结:从渲染机制谈script标签的位置是否会影响首屏时间

看了文章 【JS 一定要放在 Body 的最底部么?聊聊浏览器的渲染机制】,挺有感触,内容比较长,把总结部分摘要下:

浏览器的渲染过程:

  1. Create/Update DOM And request css/image/js:浏览器请求到HTML代码后,在生成DOM的最开始阶段(应该是 Bytes → characters 后),并行发起css、图片、js的请求,无论他们是否在HEAD里。注意:发起 js 文件的下载 request 并不需要 DOM 处理到那个 script 节点,比如:简单的正则匹配就能做到这一点,虽然实际上并不一定是通过正则:)。这是很多人在理解渲染机制的时候存在的误区。
  2. Create/Update Render CSSOM:CSS文件下载完成,开始构建CSSOM
  3. Create/Update Render Tree:所有CSS文件下载完成,CSSOM构建结束后,和 DOM 一起生成 Render Tree。
  4. Layout:有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。下一步操作称之为Layout,顾名思义就是计算出每个节点在屏幕中的位置。
  5. Painting:Layout后,浏览器已经知道了哪些节点要显示(which nodes are visible)、每个节点的CSS属性是什么(their computed styles)、每个节点在屏幕中的位置是哪里(geometry)。就进入了最后一步:Painting,按照算出来的规则,通过显卡,把内容画到屏幕上。

以上五个步骤前3个步骤之所有使用 “Create/Update” 是因为DOM、CSSOM、Render Tree都可能在第一次Painting后又被更新多次,比如JS修改了DOM或者CSS属性。

Layout 和 Painting 也会被重复执行,除了DOM、CSSOM更新的原因外,图片下载完成后也需要调用Layout 和 Painting来更新网页。

继续阅读 总结:从渲染机制谈script标签的位置是否会影响首屏时间

浮点计算 — 加减乘除

浮点计算一直有bug,项目用到了,在网上找了套能用的,记录下。。。

/**
 ** 乘法函数,用来得到精确的乘法结果
 ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
 ** 调用:accMul(arg1,arg2)
 ** 返回值:arg1乘以 arg2的精确结果
 **/
function accMul(arg1, arg2) {
    var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
    try {
        m += s1.split(".")[1].length;
    }
    catch (e) {
    }
    try {
        m += s2.split(".")[1].length;
    }
    catch (e) {
    }
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}

/**
 ** 除法函数,用来得到精确的除法结果
 ** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
 ** 调用:accDiv(arg1,arg2)
 ** 返回值:arg1除以arg2的精确结果
 **/
function accDiv(arg1, arg2) {
    var t1 = 0, t2 = 0, r1, r2;
    try {
        t1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
    }
    try {
        t2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
    }
    with (Math) {
        r1 = Number(arg1.toString().replace(".", ""));
        r2 = Number(arg2.toString().replace(".", ""));
        return (r1 / r2) * pow(10, t2 - t1);
    }
}

/**
 ** 减法函数,用来得到精确的减法结果
 ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
 ** 调用:accSub(arg1,arg2)
 ** 返回值:arg1加上arg2的精确结果
 **/
function accSub(arg1, arg2) {
    var r1, r2, m, n;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

/**
 ** 加法函数,用来得到精确的加法结果
 ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
 ** 调用:accAdd(arg1,arg2)
 ** 返回值:arg1加上arg2的精确结果
 **/
function accAdd(arg1, arg2) {
    var r1, r2, m, c;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    c = Math.abs(r1 - r2);
    m = Math.pow(10, Math.max(r1, r2));
    if (c > 0) {
        var cm = Math.pow(10, c);
        if (r1 > r2) {
            arg1 = Number(arg1.toString().replace(".", ""));
            arg2 = Number(arg2.toString().replace(".", "")) * cm;
        } else {
            arg1 = Number(arg1.toString().replace(".", "")) * cm;
            arg2 = Number(arg2.toString().replace(".", ""));
        }
    } else {
        arg1 = Number(arg1.toString().replace(".", ""));
        arg2 = Number(arg2.toString().replace(".", ""));
    }
    return (arg1 + arg2) / m;
}

整理:目前移动端部分问题汇总

伪类 :active 生效

要CSS伪类 :active 生效,只需要给 document 绑定 touchstarttouchend 事件

<style>
a {
  color: #000;
}
a:active {
  color: #fff;
}
</style>
<a herf=foo >bar</a>
<script>
  document.addEventListener('touchstart',function(){},false);
</script>

消除 transition 闪屏

两个方法

-webkit-transform-style: preserve-3d;
/*设置内嵌的元素在 3D 空间如何呈现:保留 3D*/
-webkit-backface-visibility: hidden;
/*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/

消除 IE10 里面的那个叉号

input:-ms-clear{display:none;}

来源出处:http://msdn.microsoft.com/en-us/library/windows/apps/hh767361.aspx

继续阅读 整理:目前移动端部分问题汇总

思考:为何jQuery去掉了浏览器检测

由于做HTML5相关的项目,许多前卫时髦的前端技术就需要考虑一下IE是否支持。要是在以前,可以很方便地调用jQuery的jQuery.browser来实现。

If(jQuery.browser.msie) alert(“DIE IE!”)
但这一便利在jQuery 1.9之后就不复存在了。突然觉得像失去了一个最亲密的战友,一个我一搞开发就离不开的好基友,一个我离开了就 无法写出跨浏览器的前端代码的好工具。一下子我竟不知道该如何是好。

然后每次需要考虑IE的时候,我就会去google一下,如何用1.9版本的jQuery来检测IE,但网上的多数回答都告诉我:jQuery1.9废掉勒jQuery.browser,建议用jQuery.support,但是没有人告诉我为什么?

也不知道那时我的是不是脑子被门夹了半天反应不过来为什么给废掉了,反正我的目的很简单,就是需要检测当前用户用的是不是IE,如果不是IE,那么我就需要弹出相关提示信息告诉用户你正在使用IE,某些功能可能不被支持云云。。。

无奈,以至于我的编码回到了那个没有jQuery的石器时代,用最原始的最plain的JavaScript代码来检测IE,而关于这样的方法,由于有无数前辈在与IE的博弈中积累了大量经验,现成的方法已经写过N多了,所以我也就随便拣一个用着。而且每次用的都还不一样,下次遇到要检测IE的时候,又去Google一把,得到另一段代码达到相同的效果。 继续阅读 思考:为何jQuery去掉了浏览器检测

Google JavaScript代码风格指南

原文:http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml

每个风格点都有一个展开/收起按钮以便你可以得到更多的信息:.
你可以将全部展开或收起:


全部展开/全部收起

背景

JavaScript是一门客户端脚本语言,Google经常用它来晒优越,本文档列出了一些在做JS项目时需要注意的地方。都是高富帅整理的,还望各位屌丝们有时间都好好看看多学学,别对这个世界太消极了!(译者注:所谓的客户端呢就是浏览器或本地软件环境,市面上所有的浏览器都支持JS,JS发展到现在统一WEB端再进军移动互联网后,相信在一段时间内都是不可被轻易替代的语言,所以有兴趣的同学们可以多关注一下)

JavaScript语言规范

变量(var)

每个变量声明都要加上var关键字噢。

常量

常量命名用类似NAMES_LIKE_THIS这样的形式。没事干了可以用@const来标记它是常量,但永远不要用const关键字来进行常量声明。

分号


每一语句的结尾都要加上分号噢。

继续阅读 Google JavaScript代码风格指南

Chrome取消-webkit-text-size-adjust支持

最近更新了chrome27正式版后,发现原来用到 -webkit-text-size-adjust  的地方已经失效了,搜索了一下发现这个属性不被支持了,囧….那么还有什么办法能在chrome下设置12px以下的字体呢?

第一步:设置css部分为12px
第二步:使用scale滤镜进行缩放
第三步:使用letter-spacing调整字符间距

不过我觉得这也是一件好事,因为 -webkit-text-size-adjust 属性经常被滥用,全局设置 -webkit-text-size-adjust:none; 的人太多了,导致了放大网页的时候字号不能改变,可用性大大降低,对于有视觉障碍的用户更是缺少情怀:)

chrome点击链接变成下载

在使用电信宽带的时候,用 chrome 浏览器有时会碰到这种情况:

1.点击任何链接,不会正常跳转,而是变成了下载文件;

2.书签栏里的任何书签点击都没反应;

3.F5没反应,想刷新页面只能去点击刷新按钮,刷新后还是老样子;

4.在地址栏里敲东西,感觉 ctrl 键默认被按住了一样,光敲字母都会触发好多快捷键操作;

….

这些情况我在公司的时候平均一天会碰到1,2次,在家的时候会稍微好些,碰到的比较少,我当时还以为是电脑加入公司域的问题(因为之前 IE 出过更离谱的事,每次打开会假死一会),我就默默的忍了,但最近貌似很严重,我浏览网页前端调试都是用的 chrome,特别是在调试数据的时候,MD,我只能把浏览器关了从新打开,心里一股怨气啊~~~现在知道了,是电信的广告恶意劫持,而且广告代码还有严重的兼容性问题,IE下正常,chrome 等用 GZIP 压缩传输下的就会变成这球样,影响用户正常使用,宽带费用这么高,服务那么差,我很想在最后说一句:“电信,我去年买了块表!”

解决方法:点击链接出现下载的时候,选择否,然后按下 alt 键。

xmlHttpRequest对象的一些总结

总结,五个步骤:

1.创建XMLHttpRequest对象。

2.设置连接信息 xmlhttp.open(请求方式,url,是否同步);

3.注册回调函数 xmlhttp.onreadystatechange = 函数名 (函数名后面不要加括号); 

4.发送数据。xmphttp.send(data);

5.接收响应数据

readyState 属性存有服务器响应的状态信息。每当 readyState 改变时,onreadystatechange 函数就会被执行。

状态描述
0 请求未初始化(在调用 open() 之前)
1 请求已提出(调用 send() 之前)
2 请求已发送(这里通常可以从响应得到内容头部)
3 请求处理中(响应中通常有部分数据可用,但是服务器还没有完成响应)
4 请求已完成(可以访问服务器响应并使用它)

继续阅读 xmlHttpRequest对象的一些总结

利用 Linode 的 SSH 翻墙

前几天买了个 linode 的 vps,一个月 20 刀,配置是:1 GB RAM、8 CPU (1x priority)、24 GB Storage、2 TB Transfer,速度非常不错,选的东京的机房,ping 一下都是 100ms以内,正好国内的空间快到期了,就搬家到 linode 了,很爽,关键是还能用 linode 的 ssh 翻墙:),下面说下具体方法(windows系统):

1.购买后选择 32 位 CentOS,然后在安装 LNMP(Linux 下 Nginx、MySQL、PHP 这种网站服务器架构),具体教程看这里

2.下载 Bitvise Tunnelier介绍),按照下面几个步骤设置好:

第一步

继续阅读 利用 Linode 的 SSH 翻墙

HTML5音乐播放器(五):同步显示歌词

好久没更新博客了,真是罪过,老偷懒,鄙视下自己,这两天把歌词同步显示的功能弄完了,先来说说原理:

1.ajax获取歌词文件(lrc文件)。

2.用正则分别去过滤出歌词和歌词前面对应的时间,存入数组。

[ti:很难]
[ar:张震岳]
[al:OK]
[by:]
[00:15.79]又一天的一个晴天
[00:19.07]阳光印在这张旧沙发
[00:22.96]躺下来 闭上眼
[00:25.11]恍然不知寂寞 枕着蔓延
.....
//获取歌词内容
lrcVal = xmlhttp.responseText.replace(/[dd:dd.dd]/g,"");
lrcArray = lrcVal.split("n");

//歌曲名
lrcArray[0].replace(/[ww:(.*?)]/g,function(){
    musicName = arguments[1] || "暂无";
});

//歌手
lrcArray[1].replace(/[ww:(.*?)]/g,function(){
    singer = arguments[1] || "暂无";
});

//获取歌词时间轴
xmlhttp.responseText.replace(/[(d*):(d*)([.|:]d*)]/g,function(){
    var min = arguments[1] | 0, //分
    sec = arguments[2] | 0, //秒
    realMin = min * 60 + sec; //计算总秒数

    lrcTimeArray.push(realMin);
});

继续阅读 HTML5音乐播放器(五):同步显示歌词