`
hunter3721
  • 浏览: 1272 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

JQuery中使用DE的绝对像素值hack的一处疑问

阅读更多

本篇主要记录一下昨天和同事对JQ里取绝对像素值时对runTimeStyle的一处细节的讨论,同时提出自己的一些疑问。

 

疑问

最近我的同事 小卡 在整合jquery代码的时候,对JQuery里IE下取精确像素值的部分提出了一些疑问

 

下面的代码片段来自jquery-1.8.2.js

 

 

currentStyle = function( elem, name ) {
	var left, rsLeft, uncomputed,
		ret = elem.currentStyle && elem.currentStyle[ name ],
		style = elem.style;

	// Avoid setting ret to empty string here
	// so we don't default to auto
	if ( ret == null && style && (uncomputed = style[ name ]) ) {
		ret = uncomputed;
	}

	// From the awesome hack by Dean Edwards
	// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291

	// If we're not dealing with a regular pixel number
	// but a number that has a weird ending, we need to convert it to pixels
	if ( rnumnonpx.test( ret ) ) {

		// Remember the original values
		//①
		left = style.left;
		rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;

		// Put in the new values to get a computed value out
		//②
		if ( rsLeft ) {
			elem.runtimeStyle.left = elem.currentStyle.left;
		}
		//③
		style.left = name === "fontSize" ? "1em" : ret;
		ret = style.pixelLeft + "px";

		// Revert the changed values
		//④
		style.left = left;
		if ( rsLeft ) {
			elem.runtimeStyle.left = rsLeft;
		}
	}

	return ret === "" ? "auto" : ret;
};
 

 

 

主要是代码段②这里

 

		// Put in the new values to get a computed value out
		if ( rsLeft ) {
			elem.runtimeStyle.left = elem.currentStyle.left; //疑问!
		} 
 

 疑问:这一句到底是干啥用的?

 小卡试过 将这段去掉,在IE6/7/8/9里均不影响最终结果,即使runtimeStyle已经被人为设置过

 

解释?

我以前看JQ的时候也对DE的这段代码有过疑问,所以我按照那时候的理解给出的解释:

runtimeStyle是运行时样式,优先级最高
  • 当runtimeStyle有值的时候,元素实际渲染总是以此为准,此时:
      - 若用js取currentStyle的值时,引擎会返回runtimeStyle的值
      - 若去设置style,元素的实际渲染不会发生变化的,因为style优先级很低,已经不作数了
  • 当runtimeStyle的值不存在或者被清空(赋值''就是清空)时,元素的渲染以currentStyle为准。此时:
  - 用js取currentStyle的值,就按照currentStyle自己的规则得到值。(currentStyle取值按照import-style,inline-style,HTML Attribute,HTML default根据样式优先级决定)
  - 若去设置style,则有可能改变元素的渲染
 
所以结合JQ的代码来看: 
①是备份style和runtimeStyle(因为后面需要还原)
②是一个必要的副作用消除步骤,因为接下来要通过设置style来取像素值,这里给最高优先级的runtimeStyle设置currentStyle,就能保证下面的过程不改变渲染
③是通过设置style.left然后再通过pixelLeft取像素值的过程
④是还原现场的过程

  

 但 herbert 提出了质疑:

写道
如果runtimeStyle存在的话,currentStyle的值一定是runtimeStyle的值,这里赋值的意义何在?

 

 我回过头看了一下上面的代码,发现还真是这么回事。

if ( rsLeft ) {
	//进了这个if,说明runtimeStyle.left有值
	//当runtimeStyle.left有值时, currentStyle.left的值取出来就是runtimeStyle.left的值
	//那下面这句赋值确实无意义啊!囧囧囧~~
	elem.runtimeStyle.left = elem.currentStyle.left;
}
 

 为啥我以前研究这里的时候,没发现这个悖论呢?

 

溯源-反省 

去找了下源头

 

 

 发现DE原始的代码里并无此判断

 

 然后又翻了一下1.4的JQ,发现里面也是没有这句判断。

 发现是1.5版本才增加的这个判断。

 

 那么到底JQ里为啥要增加这句判断呢?

 去Github看下history,发现2011年1月5号之前,源码里也是没有这个判断的

 直到rwldrn一个针对opera的bugfix
  

 
 可以看到,这里是为了规避opera抛出异常,所以加了一句判断。
 
 看到这里,只有两种可能性了:
  A. 我之前的理解是错误的,这里并非为了担心下面对style.left赋值导致UI改变才写了这句话,而是有其他我暂未想到的原因
  B. 我之前的理解是正确的,rwldrn的这个fix虽然规避了异常,但无意间使得对runtimeStyle的设置和恢复的代码,在常规情况下都不会进入了
 
  那个可能性更大?
  rwldrn提交了一个有副作用的fix(尽管可以看到,这个副作用不大),而这个错误在接下来的2年里,在无数人review的JQuery项目里,都未被发现?
 
  所以我更倾向于我的理解是错误的。
 

到底咋解释?

 再看一遍runTimeStyle的资料
 仍然没有思路
 
 在网上找了一圈下来,发现大部分的理解和我基本相同
 除了 franky这篇
 
...

其中要提的是 element.runtimeStyle 为什么这里也把他临时覆盖了呢? 可能是出于 保险。比如 其他代码中可能更改了此值 因为 runtimeStyle的优先级 要高越style... 所以为了pixelLeft取出正确的值 所以 也覆盖了element.runtimeStyle.

...
 
 franky的这个猜测,倒是和我的理解不同,但他的博文较早了,当时也仍然是基于没有那句if的讨论,所以当时看来也说得通
 但现在jq里加上那句if后,这个解释仍然无法规避同样的悖论
 
 实在想不出什么靠谱的解释了。。。
 只能先上来po一篇博文,留待以后研究后补充结论。
 也欢迎大神们来这里讨论~~
 

相关资料

汇总在这里(持续补充),供参考:
 
来源:
http://erik.eae.net/archives/2007/07/27/18.54.15/
两篇相关的中文blog:
http://yiminghe.iteye.com/blog/511589
http://www.cnblogs.com/_franky/archive/2009/11/29/1612969.html
runtimeStyle属性的介绍:
http://help.dottoro.com/ljhddfwr.php


  
  • 大小: 94.5 KB
  • 大小: 37.3 KB
分享到:
评论
2 楼 hunter3721 2012-11-09  
I have already pulled a request here:
https://github.com/jquery/jquery/pull/1026
1 楼 司徒正美 2012-11-09  
这两个 if ( rsLeft ) {  直接去掉就行了
以前jQuery使用非A即B的方式,导致opera错误跑到currentStyle分支下
现在既然不会跑到这里,那就没用了

相关推荐

    jQuery1.12.4+jQuery中文手册.rar

    1. **选择器**:jQuery提供了丰富的CSS选择器,如`$("#id")`用于选取ID为指定值的元素,`$(".class")`用于选取具有特定类的元素,`$("tagname")`则用于选取所有指定标签名的元素。 2. **DOM操作**:`$(selector)....

    jQuery实现获取元素索引值index的方法

    在使用jQuery进行前端开发时,我们常常需要获取元素在集合中的索引值以便进行进一步的操作。jQuery作为一个强大的JavaScript库,提供了一系列方法来简化DOM操作,其中“.index()”方法便是用于获取元素索引值的一种...

    JQuery UI 中文帮助文档

    4. **配置选项**:可以通过参数设置组件的具体行为和外观,如`$(selector).dialog({width: 500, modal: true})`创建一个宽度为500像素且模态的对话框。 5. **事件处理**:绑定事件监听器以响应用户的交互行为,如`$...

    jquery获取form表单input元素值的简单实例

    在本篇内容中,我们将详细探讨如何使用jQuery来获取form表单中input元素的值,包括文本框、复选框、单选按钮等不同类型input元素的值获取方法。通过jQuery提供的val()方法和attr()方法,我们可以轻松获取或设置input...

    一个简单的jquery设计的一像素表格

    在本项目中,"一个简单的jquery设计的一像素表格"实现了这一功能,并且增加了交互性,允许用户通过鼠标操作来与表格进行互动。 jQuery是一个强大的JavaScript库,它极大地简化了DOM操作、事件处理、动画以及Ajax...

    jQuery中文参考手册

    《jQuery中文参考手册》是一本全面且详尽的资源,旨在帮助开发者深入理解和高效使用jQuery这一流行的JavaScript库。jQuery以其简洁、高效的语法和强大的功能,极大地简化了网页动态效果的实现,使得DOM操作、事件...

    jQuery获取table下某一行某一列的值实现代码

    从提供的文件内容中,我们可以提取以下关于jQuery获取表格中某一行某一列值的知识点: 1. jQuery选择器的使用:在文中,通过使用选择器 $(".div") 找到了包含多个表格的div元素。这说明了jQuery选择器用于选取页面...

    jQuery操作checkbox并获取选中值

    在网页开发中,jQuery是一个非常流行的JavaScript库,它极大地简化了DOM操作、事件处理、动画效果和Ajax交互。本文将详细讲解如何使用jQuery来操作checkbox,并实现全选、全不选、反选以及获取选中值这四个核心功能...

    jQuery API 1.4.4 中文参考手册.chm

    jQuery API 1.4.4 中文参考手册.chm,jquery api 下载,jQuery 1.4.4 API 参考文档中文版.rar,jQuery最新版CHM下载,jQuery中文参考手册,jQuery中文版1.4.4参考手册,jQuery 1.4.4 速查表,jQuery中文参考手册,jQuery中文...

    13jQuery基础使用与样式篇.docx

    总结,jQuery的选择器系统是其强大之处,它使得在JavaScript中操作DOM变得简单且高效。结合基础选择器、层级选择器和筛选选择器,开发者可以灵活地找到并操作页面上的任意元素,进而实现丰富的交互效果和动态更新。...

    jquery1.7中文参考手册

    《jQuery 1.7中文参考手册》是一本详细介绍jQuery库1.7版本的资源文档,主要涵盖该版本中各种函数、方法和API的使用。jQuery是JavaScript的一个库,它极大地简化了JavaScript编程,使得网页交互变得更加简单高效。该...

    Jquery1.8.0和jquery1.8中文Api

    总结,jQuery 1.8.0作为一款强大且广泛使用的JavaScript库,其1.8.0版本的更新优化了多个方面,为开发者提供了更好的工具。配合中文API文档,无论新手还是经验丰富的开发者都能更高效地利用jQuery进行Web开发。

    jQuery.ui.1.7.2中文文档

    jQuery UI 是一个基于 jQuery 的开源库,它提供了丰富的用户界面组件和交互效果,为开发者构建功能完善的Web应用程序提供了强大支持。1.7.2版本是该库的一个稳定版本,包含了众多实用的功能和组件。本文将对其中的...

    Jquery AutoComplete 使用demo

    jQuery AutoComplete 是一个非常流行的 jQuery 插件,它为输入框提供了自动补全的功能,广泛应用于网页表单、搜索框等场景,以提高用户体验。这个插件允许开发者从本地数组或通过异步方式从服务器获取数据,实现动态...

    jquery ajax 异步传值并把值赋予在div标签内

    jquery ajax 异步传值并把值赋予在div标签内 很简单的jquery ajax异步传值 让您清楚了解jquery ajax运作 点击按钮的时候 程序会通过ajax去获取某个PHP文件的输出值 获取PHP文件的输出值的那一刻下面的程序会继续执行...

    jQuery鼠标拖动滑块选值代码

    "jQuery鼠标拖动滑块选值代码"是一个典型的例子,它利用jQuery实现了用户可以通过鼠标拖动滑块来选择数值的功能,同时也支持点击滑杆或直接在输入框输入数值。这种功能常见于各种设置面板、游戏控制或数据调整场景。...

    SSH+jQuery+json 实现的Ajax操作,绝对精华,代码简练清晰,绝对能看明白

    这个压缩包中的资源,"SSH+jQuery+json 实现的Ajax操作,绝对精华,代码简练清晰,绝对能看明白",显然提供了一个使用这些技术实现Ajax级联操作的实例。下面将详细介绍这些技术及其在Ajax操作中的应用。 **SSH ...

    jquery 获取单选按钮的值

    在IT行业中,jQuery是一个广泛使用的JavaScript库,它简化了HTML文档遍历、事件处理、动画制作和Ajax交互等任务。本篇文章将详细讲解如何在jQuery中获取单选按钮(radio button)的值。 首先,我们需要了解HTML中的...

    jquery api 3.3.1中文文档

    1. **选择器(Selectors)**:jQuery提供了丰富的CSS选择器,如ID选择器(#id)、类选择器(.class)、元素选择器(element)等,用于快速定位DOM元素。 2. **DOM操作(DOM Manipulation)**:包括`$(selector)....

    ASP.NET jquery datepicker的使用

    在本教程中,我们将深入探讨如何在ASP.NET中集成和使用jQuery的datepicker。 ### 1. jQuery UI和jQuery Datepicker 首先,要使用jQuery的datepicker,你需要引入jQuery UI库,它包含了datepicker组件。你可以从...

Global site tag (gtag.js) - Google Analytics