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

Ext.Element.setXY 使用注意 bug in IE ?

阅读更多

有兴趣的可以在 ie ff 中分别执行这段代码 :

 

<!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>
<title>setXY bug</title>

<!--
<script type="text/javascript" src="ext-base.js"></script>
<script type="text/javascript" src="ext-core.js"></script>
-->
<script type="text/javascript" src="ext-core-3.0.js"></script>

</head>
<body>
	
	<div id="test1" style="position:relative;width:100px;height:100px;border:1px solid green;
padding:20px;">
	
		<div id="test2" style="position:absolute;width:50px;height:50px;margin:10px;
border:1px solid red;">
			
	</div>
	</div>
<script type="text/javascript">
//<![CDATA[
Ext.onReady(function(){
	alert("getBoundingClientRect of test2 : "+
document.getElementById('test2').getBoundingClientRect().left);
	alert("offsetLeft of test2 : "+document.getElementById('test2').offsetLeft);
	
	alert("getBoundingClientRect of test2's parent : "+
document.getElementById('test1').getBoundingClientRect().left);
	
	Ext.get('test2').setX(Ext.get('test2').getX());
	//if fixed by myself
	//Ext.get('test2').setX(Ext.get('test2').getX() - 
//parseInt(Ext.get('test2').getStyle("margin-left"),10));
	
	alert("after current getBoundingClientRect of test2 : "+
document.getElementById('test2').getBoundingClientRect().left);
});
//]]>

</script>

</body>
</html>


将得到的页面坐标再设置回去,ie元素位置却改变了。

 

分析:

 

以前的文章 也分析过,由于 ie 不能取得运行时的未显式设置的 left 值,于是 extjs 用offsetLeft 变通了一下,可是毕竟 offsetleft 和 left 还是不一样的 。


left 可能都比较熟悉了,有一点注意: css 2.1 规定偏移是以外边距边界而不是以内容边界。

 

关于 offsetleft


在元素 A 上读取 offsetLeft 属性时,必须按以下算法返回结果值:

   1. 如果元素 A 是 HTML 的 body 元素,其 display 属性计算值是 none,或者不具有 CSS 布局盒子,则返回 0,并停止本算法。
   2. 如果元素 A 的 offsetParent 是 null 或者是 HTML 的 body 元素,以 CSS 像素为单位返回元素 A 左边框距画布原点的水平距离,并停止本算法。
   3. 以 CSS 像素为单位返回元素 A 左 border edge 距其 offsetParent 左 padding edge 的距离。关于 border edge 与 padding edge 可见 css2.1 的相关定义

为了更好地理解,可以参照下图:


 


上图中,大块是小块的 offsetParent,红色是大块的边框,蓝色是小块的边框,蓝框外白色区域是大块的 padding 或/和 小块的 margin 或其他元素或其他原因造成的空白。offsetTop 是小块上边框上部与大块上边框下部的距离;offsetLeft 是小块左边框左部与大块左边框右部的距离。

 

则可见在例子中情况下  offsetLeft = left + margin-left


所以精确需要的话改动一下

 

<!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>
<title>setXY bug</title>


<script type="text/javascript" src="ext-base.js"></script>
<script type="text/javascript" src="ext-core.js"></script>

<!--
<script type="text/javascript" src="ext-core-3.0.js"></script>
-->
</head>
<body>
	
	<div id="test1" style="position:relative;width:100px;height:100px;
border:1px solid green;padding:20px;">
	
		<div id="test2" style="position:absolute;width:50px;height:50px;
margin:10px;border:1px solid red;">
			
	</div>
	</div>
<script type="text/javascript">
//<![CDATA[
Ext.onReady(function(){
	alert("getBoundingClientRect of test2 : "+
document.getElementById('test2').getBoundingClientRect().left);
	alert("offsetLeft of test2 : "+document.getElementById('test2').offsetLeft);
	
	alert("getBoundingClientRect of test2's parent : "+
document.getElementById('test1').getBoundingClientRect().left);
	if(!isNaN(parseInt(Ext.get('test2').getStyle("left"))))
		Ext.get('test2').setX(Ext.get('test2').getX());
	else
		Ext.get('test2').setX(Ext.get('test2').getX() - 
parseInt(Ext.get('test2').getStyle("margin-left"),10));
	
	alert("after current getBoundingClientRect of test2 : "+
document.getElementById('test2').getBoundingClientRect().left);
});
//]]>

