NaN:保留字(表明数据类型不是数字)
undefined:对象属性或方法不存在,或声明了变量但从未赋值。
即当你使用了对象未定的属性或者未定义的方法时或当你声明一个变量,但你确从未对其进行赋值,便对其进行操作(当然赋值除外),会有”undefined”提示。
null :指出一个变量中没有包含有效的数据。
产生 null 的原因是:对一个变量显式地赋值为 null。 包含 null 的表达式之间的任何操作。

Boolean 表达式
一个值为 true 或者 false 的表达式。
如果需要,非 Boolean 表达式也可以被转换为 Boolean 值,但是要遵循下列规则:所有的对象都被当作 true。 当且仅当字符串为空时,该字符串被当作 false。
null 和 undefined 被当作 false。
当且仅当数字为零时,该数字被当作 false。

字符串比较
两个字符序列之间的比较。
除非在进行比较操作的函数中指出,所有的字符串比较操作都是二进制的。
在英语中,二进制比较区分大小写;而文本比较则不区分。

数值表达式
数值表达式指的是任何值为数字的表达式。这种表达式的元素可以包括关键字、变量、文字和运算符的任意组合,只要此组合能够生成一个数字。在特定的情况下,如果可以的话,字符串也可以被转换为数字。

构造函数
一种 JScript 函数,具有两个特殊的性质:由 new 运算符来调用此函数。 通过 this 关键字将新创建对象的地址传递到此函数。 强列建议使用构造函数来初始化新的对象。

ASCII 字符集
美国标准信息交换编码 (ASCII) 的 7 位字符集,它被广泛地用来表示标准的美国键盘上的字母和符号。
ASCII 字符集与 ANSI 字符集中的头 128 个字符 (0–127) 完全相同。Automation 对象通过Automation 接口可以被其他应用程序或编程工具使用的对象。

全球标准时间 (UTC)
全球标准时间指的是由世界时间标准设定的时间。原先也被称为格林威治标准时间或者 GMT。

Jscript 有三种主要数据类型、两种复合数据类型和两种特殊数据类型。
主要(基本)数据类型是:字符串 数值 布尔
复合(引用)数据类型是:对象 数组
特殊数据类型是:Null Undefined
null = = undefined
true

“NaN” = = NaN
false

5 = = NaN
false

NaN = = NaN
false

NaN != NaN
true

false = =0
true

true = =1
true

true = = 2
false

undefined = = 0
false

null = = 0
false

“5″ = = 5
true

1.类型分析:
js中的数据类型有undefined,boolean,number,string,object等5种,前4种为原始类型,第5种为引用类型。
var a1;
var a2 = true;
var a3 = 1;
var a4 = “Hello”;
var a5 = new Object();
var a6 = null;
var a7 = NaN;
var a8 = undefined;
alert(typeof a); //显示”undefined”
alert(typeof a1); //显示”undefined”
alert(typeof a2); //显示”boolean”
alert(typeof a3); //显示”number”
alert(typeof a4); //显示”string”
alert(typeof a5); //显示”object”
alert(typeof a6); //显示”object”
alert(typeof a7); //显示”number”
alert(typeof a8); //显示”undefined”
从上面的代码中可以看出未定义的值和定义未赋值的为undefined,null是一种特殊的object,NaN是一种特殊的number。

2.比较运算
var a1; //a1的值为undefined
var a2 = null;
var a3 = NaN;
alert(a1 == a2); //显示”true”
alert(a1 != a2); //显示”false”
alert(a1 == a3); //显示”false”
alert(a1 != a3); //显示”true”
alert(a2 == a3); //显示”false”
alert(a2 != a3); //显示”true”
alert(a3 == a3); //显示”false”
alert(a3 != a3); //显示”true”
从上面的代码可以得出结论:(1)undefined与null是相等;(2)NaN与任何值都不相等,与自己也不相等。

Null 数据类型
在 Jscript 中数据类型 null 只有一个值:null。关键字 null 不能用作函数或变量的名称。
包含 null 的变量包含“无值”或“无对象”。换句话说,该变量没有保存有效的数、字符串、boolean、数组或对象。可以通过给一个变量赋 null 值来清除变量的内容。
请注意,在 Jscript 中,null 与 0 不相等(与在 C 和 C++ 中不同)。同时应该指出的是,Jscript中 typeof 运算符将报告 null 值为 Object 类型,而非类型 null。这点潜在的混淆是为了向下兼容。

Undefined 数据类型
如下情况是返回 undefined 值:
对象属性不存在,
声明了变量但从未赋值。
注意不能通过与 undefined 做比较来测试一个变量是否存在,虽然可以检查它的类型是否为“undefined”。在以下的代码范例中,假设程序员想测试是否已经声明变量 x :

// 这种方法不起作用
if (x == undefined)
// 作某些操作

// 这个方法同样不起作用- 必须检查
// 字符串 “undefined”
if (typeof(x) == undefined)
// 作某些操作

// 这个方法有效
if (typeof(x) == “undefined”)
// 作某些操作

考虑将 undefined 值与null做比较。
针对上面的判断,如果变量 x 没有定义的话 if (x == undefined) {…}会抛出exception:变量x未定义,这句判断不会执行,可用try{…}catch(ex){…} 捕获。
不管x是否已经定义,使用 if (typeof(x) == undefined) 都会判断为 false。
someObject.prop == null;

如下情况时,比较的结果为 true,
如果属性 someObject.prop 包含 null 值,
如果属性 someObject.prop 不存在。

要检查一个对象属性是否存在,可以使用新的 in 运算符:
if (“prop” in someObject)
// someObject 有属性 ‘prop’

