jQuery 样式操作由下面五个子模块组成:
- 内联样式
- 计算样式
- 类样式
- 坐标
- 尺寸
它主要解决如下的问题:
- 浏览器兼容。
- 驼峰、连字符样式名的自动转换。
- 简化样式读写。
表示不用自动添加 px
单位的 css 属性。
cssNumber: {
"columnCount": true,
"fillOpacity": true,
"fontWeight": true,
"lineHeight": true,
"opacity": true,
"orphans": true,
"widows": true,
"zIndex": true,
"zoom": true
}
normal
对应的数字值。
cssNormalTransform = {
letterSpacing: 0,
fontWeight: 400
}
获取所有的计算样式。
- 如果浏览器支持
window.getComputedStyle
那么通过window.getComputedStyle(elem,null)
来获取指定元素的计算样式。第二个参数可以指定伪元素,IE 11 才支持,所以尽量别用。 - IE 6-8 不支持
window.getComputedStyle
,但是支持currentStyle
属性,因此对IE 6-8
使用elem.currentStyle
来获取指定元素的计算样式。
获取指定名称的计算样式。同样是如果浏览器支持 window.getComputedStyle
那么利用 window.getComputedStyle
来获取计算样式,否则通过 currentStyle
属性。不过还是有一些 bug 的。
window.getComputedStyle
:Chrome < 17 and Safari 5.0 使用计算结果替代使用的值来计算margin-right
。(这个应该是在cssHooks
中修复的)Safari 5.1.7 (最新)返回百分比但是我们需要像素值。(此处修复的是非像素值)currentStyle
:IE 通过currentStyle
获取到的是 cascade style也就是 em、% 等,所以需要把他转化为特定的像素值!
负责读取和设置内联样式。设置内联样式时,会计算相对值、添加单位、解决样式不兼容。读取和设置内联样式时会优先调用修正对象上的 get/set
方法。
- 过滤文本节点和注释节点。
- 获取驼峰样式名,并且进行修正,如果有需要还会加上对应的浏览器前缀。
- 根据
name
或驼峰名获取修正对象hooks
。 - 如果传入了
value
- 如果类型是字符串,并且匹配
+=/-=
则表示是相对值,那么将其转为数值并加上原来的值,设置类型为数字。 - 如果是数字类型,并且根据
jQuery.cssNumber
需要自动加上px
单位,那么加上。 - 在 IE 9、10 下要清空
background-*
内联样式时,为出问题,因为设置为"inherit"
。 - 如果存在
hooks.set
,那么优先调用。 - 否则直接在
elem.style
上进行赋值,记得捕获异常,因为在 IE 下,如果传入了非法值会报错。 - 否则。
- 如果存在
hooks.get
,那么优先调用。 - 否则直接在
elem.style
上进行取值。
负责读取计算样式。读取内联样式时会优先调用修正对象上的 get
方法。
- 获取驼峰样式名,并且进行修正,如果有需要还会加上对应的浏览器前缀。
- 根据
name
或驼峰名获取修正对象hooks
。 - 如果存在
hooks.get
,那么优先调用。 - 如果没有
hooks.get
或hooks.get
得到的是undefined
,则调用curCSS( elem, name, styles );
获取计算值。 - 如果得到的是
normal
,将其通过cssNormalTransform
转换为数字值。 - 如果传入的
extra
为true
,那么强制转为数字,如果成功则返回,不成功还是返回原来的值。
四种调用模式:
.css(propertyName)
:获取匹配元素集合第一个元素的计算样式。.css(propertyName, value)
:在每个匹配元素上设置一个内联样式。.css(propertyName, function(index, value))
:在每个匹配元素上设置一个内联样式,属性值由函数返回。
执行过程:
- 如果
name
是数组,那么会调用jQuery.css
取得所有的计算值,返回。 - 否则如果
value
是undefined
,则通过jQuery.css
进行取值。 - 否则用
jQuery.style
设置内联样式值。
opacity
:- 支持
opacity
的情况:读取计算样式时,使用curCSS
,如果得到空字符串,那么返回 1。 - 不支持
opacity
的情况:从elem.style.filter
或elem.currentStyle.filter
中读取,并除以 100。未设置filter
,那么如果是计算值,则返回 1,内联样式返回空字符串。set
方法也是通过filter
来设置。 marginRight
:早先的 WebKitwindow.getComputedStyle
方法无法正确获取margin-right
计算值。修正方法是通过临时设置display:inline-block
来得到正确的值。height
、width
:尺寸一节详细介绍。top
、left
:早先的 WebKitwindow.getComputedStyle
方法返回位置相关的值是百分比,需要用jQuery( elem ).position()
求出像素值。margin
、padding
、borderWidth
:动画里用到,后面写。
为所有匹配元素设置 options
指定的坐标,或者读取第一个匹配元素的坐标。
- 如果传入了
options
,那么调用jQuery.offset.setOffset
进行设置。 - 过滤不在文档中的元素。
- 如果存在
getBoundingClientRect
方法,那么利用它来获取窗口坐标。(IE 4 就支持了,只是不返回width
、height
,不支持的是 BlackBerry 5、iOS 3,对此的策略原来是手动计算,现在的策略是直接返回{left:0,top:0}
) - 获取
window
。 - 相对文档的上坐标 = 距窗口的上坐标 + 垂直方向偏移 - 文档上边框厚度。(左坐标类似)
垂直偏移优先从
window.pageYOffset
,其次是documentElement.scrollTop
。
设置单个元素的文档坐标。
- 如果定位是
static
,则设置为relative
,使left
、top
生效。 - 获取当前文档坐标,计算样式等。
- 如果当前元素的
position
是absolute
、fixed
且计算样式为auto
,那么通过.position()
得到相对于offsetParent
的坐标。 - 如果
options
是函数则求值。 - 计算最终的内联样式。最终内联样式 = 目标文档坐标 - 当前文档坐标 + 计算样式。
- 如果
options
中有using
指定了回调,那么交给它来设置。否则利用.css
方法设置内联样式。
获取第一个匹配元素相对于 offsetParent
的坐标。
- 如果没有匹配元素则返回
null
。 - 对于
fixed
定位的元素offset = elem.getBoundingClientRect()
。 - 否则。
- 获取
offsetParent
元素。 - 获取当前元素的文档坐标。
- 获取
offsetParent
的文档坐标。 - 对于
offsetParent
是html
的情况,要加上border
。 - 当前元素的文档坐标减去
offsetParent
的文档坐标,对于 WebKitoffsetLeft
和marginLeft
会自动相等,导致不正确。所以还要减去对应方向的margin
。对于 jQuery 来说这个elem
把width+padding+border+margin
看成了一个整体,所以最终得到的 top 是 elem 这个整体距离被定为祖辈元素顶部内边的距离。这与offsetTop
、offsetLeft
不一致。
.map
遍历。- 通过
offsetParent()
属性得到最近定位祖先,没找到则返回html
。 - 如果找到的为
static
定位,那么继续找,直到找到html
。 .map
会将得到的元素包装为 jQuery 对象。
读取匹配元素中每个元素的滚动条偏移或设置每个元素的滚动条偏移。
- 如果没有传入
val
,则读取值,window
上通过pageXOffset/pageYOffset
读取,其他的通过scrollLeft/scrollRight
读取。 - 否则,设置值。
window
通过scrollTo
方法来滚动到指定位置,其它的直接通过赋值scrollLeft/scrollRight
完成设置。
getWidthOrHeight(elem,name,extra)
- 变量初始化。
valueIsBorderBox
,borderBox
的值。val
:offsetWidth
或offsetHeight
。styles
:所有计算样式。isBorderBox
:判断是否为borderBox
。- 一些非 HTML 元素会返回
null/undefined
。 - 用
curCSS
得到计算样式。 - 否则读取内联样式。
- 如果得到的不是
px
结尾,那么直接返回。 - 检测盒模型是否可靠。
augmentWidthOrHeight()
根据extras
进行选择性地加减padding
、margin
、border
。
augmentWidthOrHeight(elem,name,extra,isBorderBox,styles)
extra
为margin
,则加上左右或上下的margin
。- 如果是
borderBox
。 extra === "content"
:则要减掉左右或上下的padding
。extra !== "margin"
:则要减掉左右或上下的border
。- 否则。
- 加上左右或上下的
padding
。 extra !== "padding"
:则要加上左右或上下的border
。
更加形象的解释就是:
- 如果
extra
为undefined
,那么就是content
。 - 如果
extra
为padding
,那么就是content+padding
。 - 如果
extra
为border
,那么就是content+padding+border
。 - 如果
extra
为margin
,那么就是content+padding+border+margin
。
- 对于
window
:返回elem.document.documentElement[ "client" + name ];
。 - 对于
document
:返回 body、documentElement 的scroll-*
、offset-*
、documentElement 的client-*
中的大者。 - 根据是否传入
value
,来调用jQuery.style
、jQuery.css
获取或设置值。 - 在
cssHooks
中会根据extra
的值,对get/set
方法进行修正。 - 返回的是
content
。
同 jQuery.fn.width()
、jQuery.fn.height()
。返回的是 content+padding
。
同 jQuery.fn.width()
、jQuery.fn.height()
,只是传入的 extra
不同,这个方法还可以传入可选的 margin
来表示是否在尺寸中加入 margin
。返回的是 content+padding+border+[margin]
。