`
yiminghe
  • 浏览: 1465390 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

IE 取得css属性的绝对像素值

阅读更多

问题:

由于 css 属性单位可以设置为 em ,以及 % 来达到流体布局以及弹性布局的效果,但是当 javascript 操作这些元素进行运算时,一般要转换为绝对数值进行运算,比如 offsetWidth ,offsetHeight ,但是不是所有的css属性(padding,margin)都对应上述可以得到直接数值的属性,w3c 规范说明可以使用

 

document.defaultView.getComputedStyle(element,null).getPropertyValue(property);

 来获得相应 css property 的像素绝对值(也不是完美的,存在缩写属性读取问题 ),而 ie 则完全没有办法 ,

 

element.currentStyle.property

 只能获得用户指定的原始css 属性,比如 4em 或 20%,没有设置则为 auto


解决:


Dean Edwards 提出了针对 ie 的处理方式,利用了生僻的ie特有元素属性  runtimeStyle (运行时样式,比style优先级更高, 设置runtimestyle后再修改style对应属性,UI不会有对应变化) ,以及 style 某些属性相应的 pixel 属性,获取到了任意css 属性有效单元的运行时绝对像素数值。

 

From Secrets of the javacript ninja :

 

.runtimeStyle is analogous to .style with one exception: Any style properties set using
.runtimeStyle.prop will override .style.prop (which still leaving the value contained in
.style.prop intact).

.pixelLeft (and Top, Bottom, Right, Height, and Width) are properties for directly accessing the pixel
value of the respective CSS properties. (Note: These could be used as alternatives to even using Dean
Edwards' technique in the first place for these properties - Dean's technique is more useful for things like
font-size, line-height, etc.).

The technique works by setting the current computed left to the runtime left ('left' is chosen arbitrarily
- it could also work with top, right, etc.) - this will keep the positioning of the element intact while we
compute the pixel value. The pixel value is computed by setting the .style.left and then reading the
resulting pixel value out using .style.pixelLeft.

Dean's technique isn't perfect - especially when attempting to handle percentages on elements that are
a child of the body element (they end up expanding to consume a large portion of the document - 10%
becomes 200px, for example) but it ends up working well enough to handle most of the common use cases.

 


演示@google code



核心代码

 

var PIXEL = /^\d+(px)?$/i;
			function getPixelValue(element, value) {
				if (PIXEL.test(value)) return parseInt(value);
				var style = element.style.left;
				var runtimeStyle = element.runtimeStyle.left;
				element.runtimeStyle.left = element.currentStyle.left;
				element.style.left = value || 0;
				value = element.style.pixelLeft;
				element.style.left = style;
				element.runtimeStyle.left = runtimeStyle;
				return value;
			};

 

 

YUI3 解决:

 

dom-style-debug.js


相当于模拟实现了标准浏览器原生的GET_COMPUTED_STYLE:

 

if (!Y.config.win[GET_COMPUTED_STYLE]) {
    Y.DOM[GET_COMPUTED_STYLE] = ComputedStyle.get; 
}
 

对于 width,height的数值获取采用 offsetWidth 减去 padding和边框的数值 ,而边框,padding,margin以及其他属性的数值则用上述的pixel方法获取。

 

IEComputed[WIDTH] = IEComputed[HEIGHT] = ComputedStyle.getOffset;

IEComputed[BORDER_WIDTH] = IEComputed[BORDER_TOP_WIDTH] = IEComputed[BORDER_RIGHT_WIDTH] =
        IEComputed[BORDER_BOTTOM_WIDTH] = IEComputed[BORDER_LEFT_WIDTH] =
        ComputedStyle.getBorderWidth;

IEComputed.marginTop = IEComputed.marginRight = IEComputed.marginBottom =
        IEComputed.marginLeft = ComputedStyle.getMargin;
 

 

注意: width,height 不能统一用 getPixelValue 来获取数值,width,height似乎有问题(为什么啊??pixelleft不能代表?),所以 yui3 区别判断用了offsetXX ,jquery也存在这个问题:(kissy 和 yui3 保持一致

 

<style>
	#t {
		width:80%;
		position:relative;
		left:80%;
	}
	</style>
<div id="t">
</div>
<script src="http://kissy.googlecode.com/svn/trunk/build/packages/ks-core.js"></script>
<script src="http://kissy.googlecode.com/svn/trunk/build/node/node-pkg-min.js"></script>
	
	
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" charset="utf-8"
        src="http://yui.yahooapis.com/3.1.1/build/yui/yui-min.js">
</script>
<script src="http://www.sencha.com/products/core/manual/js/ext-base.js"></script> 
<script src="http://www.sencha.com/products/core/manual/js/extjs.js"></script> 
<script>
	YUI().use("node",function(Y){
	
	var s=KISSY;
		
		alert(s.one("#t").css("width"));
		alert(s.one("#t")[0].offsetWidth);
		alert(Y.one("#t").getStyle("width"));
		alert(Ext.get("t").getStyle("width"));
		alert("jquery : "+$("#t").css("width"));
});
</script>
 

 

 

 

ps:IE color问题

 

同样的,如果color设置为red,black等字符数值,则标准兼容浏览器可以使用getComputedStyle得到16进制数值,而ie则会取得字符串值,dean同样给出了ie专用的方法,利用IE专有的queryCommandValue ?

 

function toHex(color) {
  var body  = createPopup().document.body,
      range = body.createTextRange();
  body.style.color = color;
  var value = range.queryCommandValue("ForeColor");
  value = ((value & 0x0000ff) << 16) | (value & 0x00ff00) | ((value & 0xff0000) >>> 16);
  value = value.toString(16);
  return "#000000".slice(0, 7 - value.length) + value;
};
 

PS: IE 绝对定位 left(top) 问题

 

当元素为绝对定位且不设置left(top)时,ie 使用 currentStyle 取得为 auto,而我们如果使用上述的 pixelLeft可以得到为0,但是实际上由于left是和其相对定位的祖先有关,即使不设置也不为0的,在标准浏览器中可用 getComputedStyle 计算取得,或许有些库使用 offsetLeft 来代替 left ,实际上这是不对的,详见:Ext.Element.setXY 使用注意 bug in IE ? 。KISSY 中对这个问题特殊处理,使用 offsetLeft - margin-left

 

// getComputedStyle for IE
var RE_SPECIAL = /^auto$/i,
    RE_WH = /^width|height$/i,
    RE_LEFT = /^left$/i,
    POSITION = "position";
if (! (doc.defaultView || {}).getComputedStyle && docElem[CURRENT_STYLE]) {
    DOM._getComputedStyle = function (elem, name) {
        var style = elem.style,
            ret = elem[CURRENT_STYLE][name];
        if (RE_SPECIAL.test(ret) && RE_LEFT.test(name)) {
            var position = DOM.css(elem, POSITION);
            //absolute: auto == offsetLeft - margin-left
            if (position == "absolute") ret = elem.offsetLeft - parseInt(DOM.css(elem, "margin-left"));
            //relative: auto ==0
            else ret = 0;
        }....
    }
}
 

 

分享到:
评论
3 楼 sp42 2014-02-23  
for ie8 可以通过 offsetHeight 获取,
for ie7,要使元素大小发生变化,才能获取,如下例,要获取 父级 td 元素 的 高度,怎么获取绝对像素值?
//导入iframe时获取高度并适应
function iFrameHeight(ifm) {  
	if(window.navigator.isFF || window.navigator.isIE8)
		ifm.height  = document.getElementById('tdtd').offsetHeight;
	
	if(window.navigator.isIE7){
		// ie6, ie7 不能通过 offsetHeight 来直接获取绝对的高度,getComputed() 也是返回 ifm.style.height ="auto",于是……
		document.getElementById('tdtd').height = "100%";
		ifm.height  = document.getElementById('tdtd').offsetHeight - 30;
		document.getElementById('tdtd').height = "";
	}
}


只是一个思路。
2 楼 yiminghe 2012-10-12  
hunter3721 写道
@yiminghe:
您认为设置runtimeStyle的目的在于“设置runtimestyle后再修改style对应属性,UI不会有对应变化”
结合您给出的DE的原始代码来看,这个解释可以说得通
但Jquery1.5之后,代码里这里有一点细节变动
导致这个解释有一个无法自圆其说的地方
详见我的一篇blog: http://hunter3721.iteye.com/blog/1697054

我还注意到kissy的源码里,此处的代码是和最新的JQ保持一致的
所以希望yiminghe能帮忙解释一下我的疑惑~


有意思,我都忘了,有空看看答复你
1 楼 hunter3721 2012-10-12  
@yiminghe:
您认为设置runtimeStyle的目的在于“设置runtimestyle后再修改style对应属性,UI不会有对应变化”
结合您给出的DE的原始代码来看,这个解释可以说得通
但Jquery1.5之后,代码里这里有一点细节变动
导致这个解释有一个无法自圆其说的地方
详见我的一篇blog: http://hunter3721.iteye.com/blog/1697054

我还注意到kissy的源码里,此处的代码是和最新的JQ保持一致的
所以希望yiminghe能帮忙解释一下我的疑惑~

相关推荐

    ie-css3.htc 免费版

    《IE浏览器支持CSS3属性:ie-css3.htc详解》 在互联网技术发展的历程中,CSS3作为一种强大的样式表语言,极大地丰富了网页设计的可能性,提供了诸如圆角、阴影、渐变等美观效果。然而,早期版本的Internet Explorer...

    ie-css3(让ie6 ie7 ue8支持css3).rar

    4. **ie-css3.htc**:这个文件很可能包含了一组JavaScript代码,当被引用到CSS中时,可以让旧版IE识别并实现某些CSS3属性。例如,它可能提供了模拟圆角、阴影或透明度等功能的方法。 5. **使用方法**:通常,开发者...

    css属性列表_和_属性值含义

    CSS 属性列表和属性值含义 CSS 属性列表和属性值含义是指在 CSS 样式表中使用的各种属性和它们的可能取值。了解这些属性和它们的含义是掌握 CSS 样式表编写的关键。 媒体类型(Media) CSS 样式表可以作用于多种...

    批量输出 CSS background-position 属性的定位像素值

    总结来说,批量输出CSS `background-position`属性的定位像素值是一个涉及到CSS理解、单位转换和自动化处理的技术任务。通过适当的工具和技术,你可以高效地统一和优化大量元素的背景图像位置,提高工作效率,并确保...

    让IE6、IE7、IE8支持CSS3的圆角、阴影样式

    然而,由于IE6-IE8不支持这些CSS3属性,我们需要采用一些替代方法来实现类似的效果。以下是一些常见的解决方案: 1. **使用JavaScript库**:比如`jQuery Corner`或`CSS3 PIE`( Positioned Interactive Elements)...

    ie兼容Css3属性

    "ie兼容Css3属性"这一主题主要关注如何使IE浏览器支持那些原本不被其完全支持的CSS3特性。 PIE,全称为“Position: absolute; !important; Expression;”,是一个JavaScript和VBScript混合的解决方案,主要用于解决...

    解决ie9、ie10本地css加载不上的解决方法实例

    Internet Explorer(IE)作为曾经的主流浏览器,尤其在IE9和IE10版本上,开发者常常会遇到CSS(层叠样式表)加载不上的问题。这主要是由于IE9和IE10对某些CSS特性支持不足以及对文件加载机制的差异导致的。本篇将...

    让ie也支持css3

    然而,由于历史原因,Internet Explorer(IE)浏览器对CSS3的支持相对滞后,尤其是旧版本。针对这种情况,开发者们采取了一些策略来解决IE浏览器的兼容性问题,其中之一就是使用"行为"(Behavior)特性。 【标题】...

    CSS属性兼容性对照表

    资源名称:CSS 属性兼容性对照表内容简介: CSS属性兼容性对照表 PDF,主要是列出一些CSS2.0/CSS2.1在各个版本的IE、火狐等主流浏览器下的兼容支持问题,此表有助于以后书写出全兼容的WEB标准化网页打下基础,前端...

    IE6, IE7, IE8 CSS 兼容速查表

    9. **CSS3属性兼容**:IE8及以下版本对CSS3新特性支持有限,如圆角、阴影、渐变等,需要借助于JavaScript库(如Modernizr)或渐进增强策略来实现。 10. **CSS Expression**:IE6和7支持CSS表达式,但这种动态计算...

    CSS属性、浏览器兼容与网页布局

    CSS属性、浏览器兼容与网页布局CSS属性、浏览器兼容与网页布局CSS属性、浏览器兼容与网页布局CSS属性、浏览器兼容与网页布局CSS属性、浏览器兼容与网页布局CSS属性、浏览器兼容与网页布局CSS属性、浏览器兼容与网页...

    ie-css3.htc(内有使用方法).rar

    在不支持此属性的旧版IE中,"ie-css3.htc"通过JavaScript和VML(Vector Markup Language,微软的一种矢量图形语言)来模拟这个效果,使元素的边角变得圆润。 2. **CSS3阴影(box-shadow)**:`box-shadow`属性则为...

    ie支持css3部分功能

    然而,IE(Internet Explorer)浏览器,特别是早期版本,对CSS3的支持并不完全,这使得开发者在创建跨浏览器兼容的网站时面临挑战。本文将详细探讨如何使IE支持CSS3的部分功能,包括阴影背景效果、圆角效果和渐变...

    css属性继承

    例如,在IE8及更早版本中,某些CSS属性(如`text-align`)在某些情况下可能无法正确地继承。这可能会导致布局上的不一致或预期之外的行为。因此,在进行跨浏览器开发时,应特别注意测试并解决这类兼容性问题。 ####...

    移除html元素的某个css属性

    3. **继承性**:某些CSS属性具有继承性,这意味着即使当前元素的属性值被设置为空,它仍然可能继承父元素的样式值。 4. **内联样式的优先级**:内联样式(即直接写在HTML标签中的style属性)具有较高的优先级,因此...

    让ie兼容css选择器

    ie7.js是一个由Dean Edwards开发的JavaScript库,它主要目的是让IE6和IE7支持一些CSS2.1及部分CSS3选择器,如类选择器(.class)、伪类(:hover、:focus等)和属性选择器([attr=value])。ie7.js通过动态创建DOM...

    IE不支持的集中css

    【描述】中提到的是一些在IE浏览器,特别是IE6中不受支持的CSS属性。了解这些属性对于优化IE兼容性具有重要意义,可以帮助开发者更有针对性地编写CSS和使用Hack。 【标签】:“IE不支持的集中css” 以下是对这些不...

    DIV+CSS相对IE6、IE7和IE8的兼容问题

    标题和描述均提到了“DIV+CSS相对IE6、IE7和IE8的兼容问题”,这揭示了在Web开发中,尤其是针对老旧浏览器如IE6、IE7和IE8进行CSS布局时,开发者可能遇到的一系列挑战。这些浏览器在解析CSS规则时存在独特的行为,...

    CSS 绝对定位属性absolute用法初探

    本文将深入探讨CSS绝对定位属性`absolute`的用法,并提供实例来帮助理解。 首先,理解`position`属性是至关重要的。这个属性决定了元素如何在页面上定位。当`position`的值设为`absolute`时,元素就进入了绝对定位...

    css属性值.rar

    本资料包"css属性值.rar"显然是一个关于CSS属性值的学习资源,包含了一份详细的文档"css属性值.doc",可能涵盖了各种CSS属性的详细解释和示例,以及一个链接"A5下载- 更全的站长资源平台.url",可能是提供更多相关...

Global site tag (gtag.js) - Google Analytics