在JavaScript中,null与undefined一度使人迷惑。下面的分析,有利于你更清晰的认知它(或者让你更迷惑):
- null是关键字;undefined是Global对象的一个属性
- null是对象(空对象, 没有任何属性和方法);undefined是undefined类型的值。

试试下面的代码:
document.writeln(typeof null); //return object
document.writeln(typeof undefined); //return undefined

- 对象模型中,所有的对象都是Object或其子类的实例,但null对象例外:
document.writeln(null instanceof Object); //return false

- null“等值(==)”于undefined,但不“全等值(===)”于undefined:
document.writeln(null == undefined); //return true
document.writeln(null === undefined); //return false

- 运算时null与undefined都可以被类型转换为false,但不等值于false:
document.writeln(!null, !undefined); //return true,true
document.writeln(null==false); //return false
document.writeln(undefined==false); //return false

 

字面上理解下来就是,回调就是一个函数的调用过程。那么就从理解这个调用过程开始吧。函数a有一个参数,这个参数是个函数b,当函数a执行完以后执行函数b。那么这个过程就叫回调。

其实中文也很好理解:回调,回调,就是回头调用的意思。函数a的事先干完,回头再调用函数b。

这里必须清楚一点:函数b是你以参数形式传给函数a的,那么函数b就叫回调函数。

也许有人有疑问了:一定要以参数形式传过去吗,我不可以直接在函数a里面调用函数b吗?确实可以。求解中。

<解惑:如果你直接在函数a里调用的话,那么这个回调函数就被限制死了。但是使用函数做参数就有下面的好处:当你a(b)的时候函数b就成了回调函数,而你还可以a(c)这个时候,函数c就成了回调函数。如果你写成了function a(){…;b();}就失去了变量的灵活性。>

下面用代码来证实我的理解。

  • <html>
  • <head>
  • <title>回调函数(callback)</title>
  • <script language=”javascript” type=”text/javascript”>
  • function a(callback)
  • {
  •     alert(“我是parent函数a!”);
  •     alert(“调用回调函数”);
  •     callback();
  • }
  • function b(){
  • alert(“我是回调函数b”);
  • }
  • function c(){
  • alert(“我是回调函数c”);
  • }
  • function test()
  • {
  •     a(b);
  •    a(c);
  • }
  • </script>
  • </head>
  • <body>
  • <h1>学习js回调函数</h1>
  • <button onClick=test()>click me</button>
  • <p>应该能看到调用了两个回调函数</p>
  • </body>
  • </html>

转自:http://www.cnblogs.com/yhql/archive/2011/08/08/2131420.html

以上的例子简单易懂,但是对比下面的,我就有点糊涂了,可能是我这水平还看不懂吧,是不是那个option啊

今天想用js调取一个接口,可总不知道如何获取返回值,只能怪自己思维打盹了,其实返回值中是个函数回调,在调用页定义这个函数就可以了,例子如下:

<script     src=”http://blogpagin.sinajs.cn/article?1315019920&0&requestId=scriptId_0.37” ></script>

趁热打铁,看了下公司牛人写的js代码,温习下他们是如何这类问题的

<SCRIPT LANGUAGE=”JavaScript”>

window.$ScriptLoader = {

requestTable : {},

request : function (url, option){
option = option || {};
option.charset = option.charset || “utf-8″;

var id = “scriptId_” + Math.random();
url = url + “&id=” + id ;

this.requestTable[id] = {
id : id,
url : url,
option : option
};
var sTag = document.createElement(“script”);
sTag.id = id;
sTag.src = url;
sTag.charset = option.charset;

document.body.appendChild(sTag);
},
response : function (id, txt){

var entity = this.requestTable[id];
if (entity){
try {
entity.option.onComplete(txt );
} catch (err) {
var oe = entity.option.onException;
try {
if(oe)
oe(txt,    err);
else {
alert(“error occurs while calling onComplete to url : ” + this.requestTable[id].url + ” Error : ” + err);
}
} catch (err) {}
} finally {

}
}
}
}

</SCRIPT>

<body>

<SCRIPT LANGUAGE=”JavaScript”>
function fun( str)
{
alert(str);
}

function errfun()
{
alert(“error”);
}

var url = “http://www.test.com/cms/test.php?quest=” ;
var option = {onComplete:fun,onException:errfun};
window.$ScriptLoader.request(url,option);

</SCRIPT>

</body>

 

原理就是动态加载一个js文件,注意js文件的编码,然后预设一个回调函数,回调函数的触发点就是onComplete时间,这也是ajax的原型

看看test.php服务器端的代码:

<?php
echo “window.\$ScriptLoader.response(‘” . $_GET[id] . “‘,’ttt’);”;
?>

 

转自:http://hi.baidu.com/ywdblog/item/d95878eb6ec891e3fa42bae4

 

Google I/O 2012开发者大会将于北京时间28日凌晨0:30旧金山召开,这一次大会的内容丰富。

首先是提到现在世界上Android 设备的一些数据。如今全球的Android设备已经达到了4亿台!2011年Android日均激活量为40万台,而今天,这一数字达到了每日100万台,也就是平均每秒 12 台。

以下是各地区的激活量

Android 4.1 

三倍缓存和触控灵敏调整,还能提升续航能力,这就是 Project Butter !

“黄油”计划实际上是使用了 GPU 的计算能力,采用新的 UI 框架,将 Android 界面#Google I/O 2012#的渲染帧速提升到 60。除此之外,还采取了多重缓冲的方式来提高渲染速度。总得来说,整个项目的目的就是,让 UI 界面如同“黄油”版顺滑。

