人在江湖漂


  • 首页

  • 归档

Node.js学习笔记——Global Objects 全局对象

发表于 2011-12-07 | 分类于 javascript

global

在浏览器中,顶级作用域为全局作用域,在全局作用域下通过var something即定义了一个全局变量。但是在Node中并不如此,顶级作用域并非是全局作用域,在Node模块中通过var something定义的变量仅作用于该模块。

require.resolve()

使用内部函数require()的机制查找一个模块的位置,而不用加载模块,只是返回解析后的文件名。

require.paths

require()的搜索路径数组,你可以修改该数组添加自定义的搜索路径。

例如:将一个新的搜索路径插入到搜索列表的头部。

1
require.paths.unshift('/usr/local/node');

__filename

当前正在执行的脚本的文件名。这是一个绝对路径,可能会和命令行参数中传入的文件名不同。

例如:在目录/Users/mjr下运行node example.js

1
2
console.log(__filename);
// /Users/mjr/example.js

__dirname

当前正在执行脚本所在的目录名。

例如:在目录/Users/mjr下运行node example.js

1
2
console.log(__dirname);
// /Users/mjr

module

指向当前模块的引用。特别的,当你通过module.exports和exports两种方式访问的将是同一个对象,参见src/node.js。

折腾Node.js

发表于 2011-12-05 | 分类于 javascript

前段时间在折腾Node.js。刚刚入门,啥都不懂,写篇东西记录下自己碰到的问题。

谷歌的blog被墙了,故得搬过来=。=

说起Node.js,不得不提到git。

git的使用可以去看它的官网的帮助手册

接着就是Node.js了,大头的来了

第一步:安装依赖包

1
2
3
1.安装 python2.6或者更高
2.sudo apt-get install g++ curl libssl-dev apache2-utils
3.sudo apt-get install git-core

第二步:获取源码

1
git clone git://github.com/joyent/node.git

第三步:指定编译版本,这个比较关键

1
2
3
4
5
6
7
8
9
10
11
1.cd node
2.git checkout v0.4.10 (这里比较重要,目前很多常用的包只支持到0.4.10,如express,所以如果用最新的版本的话,会导致npm无法下载相应的包)
3.指定路径,编译执行
mkdir ~/local
./configure -prefix=$HOME/local/node
./configure
make
make install
echo 'export PATH=$HOME/local/node/bin:$PATH'>> ~/.profile
echo 'export NODE_PATH=$HOME/local/node:$HOME/local/node/lib/node_modules'>> ~/.profile
source ~/.profile

第四步:设置环境变量

如果想重启后还能继续直接使用node命令,那么需要设置环境变量:
使用命令 sudo gedit /etc/profile 打开配置文件,在文件最后中添加如下两行:

1
2
export PATH=”$HOME/local/node/bin:$PATH”
export NODE_PATH=”$HOME/local/node:$HOME/local/node/lib/node_modules”

保存后重启系统使设置生效。

第五步:安装npm (这里注意可能需要翻墙来安装)

1
2
3
4
5
6
7
8
curl http://npmjs.org/install.sh | sh
根据需要,安装相应的包,例如express:
npm install express
如果输入该命令后长时间没有反应,可以通过添加 -verbose参数查看执行的详细信息,即:
npm install express -verbose
一般情况下无法下载有两个原因:
1. 网速太慢,超时退出。
2. node的版本太新,当前下载的包不支持。(解决方法在第三步已说明。)

如果被墙了,可以用SSH翻墙后,用proxychains来执行,当然还得先装个proxychains(详见附录)。

安装完proxychains后可用命令proxychains npm install  XXX,来安装node相应的包。

搞定后你可以先跑个helloworld例子看一下,这个例子网上到处都有,就不贴了=。=
附录: proxychains安装方法如下:

