继续上一部分,我们要看一下颜色。火狐好像不管三七二十一都会转变为rgb格式,不过我们通常比较习惯的是hex格式。这就用到以下两函数。
1.
var
rgb2hex =
function
(rgb) {
2.
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
3.
return
"#"
+tohex(rgb[1])+tohex(rgb[2])+tohex(rgb[3])
4.
}
5.
var
tohex =
function
(x) {
6.
var
hexDigits = [
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
];
7.
return
isNaN(x) ?
'00'
: hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
8.
}
我们用正则表达式在检测其是否为rgb格式,是就用rgb2hex来转换它。但如果是red,green等值呢,火狐就一反常态,转换为hex格式,但IE依然如故。我们没有办法,自己做一个哈希,把常用的颜色都弄进去,然后一一匹对便是。
01.
if
(style.search(/background|color/) != -1) {
02.
var
color = {
03.
aqua:
'#0ff'
,
04.
black:
'#000'
,
05.
blue:
'#00f'
,
06.
gray:
'#808080'
,
07.
purple:
'#800080'
,
08.
fuchsia:
'#f0f'
,
09.
green:
'#008000'
,
10.
lime:
'#0f0'
,
11.
maroon:
'#800000'
,
12.
navy:
'#000080'
,
13.
olive:
'#808000'
,
14.
orange:
'#ffa500'
,
15.
red:
'#f00'
,
16.
silver:
'#c0c0c0'
,
17.
teal:
'#008080'
,
18.
transparent:
'rgba(0,0,0,0)'
,
19.
white:
'#fff'
,
20.
yellow:
'#ff0'
21.
}
22.
if
(!!color[value]){
23.
value = color[value]
24.
}
25.
if
(value ==
"inherit"
){
26.
return
getStyle(el.parentNode,style);
27.
}
28.
if
(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(value)){
29.
return
rgb2hex(value)
30.
}
else
if
(/^
#/.test(value)){
31.
value = value.replace(
'#'
,
''
);
32.
return
"#"
+ (value.length == 3 ? value.replace(/^(\w)(\w)(\w)$/,
'$1$1$2$2$3$3'
) : value);
33.
}
34.
return
value;
35.
}
基本上是对于CSS的精确取值就是这样,显然它还存在许多不足之处,但对于布局用的和常用的样式都实现了。还提供了一个判断页面渲染模式的常数q,为了方便,方法名与JQuery同名(只能取值,不能赋值,以后有空慢慢与我的addSheet函数整合到一起)。
001.
(
function
(){
002.
var
isQuirk = (document.documentMode) ? (document.documentMode==5) ?
true
:
false
: ((document.compatMode==
"CSS1Compat"
) ?
false
:
true
);
003.
var
isElement =
function
(el) {
004.
return
!!(el && el.nodeType == 1);
005.
}
006.
var
propCache = [];
007.
var
propFloat = !+
"\v1"
?
'styleFloat'
:
'cssFloat'
;
008.
var
camelize =
function
(attr){
009.
return
attr.replace(/\-(\w)/g,
function
(all, letter){
010.
return
letter.toUpperCase();
011.
});
012.
}
013.
var
memorize =
function
(prop) {
//意思为:check out form cache
014.
return
propCache[prop] || (propCache[prop] = prop ==
'float'
? propFloat : camelize(prop));
015.
}
016.
var
getIEOpacity =
function
(el){
017.
var
filter;
018.
if
(!!window.XDomainRequest){
019.
filter = el.style.filter.match(/progid:DXImageTransform.Microsoft.Alpha\(.?opacity=(.*).?\)/i);
020.
}
else
{
021.
filter = el.style.filter.match(/alpha\(opacity=(.*)\)/i);
022.
}
023.
if
(filter){
024.
var
value = parseFloat(filter[1]);
025.
if
(!isNaN(value)) {
026.
return
value ? value / 100 : 0;
027.
}
028.
}
029.
return
1;
030.
}
031.
var
convertPixelValue =
function
(el, value){
032.
var
style = el.style,left = style.left,rsLeft = el.runtimeStyle.left;
033.
el.runtimeStyle.left = el.currentStyle.left;
034.
style.left = value || 0;
035.
var
px = style.pixelLeft;
036.
style.left = left;
//还原数据
037.
el.runtimeStyle.left = rsLeft;
//还原数据
038.
return
px +
"px"
039.
}
040.
var
rgb2hex =
function
(rgb) {
041.
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
042.
return
"#"
+tohex(rgb[1])+tohex(rgb[2])+tohex(rgb[3])
043.
}
044.
var
tohex =
function
(x) {
045.
var
hexDigits = [
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
];
046.
return
isNaN(x) ?
'00'
: hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
047.
}
048.
var
getStyle =
function
(el, style){
049.
var
value;
050.
if
(!+
"\v1"
){
051.
//特殊处理IE的opacity
052.
if
(style ==
"opacity"
){
053.
return
getIEOpacity(el)
054.
}
055.
value = el.currentStyle[memorize(style)];
056.
//特殊处理IE的height与width
057.
if
(/^(height|width)$/.test(style)){
058.
var
values = (style ==
'width'
) ? [
'left'
,
'right'
] : [
'top'
,
'bottom'
], size = 0;
059.
if
(isQuirk){
060.
return
el[camelize(
"offset-"
+style)] +
"px"
061.
}
else
{
062.
var
client = parseFloat(el[camelize(
"client-"
+style)]),
063.
paddingA = parseFloat(getStyle(el,
"padding-"
+ values[0])),
064.
paddingB = parseFloat(getStyle(el,
"padding-"
+ values[1]));
065.
return
(client - paddingA - paddingB)+
"px"
;
066.
}
067.
}
068.
}
else
{
069.
if
(style ==
"float"
){
070.
style = propFloat;
071.
}
072.
value = document.defaultView.getComputedStyle(el,
null
).getPropertyValue(style)
073.
}
074.
//下面部分全部用来转换上面得出的非精确值
075.
if
(!/^\d+px$/.test(value)){
076.
//转换可度量的值
077.
if
(/(em|pt|mm|cm|pc|
in
|ex|rem|vw|vh|vm|ch|gr)$/.test(value)){
078.
return
convertPixelValue(el,value);
079.
}
080.
//转换百分比,不包括字体
081.
if
(/%$/.test(value) && style !=
"font-size"
){
082.
return
parseFloat(getStyle(el.parentNode,
"width"
)) * parseFloat(value) /100 +
"px"
083.
}
084.
//转换border的thin medium thick
085.
if
(/^(border).+(width)$/.test(style)){
086.
var
s = style.replace(
"width"
,
"style"
),
087.
b = {
088.
thin:[
"1px"
,
"2px"
],
089.
medium:[
"3px"
,
"4px"
],
090.
thick:[
"5px"
,
"6px"
]
091.
};
092.
if
(value ==
"medium"
&& getStyle(el,s) ==
"none"
){
093.
return
"0px"
;
094.
}
095.
return
!!window.XDomainRequest ? b[value][0] : b[value][1];
096.
}
097.
//转换margin的auto
098.
if
(/^(margin).+/.test(style) && value ==
"auto"
){
099.
var
father = el.parentNode;
100.
if
(/MSIE 6/.test(navigator.userAgent) && getStyle(father,
"text-align"
) ==
"center"
){
101.
var
fatherWidth = parseFloat(getStyle(father,
"width"
)),
102.
_temp = getStyle(father,
"position"
);
103.
father.runtimeStyle.postion =
"relative"
;
104.
var
offsetWidth = el.offsetWidth;
105.
father.runtimeStyle.postion = _temp;
106.
return
(fatherWidth - offsetWidth)/2 +
"px"
;
107.
}
108.
return
"0px"
;
109.
}
110.
//转换top|left|right|bottom的auto
111.
if
(/(top|left|right|bottom)/.test(style) && value ==
"auto"
){
112.
return
el.getBoundingClientRect()[style];
113.
}
114.
//转换颜色
115.
if
(style.search(/background|color/) != -1) {
116.
var
color = {
117.
aqua:
'#0ff'
,
118.
black:
'#000'
,
119.
blue:
'#00f'
,
120.
gray:
'#808080'
,
121.
purple:
'#800080'
,
122.
fuchsia:
'#f0f'
,
123.
green:
'#008000'
,
124.
lime:
'#0f0'
,
125.
maroon:
'#800000'
,
126.
navy:
'#000080'
,
127.
olive:
'#808000'
,
128.
orange:
'#ffa500'
,
129.
red:
'#f00'
,
130.
silver:
'#c0c0c0'
,
131.
teal:
'#008080'
,
132.
transparent:
'rgba(0,0,0,0)'
,
133.
white:
'#fff'
,
134.
yellow:
'#ff0'
135.
}
136.
if
(!!color[value]){
137.
value = color[value]
138.
}
139.
if
(value ==
"inherit"
){
140.
return
getStyle(el.parentNode,style);
141.
}
142.
if
(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(value)){
143.
return
rgb2hex(value)
144.
}
else
if
(/^
#/.test(value)){
145.
value = value.replace(
'#'
,
''
);
146.
return
"#"
+ (value.length == 3 ? value.replace(/^(\w)(\w)(\w)$/,
'$1$1$2$2$3$3'
) : value);
147.
}
148.
return
value;
149.
}
150.
}
151.
return
value;
//如 0px
152.
}
153.
var
css =
function
(){
154.
var
a = arguments;
155.
if
(a.length == 1){
156.
return
getStyle(
this
,a[0])
157.
}
158.
}
159.
var
_ =
function
(el){
160.
var
el = isElement(el)? el :document.getElementById(el);
161.
var
gene = !el.constructor ? el : el.constructor.prototype;
162.
gene.css = css;
163.
gene.width =
function
(){
164.
return
getStyle(
this
,
"width"
);
165.
};
166.
gene.height =
function
(){
167.
return
getStyle(
this
,
"height"
);
168.
};
169.
return
el
170.
}
171.
if
(!window._){
//为了避免与JQuery的$发生冲突,我用_作为类库唯一的全局变量
172.
window[
'_'
] =_;
173.
}
174.
_.q = isQuirk;
175.
})()
用法如下:
1.
window.onload =
function
(){
2.
alert(_(
"ccc"
).css(
"background-color"
))
3.
alert(_(
"aaa"
).css(
"width"
))
4.
alert(_(document.body).width())
5.
};
我们可以用这个东西研究一下document.body与document.documentElement。
01.
function
text(){
02.
var
body = document.body,html = document.documentElement;
03.
_(
"w1"
).innerHTML = _(body).width();
04.
_(
"w2"
).innerHTML = _(html).width();
05.
_(
"h1"
).innerHTML = _(body).height();
06.
_(
"h2"
).innerHTML = _(html).height();
07.
_(
"ml1"
).innerHTML = _(body).css(
"margin-left"
);
08.
_(
"ml2"
).innerHTML = _(html).css(
"margin-left"
);
09.
_(
"mr1"
).innerHTML = _(body).css(
"margin-right"
);
10.
_(
"mr2"
).innerHTML = _(html).css(
"margin-right"
);
11.
_(
"mt1"
).innerHTML = _(body).css(
"margin-top"
);
12.
_(
"mt2"
).innerHTML = _(html).css(
"margin-top"
);
13.
_(
"mb1"
).innerHTML = _(body).css(
"margin-bottom"
);
14.
_(
"mb2"
).innerHTML = _(html).css(
"margin-bottom"
);
15.
_(
"pl1"
).innerHTML = _(body).css(
"padding-left"
);
16.
_(
"pl2"
).innerHTML = _(html).css(
"padding-left"
);
17.
_(
"pr1"
).innerHTML = _(body).css(
"padding-right"
);
18.
_(
"pr2"
).innerHTML = _(html).css(
"padding-right"
);
19.
_(
"bl1"
).innerHTML = _(body).css(
"border-left-width"
);
20.
_(
"bl2"
).innerHTML = _(html).css(
"border-left-width"
);
21.
_(
"br1"
).innerHTML = _(body).css(
"border-right-width"
);
22.
_(
"br2"
).innerHTML = _(html).css(
"border-right-width"
);
23.
_(
"qqq"
).innerHTML = !_.q ?
"标准模式"
:
"怪癖模式"
;
24.
_(
"t1"
).innerHTML = _(body).css(
"top"
);
25.
_(
"t2"
).innerHTML = _(html).css(
"top"
);
26.
_(
"l1"
).innerHTML = _(body).css(
"left"
);
27.
_(
"l2"
).innerHTML = _(html).css(
"left"
);
28.
_(
"ot1"
).innerHTML = body.offsetTop;
29.
_(
"ot2"
).innerHTML = html.offsetTop;
30.
_(
"ol1"
).innerHTML = body.offsetLeft;
31.
_(
"ol2"
).innerHTML = html.offsetLeft;
32.
_(
"ct1"
).innerHTML = body.clientTop;
33.
_(
"ct2"
).innerHTML = html.clientTop;
34.
_(
"cl1"
).innerHTML = body.clientLeft;
35.
_(
"cl2"
).innerHTML = html.clientLeft;
36.
_(
"cw1"
).innerHTML = body.clientWidth;
37.
_(
"cw2"
).innerHTML = html.clientWidth;
38.
_(
"ow1"
).innerHTML = body.offsetWidth;
39.
_(
"ow2"
).innerHTML = html.offsetWidth;
40.
_(
"sw1"
).innerHTML = body.scrollWidth;
41.
_(
"sw2"
).innerHTML = html.scrollWidth;
42.
}
在标准模式下,火狐等浏览器中我们看到offsetWidth等值最大为1007,因为火狐的offsetWidth不大于clientWidth,而clientWidth是不包含滚动条(滚动条的宽都固定为17px)。在IE中,offsetWidth是比clientWidth多了两个border,由此发现问题,1024-1003-17=4,4应该是两个auto生成,而这个auto应该为border的值,这两个border在IE中是固定死,不能通过以下手段修改。
1.
<
style
type
=
"text/css"
>
2.
html{
3.
border: 0;
4.
}
5.
</
style
>
换言之,在标准模式下,IE的html是存在不可修改的宽为2px的border。也换言之,我的程序是有个BUG,没有正确显示出html的border为2px,囧。
再看怪癖模式,
测试属性 | document.body | document.documentElement |
---|---|---|
width | 1024px | 1024px |
height | 604px | 604px |
margin-left | 0px | undefined |
margin-right | 0px | undefined |
margin-top | 0px | undefined |
margin-bottom | 0px | undefined |
padding-left | 0px | 0px |
padding-right | 0px | 0px |
border-left-width | 4px | 0px |
border-right-width | 4px | 0px |
渲染模式 | 怪癖模式 | |
top | 0 | 0 |
left | 0 | 0 |
offsetTop | 0 | 0 |
offsetLeft | 0 | 0 |
clientTop | 2 | 0 |
clientLeft | 2 | 0 |
offsetWidth | 1024 | 1024 |
clientWidth | 1003 | 0 |
scrollWidth | 1003 | 1024 |
火狐等没有所谓的怪癖模式,直接看IE的。发现那神秘的2px又出现,这时出现在document.body的clientTop,clientLeft中。那么怪癖模式下的document.body的clientTop,clientLeft又相当于CSS的什么概念呢?我们来看微软给出的一幅老图,那时IE5独步天下,没有所谓标准模式与怪癖模式之分,因此这幅图的东西都是按怪癖模式表示的。
不难看出,clientLeft相当于borderLeft,clientTop相当于borderTop。至于上面的border-left-width与border-right-width,就不要看了,是错误,因为我当初就没有考虑这两个元素在标准模式与怪癖模式下的问题。既然document.body的边框区就达1024px了,那么html元素的脸往哪里搁呢?!对不起,在微软早期的设想,body元素才是代表文档(一个强有力的证据是,在怪癖模式下,网页的滚动条是位于body元素中)。模准模式连同火狐那帮失败者宣扬的各种没有市场份额的“标准”,都是在微软极不情愿下支持的。你看,documentElement这样累赘傻气的名字像是微软起的吗?!如果是微软,它应该就叫html,和document.boy那样简洁。搞到在标准模式下,我们取scrollLeft,要用document.
来源:http://www.cnblogs.com/rubylouvre/archive/2009/09/08/1562212.html