</script>

</body>
</html>

 

 

PS:

 

其实对于任何不能得到精确用户未设置left数值的浏览器都存在ie中的情况。(现代的标准浏览器可以避免),进一步发散来讲,这就涉及了 ie 下取得css属性像素值的问题 。另外还有

关于 setXY 的一点剖析 ,特别对于以html为包含块的情况。

 

 

已提交 extjs 官方bug报告。

 

 

  • 大小: 2 KB
分享到:
评论
1 楼 lchj 2009-07-03  
以前我都是这么干的:
	var xy = inputel.getXY();
	date.style.top=0;
	date.style.left=0;
	date.setXY([xy[0]+1,xy[1]-1]);

相关推荐

    EXTJS总结.txt

    // 返回下一个侧边节点,但一定要是div的,找到就返回,类型是Ext.Element Ext.fly('elId').next("div"); 27.prev 获取上一个侧边节点,跳过文本节点。可选地可送入一个期待的选择符。 // 返回上一个侧边节点,...

    C++对象和指针的引用

    在实际中,使用对象引用作函数参数要比使用对象指针作函数更普遍,这是因为使用对象引用作函数参数具有用对象指针作函数参数的优点,而用对象引用作函数参数将更简单,更直接。所以,在C++编程中,人们喜欢用对象...

    logo:用C编码的徽标命令解释器

    setxy,打印,st,ht,干净 汇编 全部:runMe runMe:绘图.o操作.o维护.o动作.o计算.o内存.o main.o gcc绘图.o操作.o维护.o动作.o计算.o内存.o main.o -o bin / runMe -导致-lm -Iinclude drawing.o:src / ...

    php 直接生成PDF的 类

    用法: ... $pdf = new PDF_Chinese('P', 'mm', 'A4');...$pdf-&gt;SetXY($dycs['xm12'][0], $dycs['xm12'][1]); $len = strlen($xm12); $pdf-&gt;Cell($len, 14, $xm12); //打印输出 $pdf-&gt;Output();

    logo-svg:基于徽标(语言)的SVG编码器

    放弃使用徽标解析器的支持SVG的分支! SVG.js的最小徽标命令集: 前进/后退落后左/左右/右SETX,SETY,SETXY 重复n [...] 至FOO:ARG1:ARG2 BODY END 计划: 重启家清除屏幕/清除/ CS 颜色[rgb] MAKE“ X 1(将:X...

    basic-badge:2018 Hackaday贝尔格莱德硬件徽章

    请参见标准字词: print println if else goto gosub return for next end let rem徽章定制词led X,Y控制LED,X [0..2] RGB,Y [0..1]开/关tune A,B,C,D在持续时间D播放音调A,B,C clrscr清晰画面setxy X,...

    VC GDI练习编写的苹果机游戏.rar

     void SetXY();//设置图片旋转  void setCurrentPos(int);//设置当前的位置  void KeyDownF1();//按下F1时触发  bool getIntarrayIndes(int);//获得当前要旋转的数  int GetEndPos();//获得结束位置  int ...

    易语言七彩异形效果

    易语言七彩异形效果源码,七彩异形效果,generateTriangles,createQuad,loop,updateTriangles,renderTriangles,requestAnimationFrame,create,getX,getY,setX,setY,setXY,getLength,setLength,getAngle,atan2,setAngle...

    贪吃蛇源代码

    void setXy(int x, int y);//获取窗口坐标 void updateScore();//更新分数 int delay = 0;//延迟 int eatFlag = 0;//吃了目标点的标记,默认为没有吃,吃了为1 int state = 1;//判断蛇状态的标记, 如果state==0,...

Global site tag (gtag.js) - Google Analytics