ubuntu11.10下直接sudo apt-get install proxychains就可以安装了,其他版本的linux系统可以看看自己系统的软件包支持有木有,如果软件包更新中没有就点击这里去[proxychains官方下载最新的版本](http://sourceforge.net/projects/proxychains/files/proxychains/version%203.1/proxychains-3.1.tar.gz/download)。然后编译,具体编译方法可以看包中的INSTALL文件说明。

安装完成后我们需要对程序进行配置,配置文件是/etc/proxychains.conf,但是根据作者的说明,其实配置文件在三个地方都是有效的。

好了,既然配置文件已经找到了,我们就来看看配置文件的具体配置吧。proxychains的模式有三种

dynamic_chain,按照列表中出现的代理服务器的先后顺序组成一条链,如果有代理服务器失效,则自动将其排除,但至少要有一个是有效的。

strict_chain,按照后面列表中出现的代理服务器的先后顺序组成一条链,要求所有的代理服务器都是有效的

random_chain,列表中的任何一个代理服务器都可能被选择使用,这种方式很适合网络扫描操作(参数chain_len只对random_chain有效)。

默认是选择的strict_chain,因此这里我们不做改变。在最下方可以配置自己的代理,方式可以参照配置文件。例如
http 127.0.0.1 8080

socks5 127.0.0.1 7070 (ssh用这个配置就可以了)

http 123.456.789.1 username passwd

呃,但是如果选择strict_chain的方式,建议就留一个可用的代理即可,要不会无法使用。ok,把配置文件放到你的用户目录下就可以了。配置文件在哪里?下载这个吧,可以直接用做ssh的配置,其它代理自己修改即可。[点此下载配置文件](http://yunfile.com/file/nenew/76c8efa9/)

执行程序的时候直接输入proxychains 程序名即可,比如打开火狐可以用 proxychains firefox。还有,启动个别程序的时候可能需要sudo权限。

获取光标的位置

发表于 2011-11-10 | 分类于 javascript , position

前段时间写一个MOMO的表情组件,遇到一个问题,即确定当前光标的位置,主要用于textarea跟input中,下面将相关代码罗列如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
(function(){

var textareaHelper = {
/**
* 获取光标的位置
*/
getPostion : function(node, iePos){
if(node.setSelectionRange) {
return node.selectionStart;
} else if (document.selection) {
if( iePos === true ){
i = node.pos || 0;
} else {
var i, sc = document.selection.createRange(), bc = document.body.createTextRange();
bc.moveToElementText(node);
for(i = 0; bc.compareEndPoints('StartToStart', sc) < 0 && sc.moveStart('character', -1) !== 0; i++){
if(node.value.charAt(i) == '\n'){
i++;
}
}
}
return i;
}
},
/**
* 设置光标的位置
*/
setPosition : function(textarea, p){
p = p == 'end' ? textarea.value.length : p;
if(textarea.setSelectionRange){
textarea.focus();
textarea.setSelectionRange(p, p);
} else if (textarea.createTextRange) {
var range = textarea.createTextRange();
range.moveEnd('character', -textarea.value.length);
range.moveEnd('character', p);
range.moveEnd('character', p);
range.select();
}
}
}

})();

JS中的与(AND)、或(OR)工作原理

发表于 2011-10-28 | 分类于 javascript

先来看mozilla的javascript文档对逻辑与的定义:

1
(逻辑与)若expr1可转换为false,则返回expr1;否则,返回expr2。因此,当使用布尔值时,若两个操作数都是true,则&&运算符返回true;否则,返回false。

因此换言之,这意味着,若expr1为真,则expr1 && expr2将返回expr2,否则将返回expr1。

注意:当逻辑与(&&)运算符与非布尔值(non Boolean Values)一起使用时,其运算结果不会返回“true”或“false”,而是返回两个表达式中的某一表达式本身。

那我们该怎么用呢?来接着看:

1
2
3
4
5
if(a){
return a.method();
}else{
return a;
}

根据&&的特性,我们可以将其改写为:

1
return a && a.method();

同样的,再来看逻辑或的定义:

1
(逻辑或)若expr1可转换为true,则返回expr1;否则,返回expr2。因此,当使用布尔值时,若任一操作数是true,则||运算符返回true;若两个操作数都是false,返回false。

所以我们可以利用其来以表达式风格来定义变量的缺省值

1
var myVar = input || default;

当然代码如果都运用这些特性的话,可读性就相对会低一点了,对于新人来说,阅读起来会有困难,需要在开发过程中进行相应的取舍。

IE与FF脚本兼容性问题

发表于 2011-10-25 | 分类于 javascript

getYear()方法

1
2
var year = new Date().getYear();
document.write(year);

在IE中得到的日期是”2010”,在Firefox中看到的日期是”110”,主要是因为在 Firefox 里面 getYear 返回的是 “当前年份-1900” 的值。

【兼容处理】

加上对年份的判断,如:

1
2
3
var year= new Date().getYear();
year = (year&lt;1900?(1900+year):year);
document.write(year);

也可以通过 getFullYear getUTCFullYear 去调用:

1
2
var year = new Date().getFullYear();
document.write(year);

eval()函数

在IE中,可以使用eval(“idName”)或getElementById(“idName”)来取得id为idName的HTML对象;Firefox下只能使用getElementById(“idName”)来取得id为idName的HTML对象。

【兼容处理】

统一用getElementById(“idName”)来取得id为idName的HTML对象。

const声明

在 IE 中不能使用 const 关键字。如:

1
const constVar = 32;

在IE中这是语法错误。

【兼容处理】

不使用 const ,以 var 代替。

var

1
2
3
echo=function(str){
document.write(str);
}

这个函数在IE上运行正常,Firefox下却报错了。

【兼容处理】

而在echo前加上var就正常了,这个就是我们提到var的目的。

CSS的”float”属性

Javascript访问一个给定CSS 值的最基本句法是:object.style.property,但部分CSS属性跟Javascript中的保留字命名相同,如”float”,”for”,”class”等,不同浏览器写法不同。

在IE中这样写:

1
document.getElementById("header").style.styleFloat = "left";

在FF中这样写:

1
document.getElementById("header").style.cssFloat = "left";
【兼容处理】
1
2
3
4
5
6
if(document.all){
  document.getElementById("header").style.styleFloat = "left";
}
else{
  document.getElementById("header").style.cssFloat = "left";
}

访问<label>标签中的”for”

和”float”属性一样,同样需要使用不现的句法区分来访问<label>标签中的”for”。

在IE中这样写:

1
2
var myObject = document.getElementById("myLabel");
var myAttribute = myObject.getAttribute("htmlFor");

在FF中这样写:

1
2
var myObject = document.getElementById("myLabel");
var myAttribute = myObject.getAttribute("for");
【兼容处理】

解决的方法也是先 判断浏览器类型。

访问和设置class属性

同样由于class是Javascript保留字的原因,这两种浏览器使用不同的 JavaScript 方法来获取这个属性。

IE8.0之前的所有IE版本的写法:

1
2
var myObject = document.getElementById("header");
var myAttribute = myObject.getAttribute("className");

另外,在使用setAttribute()设置Class属性的时候,两种浏览器也存在同样的差异。

1
setAttribute("className",value);

这种写法适用于IE8.0之前的所有IE版本,注意:IE8.0也不支持”className”属性了。

1
setAttribute("class",value);适用于IE8.0 以及 firefox。
【兼容处理】

方法一,两种都写上:

1
2
3
4
var myObject = document.getElementById("header");
myObject.setAttribute("class","classValue");
myObject.setAttribute("className","classValue");
//设置header的class为classValue

方法二,IE和FF都支持object.className,所以可以这样写:

1
2
var myObject = document.getElementById("header");
myObject.className="classValue";//设置header的class为classValue

方法三,先判断浏览器类型,再根据浏览器类型采用对应的写法。

对象宽高赋值问题

FireFox中类似 obj.style.height = imgObj.height 的语句无效。

【兼容处理】

统一使用 obj.style.height = imgObj.height + ‘px’;

getElementById

1
&lt;input id="id" type="button" value="click me" onclick="alert(id.value)"/&gt;

在Firefox中,按钮没反应,在IE中,就可以,因为对于IE来说,一个HTML 元素的 ID 可以直接在脚本中当作变量名来使用,而Firefox中不可以。

【兼容处理】

尽量采用W3C DOM 的写法,访问对象的时候,用document.getElementById(“id”) 以ID来访问对象,且一个ID在页面中必须是唯一的,同样在以标签名来访问对象的时候,用document.getElementsByTagName(“div”)[0] 。该方式得到较多浏览器的支持。

1
&lt;input id="id" type="button" value="click me" onclick="alert(document.getElementById('id').value)" /&gt;

集合类对象访问

IE下,可以使用()或[]获取集合类对象;Firefox下,只能使用[]获取集合类对象。如:

1
2
document.write(document.forms("formName").src);
//该写法在IE下能访问到Form对象的scrc属性
【兼容处理】

统一使用[]获取集合类对象。

frame的引用

IE可以通过id或者name访问这个frame对应的window对象,而Firefox只可以通过name来访问这个frame对应的window对象。

【兼容处理】

使用frame的name来访问frame对象,另外,在IE和Firefox中都可以使用window.document.getElementById(”frameId”)来访问这个frame对象。

parentElement

IE中支持使用parentElement和parentNode获取父节点。而Firefox只可以使用parentNode。

【兼容处理】

因为firefox与IE都支持DOM,因此统一使用parentNode来访问父节点。

table操作

IE下table中无论是用innerHTML还是appendChild插入<tr>都没有效果,而其他浏览器却显示正常。

【兼容处理】

解决的方法是,将<tr>加到table的<tbody>元素中,如下面所示:

1
2
3
4
5
6
var row = document.createElement("tr");
var cell = document.createElement("td");
var cell_text = document.createTextNode("插入的内容");
cell.appendChild(cell_text);
row.appendChild(cell);
document.getElementsByTagName("tbody")[0].appendChild(row);

移除节点removeNode()和removeChild()

appendNode在IE和Firefox下都能正常使用,但是removeNode只能在IE下用。
removeNode方法的功能是删除一个节点,语法为node.removeNode(false)或者node.removeNode(true),返回值是被删除的节点。
removeNode(false)表示仅仅删除指定节点,然后这个节点的原孩子节点提升为原双亲节点的孩子节点。
removeNode(true)表示删除指定节点及其所有下属节点。被删除的节点成为了孤立节点,不再具有有孩子节点和双亲节点。

【兼容处理】

Firefox中节点没有removeNode方法,只能用removeChild方法代替,先回到父节点,在从父节点上移除要移除的节点。

1
2
node.parentNode.removeChild(node); 
// 为了在ie和firefox下都能正常使用,取上一层的父结点,然后remove。

childNodes获取的节点

1
2
3
4
5
6
&lt;ul id="main"&gt; 
&lt;li&gt;1&lt;/li&gt;
&lt;li&gt;2&lt;/li&gt;
&lt;li&gt;3&lt;/li&gt;
&lt;/ul&gt;
&lt;input type=button value="click me!" onclick="alert(document.getElementById('main').childNodes.length)"&gt;

分别用IE和Firefox运行,IE的结果是3,而Firefox则是7。Firefox使用DOM规范,”#text”表示文本(实际是无意义的空格和换行等)在Firefox里也会被解析成一个节点,在IE里只有有实际意义的文本才会解析成”#text”。

【兼容处理】

方法一,获取子节点时,可以通过node.getElementsByTagName()来回避这个问题。但是 getElementsByTagName对复杂的DOM结构遍历明显不如用childNodes,因为childNodes能更好的处理DOM的层次结构。

方法二,在实际运用中,Firefox在遍历子节点时,不妨在for循环里加上:

1
if(childNode.nodeName=="#text") continue;//或者使用nodeType == 1。

Firefox不能对innerText支持

Firefox不支持innerText,它支持textContent来实现innerText,不过textContent没有像innerText一样考虑元素的display方式,所以不完全与IE兼容。如果不用textContent,字符串里面不包含HTML代码也可以用innerHTML代替。

【兼容处理】
1
2
3
4
5
if(document.all){
document.getElementById('element').innerText = "my text";
} else{
document.getElementById('element').textContent = "my text";
}

CSS性能调优

发表于 2011-10-20 | 分类于 css

简介

Web 开发中经常会遇到性能的问题,尤其是 Web 2.0 的应用。CSS 代码是控制页面显示样式与效果的最直接“工具”,但是在性能调优时他们通常被 Web 开发工程师所忽略,而事实上不规范的 CSS 会对页面渲染的效率有严重影响,尤其是对于结构复杂的 Web 2.0 页面,这种影响更是不可磨灭。所以,写出规范的、高性能的 CSS 代码会极大的提高应用程序的效率。本文主要来探讨一下如何优化,以及从哪些方面优化应用程序的 CSS 代码,从而最大限度的提高 Web 应用的性能。

CSS 代码的分析与渲染都是由浏览器来完成的,所以,了解浏览器的 CSS 工作机制对我们的优化有至关重要的作用。这篇文章我们主要从如下几个方面入手来介绍一下 CSS 的性能优化:

1.Style 标签的相关调优
2.特殊的 CSS 样式使用方式
3.CSS 缩写
4.CSS 的声明
5.CSS 选择器

把 Stylesheets 放在 HTML 页面头部:

浏览器在所有的 stylesheets 加载完成之后,才会开始渲染整个页面,在此之前,浏览器不会渲染页面里的任何内容,页面会一直呈现空白。这也是为什么要把 stylesheet 放在头部的原因。如果放在 HTML 页面底部,页面渲染就不仅仅是在等待 stylesheet 的加载,还要等待 html 内容加载完成,这样一来,用户看到页面的时间会更晚。

对于 @import 和 <link> 两种加载外部 CSS 文件的方式:@import 就相当于是把 <link> 标签放在页面的底部,所以从优化性能的角度看,应该尽量避免使用 @import 命令

避免使用 CSS Expressions:

参考下述代码:

清单 1. CSS Expression 案例

1
Background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" )

Expression 只有 IE 支持,而且他的执行比大多数人想象的要频繁的多。不仅页面渲染和改变大小 (resize) 时会执行,页面滚动 (scroll) 时也会执行,甚至连鼠标在页面上滑动时都会执行。在 expression 里面加上一个计数器就会知道,expression 的执行上相当频繁的。鼠标的滚动很容易就会使 expression 的执行次数超过 10000。

避免使用 Filter:

IE 特有的 AlphaImageLoader filter 是为了解决 IE6 及以前版本不支持半透明的 PNG 图片而存在的。但是浏览器在下载 filter 里面的图片时会“冻结”浏览器,停止渲染页面。同时 filter 也会增大内存消耗。最不能忍受的是 filter 样式在每个页面元素(使用到该 filter 样式)渲染时都会被浏览器分析一次,而不是像一般的背景图片渲染模式:使用过该背景图片的所有元素都是被浏览器一次性渲染的。

针对这种情况,最好的解决办法就是使用 PNG8。

CSS 缩写:

CSS 缩写可以让你用极少的代码定义一系列样式属性,这种做法可以极大程度的缩减代码量以达到提高性能的目的。

清单 2. Colour 缩写

1
2
#000000     ------>>     #000 
#336699 ------>> #369

关于颜色,重复的属性值可以省略。

清单 3. 各种缩写方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Margin-top: 2px; 
Margin-right: 5px;
Margin-bottom: 2em;
Margin-left: 15px; ----->> Margin: 2px 5px 2em 15px;

Border-width: 1px;
Border-style: solid;
Border-color: #000 ----->> border: 1px solid #000

Font-style: italic;
Font-variant: small-caps;
Font-weight: bold;
Font-size: 1em;
Line-height: 140%;
Font-family: sans-serif; ----->> font: italic small-caps bold 1em 140% sans-serief

Background-color: #f00;
Background-image: url(background.gif);
Background-repeat: no-repeat;
Background-attachment: fixed;
Background-position: 0 0;
----->>background: #f00 url(background.gif) no-repeat fixed 0 0

list-style-type: square;
list-style-position: inside;
List-style-image: url(image.gif) ----->> list-style: square inside url(image.gif)

Multiple Declarations

关于 CSS 的 class 声明和定义,也有简写的方式

清单 4. Class 的声明

1
2
3
4
5
6
7
8
9
10
11
.Class1{position: absolute; left: 20px; top: 30px;} 
.Class2{position: absolute; left: 20px; top: 30px;}
.Class3{position: absolute; left: 20px; top: 30px;}
.Class4{position: absolute; left: 20px; top: 30px;}
.Class5{position: absolute; left: 20px; top: 30px;}
.Class6{position: absolute; left: 20px; top: 30px;}


.class1 .class2 .class3 .class4 .class5 .class6{
Position: absolute; left: 20px; top: 20px;
}

这种 Class 简写的方式可以极大的缩减我们的代码,提高浏览器分析识别的效率。

CSS 选择器 (CSS Selectors)

先来看看下面这个例子:

清单 5. Child selector

1
#toc > li {font-weight: bold}

按照我们惯常的理解,编译器应该是先查找 id 为“toc”的节点,然后在他的所有直接子节点中查找类型(tag)为“li”的节点,将“font-weight”属性应用到这些节点上。

但是,不幸的是,恰恰相反,浏览器是“从右往左”来分析 class 的,它的匹配规则是从右向左来进行匹配的。这里,浏览器首先会查找页面上所有的“li”节点,然后再去做进一步的判断:如果它的父节点的 id 为“toc”,则匹配成功。

由此可知,CSS 选择器的匹配远比我们想象的要慢的多,CSS 的性能问题不容忽视。

清单 6. Descendant selector

1
#toc  li {font-weight: bold}

这个效率比之前的“child selector”效率更慢,而且要慢很多。浏览器先便利所有的“li”节点,然后步步上溯其父节点,直到 DOM 结构的根节点(document),如果有某个节点的 id 为“toc”,则匹配成功,否则继续查找下一个“li”节点。

清单 7. 尽量避免 universal rules

1
[hidden="true"] { ... } /* A universal rule */

这里的匹配规则很明显:查找页面上的所有节点,如果有节点存在“hidden”属性,并且其属性值为“true”,则匹配成功。这是最耗时耗力的匹配,页面上的所有节点都需要进行匹配运算,这种规则应尽量避免。

清单 8. Id-categorized 规则与 tag name 或 class 规则并行

1
2
button#goButton {...};----->>#goButton 
.fundation#testIcon {...};----->>#testIcon

这里,按照我们常规的理解,箭头左边的写法似乎是应该更快的,因为它的限制更多。其实不然,id 是全局唯一的,在匹配 CSS 选择器时浏览器定位到 id 是最快的,如果伴随有其他的非 id 的 selector,反而会影响匹配的效率。

清单 9. 关于 class-categorized 规则

1
utton.indented {...}----->>.button-indented {...}

程序员们经常会给某个 Class 前面加上标签名称(Tag Name),以更精确且快速的定位该节点,但是这样往往效率更差。和清单 8 中的原理一样,页面上的 class 在全局范围内来讲应该是唯一的,用唯一的 Class 名称来定位一个节点往往比组合定位更加快捷。事实上,这种做法也可以避免由于开发修改页面元素的类型(Tag)而导致的样式失效的情况,做到样式与元素的分离,两者独立维护。

清单 10. 尽量减少规则数量

1
2
3
Span[mailfolder="true"] > table > tr > td.columnClass {...} 

.span-mailfolder-tbl-tdCol {...}

规则越多,匹配越慢,上面一种规则需要进行 6 项匹配,先找“columnClass”,再找“td”,然后是“tr”,“table”,最后是符合“mailfolder”为“true”的 span,这种效率是非常慢的。如果用一个比较特殊的 class 替代(span-mailfolder-tbl-tdCol),效率会快上好几倍。

清单 11. 尽量避免使用 descendant selector

1
treehead treerow treecell {...} ----->> treehead > treerow > treecell {...}

Descendant 选择器是耗时相对高的选择器,通常来讲,它在 CSS 里的使用应该是尽量避免的,如果能用 child 选择器替代就应该尽量这样去做。

清单 12. 利用 CSS 的继承机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Color 
Font
Letter-spacing
Line-height
List-style
Text-align
Text-indent
Text-transform
White-space
Word-spacing

#bookmark > .menu-left {list-style-image: url(blah)}

------------>>>>>>>>

#bookmark {list-style-image: url(blah)}

在 CSS 中,有很多 CSS 的属性以可以继承的,如果某个节点的父节点已经设定了上述的 CSS 样式(如:color, font 等 …),并且子节点无需更改该样式,则无需再作相关设定,同时,也可以利用这一点:如果很多子节点都需要设定该 CSS 属性值,可以统一设定其父节点的该 CSS 属性,这样一来,所有的子节点再无需做额外设定,加速了 CSS 的分析效率。

原文地址

IE与FF对盒模型的不同解析

发表于 2011-09-20 | 分类于 css

首先,单纯从页面显示的角度来说,IE和FF的和模型的现实宽度/高度,都等于width+padding+border+margin宽度/高度总和。

但是在剥削的属性里,FF仍然是本身width属性的宽度,而IE的width属性width+padding+border+margin宽度/高度总和

下面举例说明:

IE和FF对盒模型的解释也不一样,代码说明:

test { width: 650px !important;width: 648px;padding-left:2px;background:#fff; }

test 显示的宽度是 650px

IE Box的总宽度是:width+padding+border+margin宽度总和

FF Box的总宽度就是 width的宽度,padding+border+margin的宽度在含在width内。

如果有BOX{width:”300px”; padding:”5px”;}

则BOX在IE的宽度应该为:310px

而在FF的宽度则是:300px

所以在BOX有填充的情况下应该这样使用

BOX{width:”290″!IMPORTANT; width: “300″;}

这样子才能确保BOX的宽度始终在300px,而不会出现被撑开的现象

而在FF里面则不会造成浮动层填不满的情况

ul 标签在 Mozilla 中有 padding 值的,而在 IE 中只有 margin 有值。

设置ul{margin:0;padding:0}

IE和Mozilla浏览器对盒模型的解释不一致,造成定位上的困难,主要差别是:

1.IE计算2个div之间的距离时候,会把1px的border计算在内,而mozilla没有.

2.设定div的宽度后,如果给padding加一个值,IE5会在宽度内减去这个值,而Mozilla会在宽度基础上加上这个值。

针对firefox ie6 ie7的css样式

现在大部分都是用!important来hack,对于ie6和firefox测试可以正常显示,

但是ie7对!important可以正确解释,会导致页面没按要求显示!找到一个针

对IE7不错的hack方式就是使用“*+html”,现在用IE7浏览一下,应该没有问题了。

CSS优先级

发表于 2011-09-06 | 分类于 css

所谓CSS优先级,即是指CSS样式在浏览器中被解析的先后顺序。

样式表中的特殊性描述了不同规则的相对权重,它的基本规则是:

统计选择符中的ID属性个数。
统计选择符中的CLASS属性个数。
统计选择符中的HTML标记名个数。

最后,按正确的顺序写出三个数字,不要加空格或逗号,得到一个三位数(css2.1是用4位数表示)。(注意,你需要把数字转换成一个以三个数字结尾的更大的数)。相应于选择符的最终数字列表可以很容易确定较高数字特性凌驾于较低数字的。

每个ID选择符(#someid),加 0,1,0,0。
每个class选择符(.someclass)、每个属性选择符(形如[attr=value]等)、每个伪类(形如:hover等)加0,0,1,0。
每个元素或伪元素(:firstchild)等,加0,0,0,1。
其它选择符包括全局选择符*,加0,0,0,0。相当于没加,不过这也是一种specificity,后面会解释。

特性分类的选择符列表

通过上面,就可以很简单的看出,HTML标记的权重是1,CLASS的权重是10,ID的权重是100,继承的权重为0

按这些规则将数字符串逐位相加,就得到最终的权重,然后在比较取舍时按照从左到右的顺序逐位比较。

优先级问题其实就是一个冲突解决的问题,当同一个元素(内容)被CSS选择符选中时,就要按照优先级取舍不同的CSS规则,这其中涉及到的问题其实很多。

###CSS的继承性和继承的局限性###

继承是CSS的一个主要特征,它是依赖于祖先-后代的关系的。继承是一种机制,它允许样式不仅可以应用于某个特定的元素,还可以应用于它的后代。

有一些属性不能被继承,如:border, margin, padding, background等。

###附加说明###

文内的样式优先级为1,0,0,0,所以始终高于外部定义。这里文内样式指形如<div style=”color:red”>blah</div>的样式,而外部定义指经由<link>或<style>卷标定义的规则。
有!important声明的规则高于一切。
如果!important声明冲突,则比较优先权。
如果优先权一样,则按照在源码中出现的顺序决定,后来者居上。
由继承而得到的样式没有specificity的计算,它低于一切其它规则(比如全局选择符*定义的规则)。
关于经由@import加载的外部样式,由于@import必须出现在所有其它规则定义之前(如不是,则浏览器应该忽略之),所以按照后来居上原则,一般优先权冲突时是占下风的。

还需要说一下,IE是可以识别位置错误的@import的,但无论@import在什么地方,它都认为是位于所有其它规则定义之前的,这可能会引发一些误会。

优先权问题看起来简单,但背后还是有非常复杂的机制,在实际应用中需要多多留意。

语义化标签和属性

发表于 2011-09-01 | 分类于 html

分离结构与表现的另一个重要方面是使用语义化的标记来构造文档内容。一个 XHTML 元素的存在就意味被标记内容的那部分有相应的结构化的意义,没有理由使用其他的标记。换句话说,不要让 CSS 使一个 HTML 元素看起来就像另一个 HTML 元素,比如用<div>来代替<p>标记标题。

首先是关于语义(Semantics)和默认样式的区别,默认样式是浏览器设定的一些常用tag的表现形式,个人认为他的主要目的就是让大家直观的认识标签(markup)和属性(attribute)的用途和作用,很明显Hx系列看起来很像标题,因为拥有粗体和较大的字号。<strong>,<em>用来区别于其他文字,起到了强调的作用。至于列表和表格很明显的告诉你他们是做什么的。

其次,语义化的网页的好处,最主要的就是对搜索引擎友好,又了良好的结构和语义你的网页内容自然容易被搜索引擎抓取,你网站的推广便可以省下不少的功夫。

具体的语义和用途在,XHTML1.0 TAG 参考中都已经说明,这里将一些容易遗忘或者混淆的TAGS和属性予以补充。

###<Hx>###

<h1>、<h2>、<h3>、<h4>、<h5>、<h6>,作为标题使用,并且依据重要性递减。<h1>是最高的等级。

例如:

1
2
<h1>文档标题</h1>
<h2>次级标题</h2>

而不要使用<div class=”title”>文档标题</div>,或者<span class=”title”>文档标题</span>.很明显搜索引擎对于后者是不会认为他是标题的。

###<p>###

段落标记,知道了<p>作为段落,你就不会再使用<br/>来换行了,而且不需要<br/><br/>来区分段落与段落。<p></p>中的文字会自动换行,而且换行的效果优于<br />。段落与段落之间的空隙也可以利用CSS来控制,很容易而且清晰的区分出段落与段落。在利用行高(line-height)很容易的定义出行间距,再定义首字下沉等效果,那就挺完美了。

例如:

1
<p>这是一个段落哦~~</p>

###<ul>、<ol>、<li>###

<ul>无序列表,很常见的到了大家广泛的使用,<ol>有序列表也挺常用。在web标准化过程中,<ul>还被更多的用于导航条,本来导航条就是个列表,这样做是完全正确的,而且当你的浏览器不支持CSS的时候,导航链接仍然很好使,就是美观方面差了一点。

例如:

1
2
3
4
5
<ul>
<li>项目一</li>
<li>项目二</li>
<li>项目三</li>
</ul>
1
2
3
4
5
<ol>
<li>项目一</li>
<li>项目二</li>
<li>项目三</li>
</ol>

###<dl>、<dt>、<dd>###

dl就是“定义列表”。比如说词典里面的词的解释、定义就可以用这种列表。

1
2
3
4
<dl>
<dt>Dog</dt>
<dd>A carnivorous mammal of the family Canidae.</dd>
</dl>

###<cite>、<q>、<blockquote>###

论坛和blog经常会用到引用别人的话,用<q>来标记简短的单行引用。Web浏览器会自动识别在<q> 之间的内容。不幸的是,IE不能识别,并且有些时候, <q>会引起一些可访问性(Accessibility)的问题。正因为如此,一些人建议尽量不要使用 <q>,手动的插入引用标记。在一个包含适当的类的 <span>中加入单行的引用内容,那么就可以用CSS来给引用设计样式了,但是这个没有语义上的意义。

对于那些一段或者好几段的长篇引用,就应当使用 <blockquote>了。CSS可以用来定义引用的样式。注意,一段文章是不可以直接放在<blockquote>中的,引用的内容还必须包含在一个元素中,通常是<p>。属性cite既可以与<q> 一起用,也可以与<blockquote>一起用,用来提供引用内容的来源地址。需要注意的是,如果你使用<span>来代替 <q>标记引用内容,那么你就不能使用 cite属性了。例如:

1
<cite>Designing with Web Standards</cite> is an excellent book by Jeffrey Zeldman.
1
<p> <cite>孔子</cite>曰:<q>学而不思则罔,思而不学则殆</q>.</p>
1
<p>The W3C says that <q cite="http://www.w3.org/TR/REC-html40/struct/text.html#h-9.2.1">The presentation of phrase elements depends on the user agent.</q>.</p>
1
2
3
4
<blockquote cite="http://www.w3cn.org/">
<p>“我们大部分人都有深刻体验,每当主流浏览器版本的升级,我们刚建立的网站就可能变得过时,我们就需要升级或者重新建造一遍网站。例如1996-1999年典型的"浏览器大战",为了兼容 Netscape 和 IE,网站不得不为这两种浏览器写不同的代码。同样的,每当新的网络技术和交互设备的出现,我们
也需要制作一个新版本来支持这种新技术或新设备,例如支持手机上网的 WAP 技术。类似的问题举不胜举:网站代码臃肿、繁杂浪费了我们大量的带宽;针对某种浏览器的 DHTML 特效,屏蔽了部分潜在的客户;不易用的代码,残障人士无法浏览网站等等。这是一种恶性循环,是一种巨大的浪费。</p>
</blockquote>

###<em>、<strong>###

<em> 是用作强调的,<strong>是用作重点强调的。 大部分浏览器用斜体显示强调的内容,用粗体来显示重点强调的内容,然而,这是没有必要的,如果是为了确定强调内容的显示方式,最好的方法就是使用CSS来定义他们的表现。当你想要的只是视觉上的效果时,就不要使用强调了。而且如果你想要强调但是还觉得粗体或者斜体不视觉效果没那么好,特别是斜体对于中文来说,那么你完全可以定义一些其他的比较醒目的样式达到强调的效果。

1
<p><em>强调</em> 的文本通常用斜体显示,然而,<strong>特别强调</strong> 的文本通常以粗体显示。</p>

###<table>、<td>、<th>、<caption>、summary###

XHTML中的表格不应用来布局。然而如果是为了标记列表的数据,就应该使用表格了。<th>为表格标题,属性summar为摘要,<caption>标签为首部说明,<thead>标签为表格头部,<tbody>标签为表格主体内容,<tfoot>标签为表格尾部。

其中还可以使用scope 可用于取代headers属性,标记含有表头信息的单元格,其中各数值的内容如下:

row 指示当前单元格,为包含当前单元格的行提供相关的表头信息。

col 指示当前单元格,为根据当前单元格指定的列提供相应的表头信息。

rowgroup 指示当前单元格,为包含当前单元格的其余行组提供相关的表头信息。

colgroup 指示当前单元格,为根据当前单元格指定的其余列组提供相应的表头信息。

abbr 用于定义表头单元格中的缩写名,如果没有定义该属性,则将默认单元格内容为节略形式。

###<dfn>###

1
<p><dfn title="Microsoft web browser">Internet Explorer</dfn> is the most popular browser used underwater.</p>

###<ins>, <del>###

知道del,就不要再用<s>做删除线了,用del显然更具有语义化。而且del还带有cite和datetime来表明删除的原因以及删除的时间。ins是表示插入,也有这样的属性。

1
<p>It really was <ins cite="rarara.html" datetime="20031024">very</ins> good.</p>

###<code>###

表示是计算机代码。而默认样式为打字体。技术论坛和blog中经常遇到。

1
<code>p{margin:2px 0;}</code>

###<abbr>、<acronym>###

<abbr>标签是表示web页面上的简称,<acronym>标签为取首字母缩写。(注:这里把简称和缩写分开而论,简称范围比缩写大,取首字母的缩写用<acronym>标签)Windows的IE6.0以下的浏览器暂不支持<abbr>标签。 在IE里,你可以应用CSS给<acronym>但是不能应用给<abbr>标签,IE会为<acronym>标签的title属性显示提示,但是会忽略<abbr>标签。

1
2
<abbr title="Cascading Style Sheets">CSS</abbr>
<acronym title="Cascading Style Sheets">CSS</acronym>

###alt属性和title属性###

title属性用来为元素提供额外说明信息title属性可以用在除了base,basefont,head,html,meta,param,script和title之外的所有标签。但是并不是必须的。

alt属性为不能显示图像、窗体或applets的用户代理(UA),指定替换文字。替换文字的语言由lang属性指定。
只需要一行语句把生产者、过滤器和消费者串联起来就可以创建出一个管道:

HTML解析原理

发表于 2011-08-27 | 分类于 html

Web页面运行在各种各样的浏览器当中,浏览器载入、渲染页面的速度直接影响着用户体验。

简单地说,页面渲染就是浏览器将html代码根据CSS定义的规则显示在浏览器窗口中的这个过程。先来大致了解一下浏览器都是怎么干活的:

  1. 用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件;

  2. 浏览器开始载入html代码,发现<head>标签内有一个<link>标签引用外部CSS文件;

  3. 浏览器又发出CSS文件的请求,服务器返回这个CSS文件;

  4. 浏览器继续载入html中<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了;

  5. 浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码;

  6. 服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;

  7. 浏览器发现了一个包含一行Javascript代码的<script>标签,赶快运行它;

  8. Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个<div> (style.display=”none”)。杯具啊,突然就少了这么一个元素

  9. 终于等到了</html>的到来,浏览器泪流满面……

  10. 等等,还没完,用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下<link>标签的CSS路径;

  11. 浏览器召集了在座的各位<div><span><ul><li>们,“大伙儿收拾收拾行李,咱得重新来过……”,浏览器向服务器请求了新的CSS文件,重新渲染页面。
    说到页面为什么会慢?那是因为浏览器要花时间、花精力去渲染,尤其是当它发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫reflow。

    reflow图解

reflow几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲染。通常我们都无法预估浏览器到底会reflow哪一部分的代码,它们都彼此相互影响着。

repaint图解

reflow问题是可以优化的,我们可以尽量减少不必要的reflow。比如开头的例子中的图片载入问题,这其实就是一个可以避免的reflow——给图片设置宽度和高度就可以了。这样浏览器就知道了图片的占位面积,在载入图片前就预留好了位置。

另外,有个和reflow看上去差不多的术语:repaint,中文叫重绘。如果只是改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性,将只会引起浏览器repaint。repaint的速度明显快于reflow(在IE下需要换一下说法,reflow要比repaint 更缓慢)。下次将通过一系列的实验说明在Firefox、IE等浏览器下reflow的优化。

1234

SpeMoon

32 日志
59 分类
49 标签
© 2018 SpeMoon
由 Hexo 强力驱动
|
主题 — NexT.Muse v6.0.0