Android 4.1 渲染速度能够达到惊人的 120 fps ! 比 Android 4.0 快很多。根据现场的视频来看,UI的场景过渡确实顺滑不少,目前4.0系统卡顿的问题已经得到很好的解决

新的主界面和 iOS 一样,能够自动排列了,当你移动一个图标时,其他图标会自动让出一个空位。

发布全新的语音输入法,ADNROID 4.1的语音识别与Siri可以离线使用!也加入了对更多其他语种的支持,但暂时不支持中文。新的 Google 搜索,全新的 Google 语音搜索,可以直接返回只是搜索卡片,搜索地方时,不仅能得到相关网页结果,还能得到前往附近星巴克的路线图。第三方音乐应用也可以在通知栏内加入控件。Google Now 提供了大量真实世界的实时信息,基于 Google 的搜索能力,从不同站点拉取大量数据,然后配合位置服务进行提醒。如果数据准确,这个功能将会非常有效。7 月中旬,Jelly Bean 将会公开源码,七月中旬开始,Galaxy Nexus和摩托罗拉Xoom就会开始收到升级

内置相机应用有了不少改进,可以同时预览多张图片,并用拖拉的方式删除其中某些图片,有点卡片的感觉。

android beam 两大改进,允许传照片视频,可以通过nfc 快速配对蓝牙。可以快速切换到之前拍摄的照片。

新的通知系统能够显示更多信息。NFC 方面,Android Beam 可以通过轻触蓝牙喇叭的方式实现配对,简化生活的某种方式。当然,到现在还没有遇到过可以使用 Android Beam 的场合。还能直接显示完整图片!通知中心增加了更多交互元素,可以直接针对某些通知类型进行处理,从目前的演示看,应该可以由开发者自行定制通知上执行的动作,非常方便。

Google发布平台开发工具PDK。这个可以提供低层次的API,对于游戏开发来说非常有价值。PDK是一套硬件开发工具,用于帮助商业公司开发更好的 Android 硬件。类似于 SDK ,PDK 是一套硬件开发工具,用于帮助商业公司开发更好的 Android 硬件。PDK 将在未来的 2 到 3 个月中发布。

Google Play 的一些数据,你可以想象的,60 万应用,200 亿应用安装数量,在 132 个国家销售。200 亿次下载量!在132个国家提供付费应用下载服务与良好的运营商合作伙伴渠道。面向开发者的 Google Cloud Messaging ,没有流量限制。Google Play 也能够提供其他娱乐内容,比如电影。现已有 400 万视频可供观看。

Nexus 7 平板发布

谷歌首款自主平板电脑。1280×800 HD, Tegra 3 四核处理器, 12 核 GPU 与早先传闻完全一致。只有 340 克,9 小时视频,300 小时“待机”。可以直接把内容放在桌面上。七月中旬开始出货,199 美元+25 刀的 Google Play 点卷!

具体参数,正如之前预期。Google Play 购买电视剧以及杂志了。更加智能的voice search。Nexus 7 现在会更智能地推荐可能感兴趣的内容给用户,也可收藏特定的电视节目。一流的杂志阅读体验。新的音乐搜索应用可以直接通过麦克风倾听音乐,Chrome 浏览器成为内置应用!

内置应用,Youtube 针对 Tablet 进行了优化,Google Map 增加了室内实景,离线下载地图也终于正式集成,完全支持导航功能。支持离线地图。内置 Google 翻译。

现场演示了两个游戏,感觉流畅度一般。不过是大型的 FPS游戏而不是微软的滚球什么的 。

Nexus Q 

定位是媒体串流设备——社交流媒体播放器

Nexus Q 出现,可以直接播放 Google Play 上提供的影音内容。使用 OMAP 4460 芯片和 Galaxy Nexus 一样,功耗 25 瓦。 也能从 Android 手机内部直接分享影片播放。此外拥有光纤接口以及 micro HDMI 输出接口。

直接从 Nexus 7 平板上选择音乐就可以在这个设备上播放。如果你有多台 Nexus Q ,他们就能够同步工作用手机就可以控制,如果你朋友家里有一台 Nexus Q ,你就能直接用它播放你在 Google Play 里的影片。

Nexus Q 售价299 美元,七月中旬发货!

 Google+

帮助人们更好的联系在一起。已经有 2.5 亿用户升级到了 Google+,其中 50% 每天登陆。平均每人每天花费一小时。发布 Tablet 版本的 Google+ 客户端。更多用户喜欢使用 Google+ 移动应用。其实国内的移动端是可以上Google+ 的。

Google+ 平板专用版界面!可以查看相册和评论,增加Hangout 视频通话功能。iPad 版本也会同步更新。

Google 发布新的名为 Google+ Events的直播工具,可以在活动过程中或者之后使用。和 Google 日历深度整合。可以直接通过 Google+ 邀请来宾

Google+ events 发布,看起来是个针对聚会的应用,与 Google 日历紧密集成。从演示来看,可以选取邀请时的背景,图片都很精致。可以直接通过 Google+ 邀请来宾。新图片会被自动分享出来。来宾回家后,聚会模式会自动把所有人拍摄的照片放到同一个地方,供大家访问。

Google Glass 

这个科幻一般的计划从两年前就开始进行了,图为原型机。现在的完成品Google Glass 包括了一块触摸板,一个显示装置和一颗摄像头。Google Glass 当前版本可以拍照以及摄像,拥有一些传感器,包括指南针以及陀螺仪。显示器离眼睛很近,但却不会阻挡视线。这种眼镜能够在镜片上显示投影,实现短信、电话、拍照、上网等功能。

美女设计师 Isabel 设计了这种不会干扰人们正常视觉的显示器。最新的原型机也很轻,比大部分太阳眼镜都轻,你根本感觉不到它们戴在脸上。

眼镜娘和眼镜哥的福音,你可以选择带上有度的镜片装备这个。这个才是真正随身携带随时可用,瞬间捕捉生活细节的拍照设想利器,而且还能现场直播!!

人们当遇到突发需要拍照的情况拿出手机进入拍摄界面通常已经错过拍照的最佳时机,而Google Glass恰恰解决了这个问题,你随时随地想拍就拍,拍摄的照片也非常便于分享。更重要的,图片都完全是第一人称视角的,就像你见到的一样。虽然目前功能上只是拍照和分享,不过未来绝对科幻。

Google 也表示欢迎开发者加入他们的行列,共同发掘 Google Glass 的其他可能性。布林认为 Google Glass 将给我们的日常生活带来变革。可穿戴式计算时代终于到来。不过仅限与会人员预订,参加 I/O 大会的开发者已经可以开始预订Google Glass。售价1500美金。提钱伤感情了。。明年年初才能出货,Google GlassI/O大会现场只是预订而不卖。

最后的最后,激动人心的时刻到了,所有现场的与会者都获得了一台免费的 Galaxy Nexus 和一台 Nexus 7 平板! 以及Nexus Q 一台!谷歌真良心!900美金票价值了。

总结以下:谷歌这次发布了Android 4.1系统、 Nexus 7 平板、 Nexus Q媒体播放器Google+以及科幻般的Google Glass也初露尊容。

 

 

 

 

一般来说,直接设input的border为none,在IE6下是没作用的,border还是在的。

这是,我们要设一下background才行,无论设什么都好,只要设成你想要的效果,即使是none也要设,这样border:none才会有效

 

今天工作的时候遇到要解析表情,先把最后解决的结果贴上来

/*
*解析内容,将内容中的表情进行替换
*@param: Contens 要处理的字符串
*@param: arrFaceList 表情数据
*@param: webRoot 处理完显示的图片目录级别
*/
function replaceFace(Contens, arrFaceList, webRoot) {

    $.each(arrFaceList.JDataList, function (i, faces) {
        var faceName = eval("/\\[" + faces.ExpressionName + "]/ig");
        var replaceHtml = "<img title='" + faces.ExpressionName + "' style='cursor:pointer' src='" + webRoot + faces.ExpressionUrl + "'>"
        Contens = Contens.replace(faceName, replaceHtml);
    });
    return Contens;
}

我遇到的问题:
1、js里的replace方法跟c#里的不一样,Js里的只替换第一个匹配项,而C#里匹配所有的匹配项。
解决办法:用正则表达式匹配。正则中有个配置参数g是global全局匹配。ig是ignore case忽略大小写的全局匹配
2、接下来的问题是中括号是正则里的特殊符号,怎么办?
解决办法:将前中括号[加转义字符\,注意,后中括号]不用加。见下面资料
3、可是正则表达式中有变量该怎么办呢?
解决办法:用eval()方法来连接字符串。
4、为什么还是不行?
解决办法:转义字符要写两次,因为在字符串”/\\[“里的单斜杠本身也需要转义。


资料:正则表达式中的特殊字符(需要转义)

  • ^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。
  • $ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 \$。
  • . 匹配除换行符 \n 之外的任何单字符。要匹配 .,请使用 \。
  • \ 将下一个字符标记为或特殊字符、或原义字符、或后向引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\\’ 匹配 “\”,而 ‘\(‘ 则匹配 “(“。
  • | 指明两项之间的一个选择。要匹配 |,请使用 \|。
  • { 标记限定符表达式的开始。要匹配 {,请使用 \{。
  • [ 标记一个中括号表达式的开始。要匹配 [,请使用 \[。
  • ( 和 ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
  • * 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
  • + 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
  • ? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
 

页面的回流不仅会造成浏览器的重新渲染,同时会影响到其中的dom元素,造成文件(图片、flash)的重新加载。之前在FF下遇到一个bug:执行关灯操作时(即将页面用一个黑色的div覆盖,但不遮挡flash播放器部分),正在播放的视频会立即中止,百思不得其解。后来经过跟踪测试发现,改变遮罩div的display属性后,导致flash部分dom的回流,页面重新加载了flash播放器。

下面是转载的页面回流和重绘,很全面。

页面呈现流程 

     在讨论页面重绘、回流之前。需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的 处理流程。可能不同的浏览器略微会有些不同。但基本上都是类似的。

 

     1.  浏览器把获取到的html代码解析成1个Dom树,html中的每个tag都是Dom树中的1个节点,根节点就是我们常用的document对象 (<html> tag)。dom树就是我们用firebug或者IE Developer Toolbar等工具看到的html结构,里面包含了所有的html tag,包括display:none隐藏,还有用JS动态添加的元素等。
     2. 浏览器把所有样式(主要包括css和浏览器的样式设置)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式,比如IE会去掉-moz开头的样 式,而firefox会去掉_开头的样式。
     3、dom tree和样式结构体结合后构建呈现树(render tree),render tree有点类似于dom tree,但其实区别有很大,render tree能识别样式,render tree中每个node都有自己的style,而且render tree不包含隐藏的节点(比如display:none的节点,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到 render tree中。注意 visibility:hidden隐藏的元素还是会包含到render tree中的,因为visibility:hidden 会影响布局(layout),会占有空间。根据css2的标准,render tree中的每个节点都称为box(Box dimensions),box所有属 性:width,height,margin,padding,left,top,border等。
    4. 一旦render tree构建完毕后,浏览器就可以根据render tree来绘制页面了。
回流与重绘
    1. 当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(其实我觉得叫重新布局更简单明了些)。每个页面至少需 要一次回流,就是在页面第一次加载的时候。
    2. 当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

注:从上面可以看出,回流必将引起重绘,而重绘不一定会引起回流。

什么操作会引起重绘、回流
    其实任何对render tree中元素的操作都会引起回流或者重绘,比如:
    1. 添加、删除元素(回流+重绘)
    2. 隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)
    3. 移动元素,比如改变top,left(jquery的animate方法就是,改变top,left不一定会影响回流),或者移动元素到另外1个父元素 中。(重绘+回流)
    4. 对style的操作(对不同的属性操作,影响不一样)
    5. 还有一种是用户的操作,比如改变浏览器大小,改变浏览器的字体大小等(回流+重绘)

让我们看看下面的代码是如何影响回流和重绘的:

var s = document.body.style;s.padding= “2px“; // 回流+重绘
s.border = “1px solid red“; // 再一次 回流+重绘
s.color = “blue“; // 再一次重绘
s.backgroundColor = “#ccc“; // 再一次 重绘
s.fontSize = “14px“; // 再一次 回流+重绘
// 添加node,再一次 回流+重绘
document.body.appendChild(document.createTextNode(‘abc!‘));

请注意我上面用了多少个再一次。

   说到这里大家都知道回流比重绘的代价要更高,回流的花销跟render tree有多少节点需要重新构建有关系,假设你直接操作body,比如在body最前面插入1个元素,会导致整个render tree回流,这样代价当然会比较高,但如果是指body后面插入1个元素,则不会影响前面元素的回流。

 

聪明的浏览器从上个实例代码中可以看到几行简单的JS代码就引起了6次左右的回流、重绘。而且我们也知道回流的花销也不小,如果每句JS操作都去回流重绘的话,浏览器 可能就会受不了。所以很多浏览器都会优化这些操作,浏览器会维护1个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者 到了一定的时间间隔,浏览器就会把flush队列,进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。虽然有了浏览器的优化,但有时候我们写的一些代码可能会强制浏览器提前flush队列,这样浏览器的优化可能就起不到作用了。当你请求向浏览器请求一些 style信息的时候,就会让浏览器flush队列,比如:
1. offsetTop, offsetLeft, offsetWidth, offsetHeight
2. scrollTop/Left/Width/Height
3. clientTop/Left/Width/Height
4. width,height
5. 请求了getComputedStyle(), 或者 ie的 currentStyle当你请求上面的一些属性的时候,浏览器为了给你最精确的值,需要flush队列,因为队列中可能会有影响到这些值的操作。

如何减少回流、重绘

减少回流、重绘其实就是需要减少对render tree的操作,并减少对一些style信息的请求,尽量利用好浏览器的优化策略。具体方法有:

1. 不要1个1个改变元素的样式属性,最好直接改变className,但className是预先定义好的样式,不是动态的,如果你要动态改变一些样式,则 使用cssText来改变,见下面代码:

// 不好的写法
var left = 1;
var top = 1;
el.style.left = left + “px“;
el.style.top  = top  + “px“;// 比较好的写法
el.className += “ className1“;// 比较好的写法
el.style.cssText += “; left: “ + left + “px; top: “ + top + “px;“;

2. 让要操作的元素进行”离线处理”,处理完后一起更新,这里所谓的”离线处理”即让元素不存在于render tree中,比如:
a) 使用documentFragment或div等元素进行缓存 操作,这个主要用于添加元素的时候,大家应该都用过,就是先把所有要添加到元素添加到1个div(这个div也是新加的),
最后才把这个div append到body中。
b) 先display:none 隐藏元素,然后对该元素进行所有的操作,最后再显示该元素。因对display:none的元素进行操作不会引起回流、重绘。所以只要操作只会有2次回 流。

3 不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,就先读取到变量中进行缓存,以后用的时候直接读取变量就可以了,见下面代码:

// 别这样写,大哥
for(循环) {
el.style.left = el.offsetLeft + 5 + “px“;
el.style.top  = el.offsetTop  + 5 + “px“;
}// 这样写好点
var left = el.offsetLeft,top  = el.offsetTop,s = el.style;
for(循环) {
left += 10;
top  += 10;
s.left = left + “px“;
s.top  = top  + “px“;
}

4. 考虑你的操作会影响到render tree中的多少节点以及影响的方式,影响越多,花费肯定就越多。比如现在很多人使用jquery的animate方法移动元素来展示一些动画效果,想想 下面2种移动的方法:

// block1是position:absolute 定位的元素,它移动会影响到它父元素下的所有子元素。
// 因为在它移动过程中,所有子元素需要判断block1的z-index是否在自己的上面,
// 如果是在自己的上面,则需要重绘,这里不会引起回流
$(“#block1″).animate({left:50});
// block2是相对定位的元素,这个影响的元素与block1一样,但是因为block2非绝对定位
// 而且改变的是marginLeft属性,所以这里每次改变不但会影响重绘,
// 还会引起父元素及其下元素的回流
$(“#block2″).animate({marginLeft:50});

实例测试

最后用2个工具对上面的理论进行一些测试,这2个工具是在我 “web 性能测试工具推荐” 文章中推荐过的工具,分别是:dynaTrace(测试ie),Speed Tracer(测试Chrome)。

第一个测试代码不改变元素的规则,大小,位置。只改变颜色,所以不存在回流,仅测试重绘,代码如下:

<body>
<script type=”text/javascript”>
var s = document.body.style;
var computed;
if (document.body.currentStyle) {
computed = document.body.currentStyle;
} else {
computed = document.defaultView.getComputedStyle(document.body, ”);
}
function testOneByOne(){
s.color = ’red’;;
tmp = computed.backgroundColor;
s.color = ’white’;
tmp = computed.backgroundImage;
s.color = ’green’;
tmp = computed.backgroundAttachment;
}function testAll() {
s.color = ’yellow’;
s.color = ’pink’;
s.color = ’blue’;tmp= computed.backgroundColor;
tmp = computed.backgroundImage;
tmp = computed.backgroundAttachment;
}
</script>
color test <br />
<button onclick=”testOneByOne()”>Test One by One</button>
<button onclick=”testAll()”>Test All</button>
</body>

testOneByOne 函数改变3次color,其中每次改变后调用getComputedStyle,读取属性值(按我们上面的讨论,这里会引起队列的 flush),testAll 同样是改变3次color,但是每次改变后并不马上调用getComputedStyle。

我们先点击Test One by One按钮,然后点击 Test All,用dynaTrace监控如下:

    

上图可以看到我们执行了2次button的click事件,每次click后都跟一次rendering(页面重绘),2次click函数执行的时间都差 不多,0.25ms,0.26ms,但其后的rendering时间就相差一倍多。(这里也可以看出,其实很多时候前端的性能瓶颈并不在于JS的执行,而 是在于页面的呈现,这种情况在用JS做到富客户端中更为突出)。我们再看图的下面部分,这是第一次rendering的详细信息,可以看到里面有2行是 Scheduleing layout task,这个就是我们前面讨论过的浏览器优化过的队列,可以看出我们引发2次的flush。

    

再看第二次rendering的详细信息,可以看出并没有Scheduleing layout task,所以这次rendering的时间也比较短。

测试代码2:这个测试跟第一次测试的代码很类似,但加上了对layout的改变,为的是测试回流。

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
</head>
<body>
<script type=”text/javascript”>
var s = document.body.style;
var computed;
if (document.body.currentStyle) {
computed = document.body.currentStyle;
} else {
computed = document.defaultView.getComputedStyle(document.body, ”);
}
function testOneByOne(){
s.color = ’red’;
s.padding = ’1px’;
tmp = computed.backgroundColor;
s.color = ’white’;
s.padding = ’2px’;
tmp = computed.backgroundImage;
s.color = ’green’;
s.padding = ’3px’;
tmp = computed.backgroundAttachment;
}function testAll() {
s.color = ’yellow’;
s.padding = ’4px’;
s.color = ’pink’;
s.padding = ’5px’;
s.color = ’blue’;
s.padding = ’6px’;tmp= computed.backgroundColor;
tmp = computed.backgroundImage;
tmp = computed.backgroundAttachment;
}
</script>
color test <br />
<button onclick=”testOneByOne()”>Test One by One</button>
<button onclick=”testAll()”>Test All</button>
</body>

用dynaTrace监控如下:

   

相信这图不用多说大家都能看懂了吧,可以看出有了回流后,rendering的时间相比之前的只重绘,时间翻了3倍了,可见回流的高成本性啊。
大家看到时候注意明细处相比之前的多了个 Calcalating flow layout。

最后再使用Speed Tracer测试一下,其实结果是一样的,只是让大家了解下2个测试工具:

测试1:

  

图上第一次点击执行2ms(其中有50% 用于style Recalculation), 第二次1ms,而且第一次click后面也跟了2次style Recalculation,而第二次点击却没有style Recalculation。
但是这次测试发现paint重绘的时间竟然是一样的,都是3ms,这可能就是chrome比IE强的地方吧。

测试2:

  

从图中竟然发现第二次的测试结果在时间上跟第一次的完全一样,这可能是因为操作太少,而chrome又比较强大,所以没能测试明显结果出来,
但注意图中多了1个紫色部分,就是layout的部分。也就是我们说的回流。

转自:http://blog.loveisanan.com/?p=104

 

对于backgroundPosition,除了IE6,7外其他浏览器都支持。

对于backgroundPositionX,除了Firefox和Opera外其他浏览器都支持。

为了解决兼容问题,我们可以通过split()方法来截取X部分或者Y部分

 

解决办法:
1、先定义一个CSS规则,然后this.className=”
2、document.getElementByIdx_x(“a”).style.cssText=”border-collapse:collapse;border-spacing:1;border:1 solid #0B2565;background-color:white;color:black;text-align=’center’;”
JS操作css的float属性的特殊写法
使用js操作css属性的写法是有一定的规律的:
1、对于没有中划线的css属性一般直接使用style.属性名即可。
如:obj.style.margin,obj.style.width,obj.style.left,obj.style.position等。
2、对于含有中划线的css属性,将每个中划线去掉并将每个中划线后的第一个字符换成大写即可。
如:obj.style.marginTop,obj.style.borderLeftWidth,obj.style.zIndex,obj.style.fontFamily等。
这个规律我想大多数的前端开发者也都熟知。但在css中有一个特殊的属性其js使用方法比较特殊。
这个特殊的属性就是:float。我们不能直接使用obj.style.float来使用,这样操作是无效的。
其正确的使用方法是为:IE:obj.style.styleFloat,其他浏览器:obj.style.cssFloat。

CSS 和 JavaScript 标签 style 属性对照表:(ps:以下只是其中一种,仍没考虑兼容性

盒子标签和属性对照
CSS语法(不区分大小写)	JavaScript语法(区分大小写)
border			border
border-bottom		borderBottom
border-bottom-color	borderBottomColor
border-bottom-style	borderBottomStyle
border-bottom-width	borderBottomWidth
border-color		borderColor
border-left		borderLeft
border-left-color	borderLeftColor
border-left-style	borderLeftStyle
border-left-width	borderLeftWidth
border-right		borderRight
border-right-color	borderRightColor
border-right-style	borderRightStyle
border-right-width	borderRightWidth
border-style		borderStyle
border-top		borderTop
border-top-color	borderTopColor
border-top-style	borderTopStyle
border-top-width	borderTopWidth
border-width		borderWidth
clear			clear
float			floatStyle
margin			margin
margin-bottom		marginBottom
margin-left		marginLeft
margin-right		marginRight
margin-top		marginTop
padding			padding
padding-bottom		paddingBottom
padding-left		paddingLeft
padding-right		paddingRight
padding-top		paddingTop

颜色和背景标签和属性对照
CSS 语法(不区分大小写)	JavaScript 语法(区分大小写)
background		background
background-attachment	backgroundAttachment
background-color	backgroundColor
background-image	backgroundImage
background-position	backgroundPosition
background-repeat	backgroundRepeat
color			color

样式标签和属性对照
CSS语法(不区分大小写)	JavaScript 语法(区分大小写)
display			display
list-style-type		listStyleType
list-style-image	listStyleImage
list-style-position	listStylePosition
list-style		listStyle
white-space		whiteSpace

文字样式标签和属性对照
CSS 语法(不区分大小写)	JavaScript 语法(区分大小写)
font			font
font-family		fontFamily
font-size		fontSize
font-style		fontStyle
font-variant		fontVariant
font-weight		fontWeight

文本标签和属性对照
CSS 语法(不区分大小写)	JavaScript 语法(区分大小写)
letter-spacing		letterSpacing
line-break		lineBreak
line-height		lineHeight
text-align		textAlign
text-decoration		textDecoration
text-indent		textIndent
text-justify		textJustify
text-transform		textTransform
vertical-align		verticalAlign

转自:http://blog.sina.com.cn/s/blog_7de0b6230100z55x.html

 

正则表达式可以:
•测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证
•替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字
•根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字

正则表达式语法:
一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

创建正则表达式:

View Code
 1 var re = new RegExp();//RegExp是一个对象,和Aarray一样
 2 //但这样没有任何效果,需要将正则表达式的内容作为字符串传递进去
 3 re =new RegExp("a");//最简单的正则表达式,将匹配字母a
 4 re=new RegExp("a","i");//第二个参数,表示匹配时不分大小写

RegExp构造函数第一个参数为正则表达式的文本内容,而第二个参数则为可选项标志.标志可以组合使用
•g (全文查找)
•i (忽略大小写)
•m (多行查找)
View Code
1 var re = new RegExp(“a”,”gi”);//匹配所有的a或A
正则表达式还有另一种正则表达式字面量的声明方式

View Code
1 var re = /a/gi;

正则表达式相关的方法和属性

正则表达式对象的方法
•test,返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式。如果存在则返回 true,否则就返回 false。
•exec,用正则表达式模式在字符串中运行查找,并返回包含该查找结果的一个数组。
•compile,把正则表达式编译为内部格式,从而执行得更快。
正则表达式对象的属性
•source,返回正则表达式模式的文本的复本。只读。
•lastIndex,返回字符位置,它是被查找字符串中下一次成功匹配的开始位置。
•$1…$9,返回九个在模式匹配期间找到的、最近保存的部分。只读。
•input ($_),返回执行规范表述查找的字符串。只读。
•lastMatch ($&),返回任何正则表达式搜索过程中的最后匹配的字符。只读。
•lastParen ($+),如果有的话,返回任何正则表达式查找过程中最后括的子匹配。只读。
•leftContext ($`),返回被查找的字符串中从字符串开始位置到最后匹配之前的位置之间的字符。只读。
•rightContext ($’),返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符。只读。
String对象一些和正则表达式相关的方法

•match,找到一个或多个正则表达式的匹配。
•replace,替换与正则表达式匹配的子串。
•search,检索与正则表达式相匹配的值。
•split,把字符串分割为字符串数组。

测试正则表达式是如何工作的!

View Code

1 //test方法,测试字符串,符合模式时返回true,否则返回false
 2 var re = /he/;//最简单的正则表达式,将匹配he这个单词
 3 var str = "he";
 4 alert(re.test(str));//true
 5 str = "we";
 6 alert(re.test(str));//false
 7 str = "HE";
 8 alert(re.test(str));//false,大写,如果要大小写都匹配可以指定i标志(i是ignoreCase或case-insensitive的表示)
 9 re = /he/i;
 10 alert(re.test(str));//true
 11 str = "Certainly!He loves her!";
 12 alert(re.test(str));//true,只要包含he(HE)就符合,如果要只是he或HE,不能有其它字符,则可使用^和$
 13 re = /^he/i;//脱字符(^)代表字符开始位置
 14 alert(re.test(str));//false,因为he不在str最开始
 15 str = "He is a good boy!";
 16 alert(re.test(str));//true,He是字符开始位置,还需要使用$
 17 re = /^he$/i;//$表示字符结束位置
 18 alert(re.test(str));//false
 19 str = "He";
 20 alert(re.test(str));//true
 21 //当然,这样不能发现正则表达式有多强大,因为我们完全可以在上面的例子中使用==或indexOf
 22 re = /\s/;// \s匹配任何空白字符,包括空格、制表符、换页符等等
 23 str= "user Name";//用户名包含空格
 24 alert(re.test(str));//true
 25 str = "user Name";//用户名包含制表符
 26 alert(re.test(str));//true
 27 re=/^[a-z]/i;//[]匹配指定范围内的任意字符,这里将匹配英文字母,不区分大小写
 28 str="variableName";//变量名必须以字母开头
 29 alert(re.test(str));//true
 30 str="123abc";
 31 alert(re.test(str));//false

当然,仅仅知道了字符串是否匹配模式还不够,我们还需要知道哪些字符匹配了模式

View Code

1 var osVersion = "Ubuntu 8";//其中的8表示系统主版本号
 2 var re = /^[a-z]+\s+\d+$/i; //+号表示字符至少要出现1次,\s表示空白字符,\d表示一个数字
 3 alert(re.test(osVersion));//true,但我们想知道主版本号
 4 //另一个方法exec,返回一个数组,数组的第一个元素为完整的匹配内容
 5 re=/^[a-z]+\s+\d+$/i;
 6 arr = re.exec(osVersion);
 7 alert(arr[0]);//将osVersion完整输出,因为整个字符串刚好匹配re
 8 //我只需要取出数字
 9 re=/\d+/;
 10 var arr = re.exec(osVersion);
 11 alert(arr[0]);//8

注意,当字符串不匹配re时,exec方法将返回null
String对象的一些和正则表达式有关的方法

View Code

1 //replace方法,用于替换字符串
 2 var str ="some money";
 3 alert(str.replace("some","much"));//much money
 4 //replace的第一个参数可以为正则表达式
 5 var re = /\s/;//空白字符
 6 alert(str.replace(re,"%"));//some%money
 7 //在不知道字符串中有多少空白字符时,正则表达式极为方便
 8 str ="some some \tsome\t\f";
 9 re = /\s+/;
 10 alert(str.replace(re,"#"));//但这样只会将第一次出现的一堆空白字符替换掉
 11 //因为一个正则表达式只能进行一次匹配,\s+匹配了第一个空格后就退出了
 12 re = /\s+/g;//g,全局标志,将使正则表达式匹配整个字符串
 13 alert(str.replace(re,"@"));//some@some@some@
 14 //另一个与之相似的是split
 15 var str = "a-bd-c";
 16 var arr = str.split("-");//返回["a","bd","c"]
 17 //如果str是用户输入的,他可能输入a-bd-c也可能输入a bd c或a_bd_c,但不会是abdc(这样就说他输错了)
 18 str = "a_db-c";//用户以他喜欢的方式加分隔符s
 19 re=/[^a-z]/i;//前面我们说^表示字符开始,但在[]里它表示一个负字符集
 20 //匹配任何不在指定范围内的任意字符,这里将匹配除字母处的所有字符
 21 arr = str.split(re);//仍返回["a","bd","c"];
 22 //在字符串中查找时我们常用indexOf,与之对应用于正则查找的方法是search
 23 str = "My age is 18.Golden age!";//年龄不是一定的,我们用indexOf不能查找它的位置
 24 re = /\d+/;
 25 alert(str.search(re));//返回查找到的字符串开始下标10
 26 //注意,因为查找本身就是出现第一次就立即返回,所以无需在search时使用g标志
 27 //下面的代码虽然不出错,但g标志是多余的
 28 re=/\d+/g;
 29 alert(str.search(re));//仍然是10

注意,当search方法没有找到匹配时,将返回-1
类似于exec方法,String对象的match方法也用于将字符串与正则表达式进行匹配并返回结果数组

View Code

1 var str = "My name is CJ.Hello everyone!";
 2 var re = /[A-Z]/;//匹配所有大写字母
 3 var arr = str.match(re);//返回数组
 4 alert(arr);//数组中只会包含一个M,因为我们没有使用全局匹配
 5 re = /[A-Z]/g;
 6 arr = str.match(re);
 7 alert(arr);//M,C,J,H
 8 //从字符串中抽取单词
 9 re = /\b[a-z]*\b/gi;//\b表示单词边界
 10 str = "one two three four";
 11 alert(str.match(re));//one,two,three,four

RegExp对象实例的一些属性
View Code

1 var re = /[a-z]/i;
 2 alert(re.source);//将[a-z]字符串输出
 3 //请注意,直接alert(re)会将正则表达式连同前向斜线与标志输出,这是re.toString方法定义的

每个RegExp对象的实例具有lastIndex属性,它是被查找字符串中下一次成功匹配的开始位置,默认值是-1。 lastIndex 属性被 RegExp 对象的 exec 和 test 方法修改.并且它是可写的.
View Code

1 var re = /[A-Z]/;
 2 //exec方法执行后,修改了re的lastIndex属性,
 3 var str = "Hello,World!!!";
 4 var arr = re.exec(str);
 5 alert(re.lastIndex);//0,因为没有设置全局标志
 6 re = /[A-Z]/g;
 7 arr = re.exec(str);
 8 alert(re.lastIndex);//1
 9 arr = re.exec(str);
 10 alert(re.lastIndex);//7

转自http://www.cnblogs.com/xingshikk/archive/2011/04/28/2031823.html

 

有时候在IE6,7下使用overflow:hidden; 或overflow:scroll;时,超出的部分还是显示了。

这时候我们需要再加上一个属性:position:relative;

© 2012 Hedgehog Suffusion theme by Sayontan Sinha