Skip to content

Instantly share code, notes, and snippets.

@smallnewer
Created September 12, 2013 03:15
Show Gist options
  • Save smallnewer/6532706 to your computer and use it in GitHub Desktop.
Save smallnewer/6532706 to your computer and use it in GitHub Desktop.
CSS的相关操作,获取完整样式。 其中将100%,1em等相对单位换成精确PX代码值得一看 完整代码在:https://github.com/RubyLouvre/avalon/blob/master/avalon.js
//=============================css相关=======================
var cssHooks = avalon.cssHooks = {}
var prefixes = ['', '-webkit-', '-o-', '-moz-', '-ms-']
var cssMap = {
"float": 'cssFloat' in root.style ? 'cssFloat' : 'styleFloat',
background: "backgroundColor"
}
var cssNumber = oneObject("columnCount,order,fillOpacity,fontWeight,lineHeight,opacity,orphans,widows,zIndex,zoom")
function cssName(name, host, camelCase) {
if (cssMap[name]) {
return cssMap[name]
}
host = host || root.style
for (var i = 0, n = prefixes.length; i < n; i++) {
camelCase = camelize(prefixes[i] + name)
if (camelCase in host) {
return (cssMap[name] = camelCase)
}
}
return null
}
cssHooks["@:set"] = function(node, name, value) {
try { //node.style.width = NaN;node.style.width = "xxxxxxx";node.style.width = undefine 在旧式IE下会抛异常
node.style[name] = value
} catch (e) {
}
}
if (window.getComputedStyle) {
cssHooks["@:get"] = function(node, name) {
var ret, styles = window.getComputedStyle(node, null)
if (styles) {
ret = name === "filter" ? styles.getPropertyValue(name) : styles[name]
if (ret === "") {
ret = node.style[name] //其他浏览器需要我们手动取内联样式
}
}
return ret
}
cssHooks["opacity:get"] = function(node) {
var ret = cssHooks["@:get"](node, "opacity")
return ret === "" ? "1" : ret
}
} else {
var rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i
var rposition = /^(top|right|bottom|left)$/
var ie8 = !!window.XDomainRequest
var salpha = "DXImageTransform.Microsoft.Alpha"
var border = {
thin: ie8 ? '1px' : '2px',
medium: ie8 ? '3px' : '4px',
thick: ie8 ? '5px' : '6px'
}
cssHooks["@:get"] = function(node, name) {
//取得精确值,不过它有可能是带em,pc,mm,pt,%等单位
var currentStyle = node.currentStyle
var ret = currentStyle[name]
if ((rnumnonpx.test(ret) && !rposition.test(ret))) {
//①,保存原有的style.left, runtimeStyle.left,
var style = node.style,
left = style.left,
rsLeft = node.runtimeStyle.left
//②由于③处的style.left = xxx会影响到currentStyle.left,
//因此把它currentStyle.left放到runtimeStyle.left,
//runtimeStyle.left拥有最高优先级,不会style.left影响
node.runtimeStyle.left = currentStyle.left
//③将精确值赋给到style.left,然后通过IE的另一个私有属性 style.pixelLeft
//得到单位为px的结果;fontSize的分支见http://bugs.jquery.com/ticket/760
style.left = name === 'fontSize' ? '1em' : (ret || 0)
ret = style.pixelLeft + "px"
//④还原 style.left,runtimeStyle.left
style.left = left
node.runtimeStyle.left = rsLeft
}
if (ret === "medium") {
name = name.replace("Width", "Style")
//border width 默认值为medium,即使其为0"
if (currentStyle[name] === "none") {
ret = "0px"
}
}
return ret === "" ? "auto" : border[ret] || ret
}
cssHooks["opacity:set"] = function(node, name, value) {
node.style.filter = 'alpha(opacity=' + value * 100 + ')'
node.style.zoom = 1
}
cssHooks["opacity:get"] = function(node) {
//这是最快的获取IE透明值的方式,不需要动用正则了!
var alpha = node.filters.alpha || node.filters[salpha],
op = alpha ? alpha.opacity : 100
return (op / 100) + "" //确保返回的是字符串
}
}
"top,left".replace(rword, function(name) {
cssHooks[name + ":get"] = function(node) {
var computed = cssHooks["@:get"](node, name)
return /px$/.test(computed) ? computed :
avalon(node).position()[ name ] + "px"
}
})
"Width,Height".replace(rword, function(name) {
var method = name.toLowerCase(),
clientProp = "client" + name,
scrollProp = "scroll" + name,
offsetProp = "offset" + name
avalon.fn[method] = function(value) {
var node = this[0]
if (arguments.length === 0) {
if (node.setTimeout) { //取得窗口尺寸,IE9后可以用node.innerWidth /innerHeight代替
return node["inner" + name] || node.document.documentElement[clientProp]
}
if (node.nodeType === 9) { //取得页面尺寸
var doc = node.documentElement
//FF chrome html.scrollHeight< body.scrollHeight
//IE 标准模式 : html.scrollHeight> body.scrollHeight
//IE 怪异模式 : html.scrollHeight 最大等于可视窗口多一点?
return Math.max(node.body[scrollProp], doc[scrollProp], node.body[offsetProp], doc[offsetProp], doc[clientProp])
}
return parseFloat(this.css(method)) || 0
} else {
return this.css(method, value)
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment