您好,欢迎访问一九零五行业门户网

javascript 精确获取样式属性(下)_javascript技巧

复制代码 代码如下:
var rgb2hex = function(rgb) {
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
return #+tohex(rgb[1])+tohex(rgb[2])+tohex(rgb[3])
}
var tohex = function(x) {
var hexdigits = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
return isnan(x) ? '00' : hexdigits[(x - x % 16) / 16] + hexdigits[x % 16];
}
我们用正则表达式在检测其是否为rgb格式,是就用rgb2hex来转换它。但如果是red,green等值呢,火狐就一反常态,转换为hex格式,但ie依然如故。我们没有办法,自己做一个哈希,把常用的颜色都弄进去,然后一一匹对便是。
复制代码 代码如下:
if(style.search(/background|color/) != -1) {
var color = {
aqua: '#0ff',
black: '#000',
blue: '#00f',
gray: '#808080',
purple: '#800080',
fuchsia: '#f0f',
green: '#008000',
lime: '#0f0',
maroon: '#800000',
navy: '#000080',
olive: '#808000',
orange:'#ffa500',
red: '#f00',
silver: '#c0c0c0',
teal: '#008080',
transparent:'rgba(0,0,0,0)',
white: '#fff',
yellow: '#ff0'
}
if(!!color[value]){
value = color[value]
}
if(value == inherit){
return getstyle(el.parentnode,style);
}
if(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(value)){
return rgb2hex(value)
}else if(/^#/.test(value)){
value = value.replace('#', '');
return # + (value.length == 3 ? value.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : value);
}
return value;
}
基本上是对于css的精确取值就是这样,显然它还存在许多不足之处,但对于布局用的和常用的样式都实现了。还提供了一个判断页面渲染模式的常数q,为了方便,方法名与jquery同名(只能取值,不能赋值,以后有空慢慢与我的addsheet函数整合到一起)。
复制代码 代码如下:
(function(){
var isquirk = (document.documentmode) ? (document.documentmode==5) ? true : false : ((document.compatmode==css1compat) ? false : true);
var iselement = function(el) {
return !!(el && el.nodetype == 1);
}
var propcache = [];
var propfloat = !+\v1 ? 'stylefloat' : 'cssfloat';
var camelize = function(attr){
return attr.replace(/\-(\w)/g, function(all, letter){
return letter.touppercase();
});
}
var memorize = function(prop) { //意思为:check out form cache
return propcache[prop] || (propcache[prop] = prop == 'float' ? propfloat : camelize(prop));
}
var getieopacity = function(el){
var filter;
if(!!window.xdomainrequest){
filter = el.style.filter.match(/progid:dximagetransform.microsoft.alpha\(.?opacity=(.*).?\)/i);
}else{
filter = el.style.filter.match(/alpha\(opacity=(.*)\)/i);
}
if(filter){
var value = parsefloat(filter[1]);
if (!isnan(value)) {
return value ? value / 100 : 0;
}
}
return 1;
}
var convertpixelvalue = function(el, value){
var style = el.style,left = style.left,rsleft = el.runtimestyle.left;
el.runtimestyle.left = el.currentstyle.left;
style.left = value || 0;
var px = style.pixelleft;
style.left = left;//还原数据
el.runtimestyle.left = rsleft;//还原数据
return px + px
}
var rgb2hex = function(rgb) {
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
return #+tohex(rgb[1])+tohex(rgb[2])+tohex(rgb[3])
}
var tohex = function(x) {
var hexdigits = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
return isnan(x) ? '00' : hexdigits[(x - x % 16) / 16] + hexdigits[x % 16];
}
var getstyle = function (el, style){
var value;
if(!+\v1){
//特殊处理ie的opacity
if(style == opacity){
return getieopacity(el)
}
value = el.currentstyle[memorize(style)];
//特殊处理ie的height与width
if (/^(height|width)$/.test(style)){
var values = (style == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
if(isquirk){
return el[camelize(offset-+style)] + px
}else{
var client = parsefloat(el[camelize(client-+style)]),
paddinga = parsefloat(getstyle(el, padding-+ values[0])),
paddingb = parsefloat(getstyle(el, padding-+ values[1]));
return (client - paddinga - paddingb)+px;
}
}
}else{
if(style == float){
style = propfloat;
}
value = document.defaultview.getcomputedstyle(el, null).getpropertyvalue(style)
}
//下面部分全部用来转换上面得出的非精确值
if(!/^\d+px$/.test(value)){
//转换可度量的值
if(/(em|pt|mm|cm|pc|in|ex|rem|vw|vh|vm|ch|gr)$/.test(value)){
return convertpixelvalue(el,value);
}
//转换百分比,不包括字体
if(/%$/.test(value) && style != font-size){
return parsefloat(getstyle(el.parentnode,width)) * parsefloat(value) /100 + px
}
//转换border的thin medium thick
if(/^(border).+(width)$/.test(style)){
var s = style.replace(width,style),
b = {
thin:[1px,2px],
medium:[3px,4px],
thick:[5px,6px]
};
if(value == medium && getstyle(el,s) == none){
return 0px;
}
return !!window.xdomainrequest ? b[value][0] : b[value][1];
}
//转换margin的auto
if(/^(margin).+/.test(style) && value == auto){
var father = el.parentnode;
if(/msie 6/.test(navigator.useragent) && getstyle(father,text-align) == center){
var fatherwidth = parsefloat(getstyle(father,width)),
_temp = getstyle(father,position);
father.runtimestyle.postion = relative;
var offsetwidth = el.offsetwidth;
father.runtimestyle.postion = _temp;
return (fatherwidth - offsetwidth)/2 + px;
}
return 0px;
}
//转换top|left|right|bottom的auto
if(/(top|left|right|bottom)/.test(style) && value == auto){
return el.getboundingclientrect()[style];
}
//转换颜色
if(style.search(/background|color/) != -1) {
var color = {
aqua: '#0ff',
black: '#000',
blue: '#00f',
gray: '#808080',
purple: '#800080',
fuchsia: '#f0f',
green: '#008000',
lime: '#0f0',
maroon: '#800000',
navy: '#000080',
olive: '#808000',
orange:'#ffa500',
red: '#f00',
silver: '#c0c0c0',
teal: '#008080',
transparent:'rgba(0,0,0,0)',
white: '#fff',
yellow: '#ff0'
}
if(!!color[value]){
value = color[value]
}
if(value == inherit){
return getstyle(el.parentnode,style);
}
if(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(value)){
return rgb2hex(value)
}else if(/^#/.test(value)){
value = value.replace('#', '');
return # + (value.length == 3 ? value.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : value);
}
return value;
}
}
return value;//如 0px
}
var css = function(){
var a = arguments;
if(a.length == 1){
return getstyle(this,a[0])
}
}
var _ = function(el){
var el = iselement(el)? el :document.getelementbyid(el);
var gene = !el.constructor ? el : el.constructor.prototype;
gene.css = css;
gene.width = function(){
return getstyle(this,width);
};
gene.height = function(){
return getstyle(this,height);
};
return el
}
if(!window._){ //为了避免与jquery的$发生冲突,我用_作为类库唯一的全局变量
window['_'] =_;
}
_.q = isquirk;
})()
用法如下:
复制代码 代码如下:
window.onload = function(){
alert(_(ccc).css(background-color))
alert(_(aaa).css(width))
alert(_(document.body).width())
};
我们可以用这个东西研究一下document.body与document.documentelement。
复制代码 代码如下:
function text(){
var body = document.body,html = document.documentelement;
_(w1).innerhtml = _(body).width();
_(w2).innerhtml = _(html).width();
_(h1).innerhtml = _(body).height();
_(h2).innerhtml = _(html).height();
_(ml1).innerhtml = _(body).css(margin-left);
_(ml2).innerhtml = _(html).css(margin-left);
_(mr1).innerhtml = _(body).css(margin-right);
_(mr2).innerhtml = _(html).css(margin-right);
_(mt1).innerhtml = _(body).css(margin-top);
_(mt2).innerhtml = _(html).css(margin-top);
_(mb1).innerhtml = _(body).css(margin-bottom);
_(mb2).innerhtml = _(html).css(margin-bottom);
_(pl1).innerhtml = _(body).css(padding-left);
_(pl2).innerhtml = _(html).css(padding-left);
_(pr1).innerhtml = _(body).css(padding-right);
_(pr2).innerhtml = _(html).css(padding-right);
_(bl1).innerhtml = _(body).css(border-left-width);
_(bl2).innerhtml = _(html).css(border-left-width);
_(br1).innerhtml = _(body).css(border-right-width);
_(br2).innerhtml = _(html).css(border-right-width);
_(qqq).innerhtml = !_.q ? 标准模式 : 怪癖模式;
_(t1).innerhtml = _(body).css(top);
_(t2).innerhtml = _(html).css(top);
_(l1).innerhtml = _(body).css(left);
_(l2).innerhtml = _(html).css(left);
_(ot1).innerhtml = body.offsettop;
_(ot2).innerhtml = html.offsettop;
_(ol1).innerhtml = body.offsetleft;
_(ol2).innerhtml = html.offsetleft;
_(ct1).innerhtml = body.clienttop;
_(ct2).innerhtml = html.clienttop;
_(cl1).innerhtml = body.clientleft;
_(cl2).innerhtml = html.clientleft;
_(cw1).innerhtml = body.clientwidth;
_(cw2).innerhtml = html.clientwidth;
_(ow1).innerhtml = body.offsetwidth;
_(ow2).innerhtml = html.offsetwidth;
_(sw1).innerhtml = body.scrollwidth;
_(sw2).innerhtml = html.scrollwidth;
}
精确取值测试属性document.bodydocument.documentelement width
height
margin-left
margin-right
margin-top
margin-bottom
padding-left
padding-right
border-left-width
border-right-width
渲染模式
top
left
offsettop
offsetleft
clienttop
clientleft
offsetwidth
clientwidth
scrollwidth
运行代码
[ctrl+a 全选 注:如需引入外部js需刷新才能执行]
在标准模式下,火狐等浏览器中我们看到offsetwidth等值最大为1007,因为火狐的offsetwidth不大于clientwidth,而clientwidth是不包含滚动条(滚动条的宽都固定为17px)。在ie中,offsetwidth是比clientwidth多了两个border,由此发现问题,1024-1003-17=4,4应该是两个auto生成,而这个auto应该为border的值,这两个border在ie中是固定死,不能通过以下手段修改。
复制代码 代码如下:
换言之,在标准模式下,ie的html是存在不可修改的宽为2px的border。也换言之,我的程序是有个bug,没有正确显示出html的border为2px,囧。
再看怪癖模式,
火狐等没有所谓的怪癖模式,直接看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.documentelement.scrollleft,因为这时body不存在滚动条;在怪癖模式下,要用document.body,虽然微软以打补丁的方法添加上document.documentelement(真拗口,难怪网景会失败),但滚动条的位置不是说变就变。
http://www.jb51.net/article/21719.htm
其它类似信息

推荐信息