它包含两个JS,其中css_ie是用于兼容旧式IE的。
(function(global,DOC){ var dom = global[DOC.URL.replace(/(#.+|\W)/g,'')]; dom.log("已加载css_ie模块"); dom.define("css_ie", function(){ if (DOC.execCommand) try { DOC.execCommand("BackgroundImageCache", false, true); } catch (e){} var adapter = dom.cssAdapter = {}; //========================= 处理 opacity ========================= var ropacity = /opacity=([^)]*)/i, ralpha = /alpha\([^)]*\)/i, rnumpx = /^-?\d+(?:px)?$/i, rnum = /^-?\d/; adapter["opacity:get"] = function(node,op){ //这是最快的获取IE透明值的方式,不需要动用正则了! if(node.filters.alpha){ op = node.filters.alpha.opacity; }else if(node.filters["DXImageTransform.Microsoft.Alpha"]){ op = node.filters["DXImageTransform.Microsoft.Alpha"].opacity }else{ op = (node.currentStyle.filter ||"opacity=100").match(ropacity)[1]; } return op ? op /100 :op//如果是零就不用除100了 } adapter["opacity:set"] = function(node, name, value){ var currentStyle = node.currentStyle, style = node.style; if(!currentStyle.hasLayout) style.zoom = 1;//让元素获得hasLayout value = (value > 0.999) ? 1: (value < 0.001) ? 0 : value; if(node.filters.alpha){ //必须已经定义过透明滤镜才能使用以下便捷方式 node.filters.alpha.opacity = value * 100; }else{ style.filter = "alpha(opacity="+((value * 100) | 0)+")"; } //IE7的透明滤镜当其值为100时会让文本模糊不清 if(value === 1){ style.filter = currentStyle.filter.replace(ralpha,''); } style.visibility = value ? "visible" : "hidden"; } var ie8 = !!global.XDomainRequest, border = { thin: ie8 ? '1px' : '2px', medium: ie8 ? '3px' : '4px', thick: ie8 ? '5px' : '6px' }; adapter[ "_default:get" ] = function(node, name){ var ret = node.currentStyle && node.currentStyle[name]; if ((!rnumpx.test(ret) && rnum.test(ret))) { var style = node.style, left = style.left, rsLeft = node.runtimeStyle && node.runtimeStyle.left ; if (rsLeft) { node.runtimeStyle.left = node.currentStyle.left; } style.left = name === 'fontSize' ? '1em' : (ret || 0); ret = style.pixelLeft + "px"; style.left = left; if (rsLeft) { node.runtimeStyle.left = rsLeft; } } if(ret == "medium"){ name = name.replace("Width","Style"); //border width 默认值为medium,即使其为0" if(arguments.callee(node,name) == "none"){ ret = "0px"; } } if(/margin|padding|border/.test(name) && ret === "auto"){ ret = "0px"; } return ret === "" ? "auto" : border[ret] || ret; } }); })(this,this.document);
//========================================= // 样式操作模块 by 司徒正美 //========================================= (function(global,DOC){ var dom = global[DOC.URL.replace(/(#.+|\W)/g,'')], node$css_ie = global.getComputedStyle ? "node" : "node,css_ie" ; dom.log("已加载css模块") dom.define("css", node$css_ie, function(){ var cssFloat = dom.support.cssFloat ? 'cssFloat': 'styleFloat', rmatrix = /\(([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/, rad2deg = 180/Math.PI, deg2rad = Math.PI/180, rcap = /-([a-z])/g,capfn = function(_,$1){ return $1.toUpperCase(); },prefixes = ['', '-ms-','-moz-', '-webkit-', '-khtml-', '-o-','ms-'], adapter = dom.cssAdapter = dom.cssAdapter || {}; function cssCache(name){ return cssCache[name] || (cssCache[name] = name == 'float' ? cssFloat : name.replace(rcap, capfn)); } //http://www.w3.org/TR/2009/WD-css3-2d-transforms-20091201/#introduction dom.mix(dom, { cssCache:cssCache, //http://www.cnblogs.com/rubylouvre/archive/2011/03/28/1998223.html cssName : function(name, target, test){ if(cssCache[name]) return name; target = target || dom.html.style; for (var i=0, l=prefixes.length; i < l; i++) { test = (prefixes[i] + name).replace(rcap,capfn); if(test in target){ return (cssCache[name] = test); } } return null; }, scrollbarWidth:function self(){ if(self.ret){ return self.ret } var test = dom('<div style="width: 100px;height: 100px;overflow: scroll;position: absolute;top: -9999px;"/>').appendTo("body") var ret = test[0].offsetWidth - test[0].clientWidth; test.remove(); return self.ret = ret }, cssNumber : dom.oneObject("fontSizeAdjust,fontWeight,lineHeight,opacity,orphans,widows,zIndex,zoom,rotate"), css: function(nodes, name, value){ var props = {} , fn; nodes = nodes.nodeType == 1 ? [nodes] : nodes; if(name && typeof name === "object"){ props = name; }else if(value === void 0){ return (adapter[name+":get"] || adapter["_default:get"])( nodes[0], cssCache(name) ); }else { props[name] = value; } for(name in props){ value = props[name]; name = cssCache(name); fn = adapter[name+":set"] || adapter["_default:set"]; if ( isFinite( value ) && !dom.cssNumber[ name ] ) { value += "px"; } for(var i = 0, node; node = nodes[i++];){ if(node && node.nodeType === 1){ fn(node, name, value ); } } } return nodes; }, // gerrer(node) 返回一个包含 scaleX,scaleY, rotate, translateX,translateY, translateZ的对象 // setter(node, { rotate: 30 })返回自身 transform : function(node, param){ var meta = dom._data(node,"transform"), ident = "DXImageTransform.Microsoft.Matrix",arr = [1,0,0,1,0,0], m if(!meta){ if(cssTransfrom){ //将CSS3 transform属性中的数值分解出来 var style = dom.css([node],cssTransfrom); if(~style.indexOf("matrix")){ m = rmatrix.exec(style); arr = [m[1], m[2], m[3], m[4], m[5], m[6]]; }else if(style.length > 6){ arr = str2matrixArr(style) } meta = arr2matrixObj(arr); }else { //http://msdn.microsoft.com/en-us/library/ms533014(v=vs.85).aspx m = node.filters ? node.filters[ident] : 0; arr = m ? [m.M11, m.M12, m.M21, m.M22, m.Dx, m.Dy] : arr; meta = arr2matrixObj(arr); meta.rotate = - meta.rotate; }//保存到缓存系统,省得每次都计算 meta = dom._data(node,"transform",meta); } if(arguments.length === 1){ return meta;//getter } //setter meta = dom._data(node,"transform",{ scaleX: param.scaleX === void 0 ? meta.scaleX : param.scaleX, scaleY: param.scaleY === void 0 ? meta.scaleY : param.scaleY, rotate: param.rotate === void 0 ? meta.rotate : param.rotate, translateX: param.translateX === void 0 ? meta.translateX : parseInt(param.translateX)|0, translateY: param.translateY === void 0 ? meta.translateY : parseInt(param.translateY)|0 }); if(cssTransfrom){ node.style[cssTransfrom] = "scale(" + meta.scaleX + "," + meta.scaleY + ") " + "rotate(" + all2deg(meta.rotate) + "deg) " + "translate(" + meta.translateX + "px," + meta.translateY + "px)"; }else if (dom.html.filters) { //注意:IE滤镜和其他浏览器定义的角度方向相反 var r = -all2rad(meta.rotate), cos = Math.cos(r ), sin = Math.sin(r), mtx = [ cos * meta.scaleX, sin * meta.scaleX, 0, -sin * meta.scaleY, cos * meta.scaleY, 0, meta.translateX, meta.translateY, 1], cxcy= dom._data(node,"cxcy"); if (!cxcy) { var rect = node.getBoundingClientRect(), // filterType = ', FilterType=\'nearest neighbor\'', //bilinear cx = (rect.right - rect.left) / 2, // center x cy = (rect.bottom - rect.top) / 2; // center y node.style.filter += " progid:" + ident + "(sizingMethod='auto expand')"; cxcy = dom._data(node,"cxcy", { cx: cx, cy: cy }); } m = node.filters[ident]; m.M11 = mtx[0]; m.M12 = mtx[1]; m.M21 = mtx[3]; m.M22 = mtx[4]; m.Dx = mtx[6]; m.Dy = mtx[7]; // recalc center rect = node.getBoundingClientRect(); cx = (rect.right - rect.left) / 2; cy = (rect.bottom - rect.top) / 2; node.style.marginLeft = cxcy.cx - cx + "px"; node.style.marginTop = cxcy.cy - cy + "px"; } } }); //支持情况 ff3.5 chrome ie9 pp6 opara10.5 safari3.1 var cssTransfrom = dom.cssName("transform"); //CSS3新增的三种角度单位分别为deg(角度), rad(弧度), grad(梯度或称百分度 )。 function all2deg(value) { value += ""; return ~value.indexOf("deg") ? parseInt(value,10): ~value.indexOf("grad") ? parseInt(value,10) * 2/1.8: ~value.indexOf("rad") ? parseInt(value,10) * rad2deg: parseFloat(value); } function all2rad(value){ return all2deg(value) * deg2rad; } dom.implement({ css : function(name, value){ return dom.css(this, name, value); }, rotate : function(value){ return dom.css(this, "rotate", value) ; } }); //将 skewx(10deg) translatex(150px)这样的字符串转换成3*2的距阵 function str2matrixArr( transform ) { transform = transform.split(")"); var i = transform.length -1 , split, prop, val , A = 1 , B = 0 , C = 0 , D = 1 , A_, B_, C_, D_ , tmp1, tmp2 , X = 0 , Y = 0 ; while ( i-- ) { split = transform[i].split("("); prop = split[0].trim(); val = split[1]; A_ = B_ = C_ = D_ = 0; switch (prop) { case "translateX": X += parseInt(val, 10); continue; case "translateY": Y += parseInt(val, 10); continue; case "translate": val = val.split(","); X += parseInt(val[0], 10); Y += parseInt(val[1] || 0, 10); continue; case "rotate": val = all2rad(val) ; A_ = Math.cos(val); B_ = Math.sin(val); C_ = -Math.sin(val); D_ = Math.cos(val); break; case "scaleX": A_ = val; D_ = 1; break; case "scaleY": A_ = 1; D_ = val; break; case "scale": val = val.split(","); A_ = val[0]; D_ = val.length>1 ? val[1] : val[0]; break; case "skewX": A_ = D_ = 1; C_ = Math.tan( all2rad(val)); break; case "skewY": A_ = D_ = 1; B_ = Math.tan( all2rad(val)); break; case "skew": A_ = D_ = 1; val = val.split(","); C_ = Math.tan( all2rad(val[0])); B_ = Math.tan( all2rad(val[1] || 0)); break; case "matrix": val = val.split(","); A_ = +val[0]; B_ = +val[1]; C_ = +val[2]; D_ = +val[3]; X += parseInt(val[4], 10); Y += parseInt(val[5], 10); } // Matrix product tmp1 = A * A_ + B * C_; B = A * B_ + B * D_; tmp2 = C * A_ + D * C_; D = C * B_ + D * D_; A = tmp1; C = tmp2; } return [A,B,C,D,X,Y]; } // 将矩阵转换为一个含有 rotate, scale and skew 属性的对象 // http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp function arr2matrixObj(matrix) { var scaleX , scaleY , XYshear , A = matrix[0] , B = matrix[1] , C = matrix[2] , D = matrix[3] ; // matrix is singular and cannot be interpolated if ( A * D - B * C ) { // step (3) scaleX = Math.sqrt( A * A + B * B ); A /= scaleX; B /= scaleX; // step (4) XYshear = A * C + B * D; C -= A * XYshear ; D -= B * XYshear ; // step (5) scaleY = Math.sqrt( C * C + D * D ); C /= scaleY; D /= scaleY; XYshear /= scaleY; // step (6) // A*D - B*C should now be 1 or -1 if ( A * D < B * C ) { A = -A; B = -B; C = -C; B = -B; D = -D; XYshear = -XYshear; scaleX = -scaleX; } } else { B = A = scaleX = scaleY = XYshear = 0; } return { translateX: +matrix[4], translateY: +matrix[5], rotate: Math.atan2(B, A), scaleX: scaleX, scaleY: scaleY, skew: [XYshear, 0] } } //IE9 FF等支持getComputedStyle dom.mix(adapter, { "_default:get" :function( node, name){ return node.style[ name ]; }, "_default:set" :function( node, name, value){ node.style[ name ] = value; }, "rotate:get":function( node ){ return all2deg((dom.transform(node) || {}).rotate) ; }, "rotate:set":function( node, name, value){ dom.transform(node, { rotate:value }); } },false); if ( DOC.defaultView && DOC.defaultView.getComputedStyle ) { adapter[ "_default:get" ] = function( node, name ) { var ret, defaultView, computedStyle; if ( !(defaultView = node.ownerDocument.defaultView) ) { return undefined; } var underscored = name == "cssFloat" ? "float" : name.replace( /([A-Z]|^ms)/g, "-$1" ).toLowerCase(); if ( (computedStyle = defaultView.getComputedStyle( node, null )) ) { ret = computedStyle.getPropertyValue( underscored ); if ( ret === "" && !dom.contains( node.ownerDocument, node ) ) { ret = node.style[name];//如果还没有加入DOM树,则取内联样式 } } return ret === "" ? "auto" : ret; }; } //========================= 处理 width height ========================= var getter = dom.cssAdapter["_default:get"], RECT = "getBoundingClientRect", cssPair = { Width:['Left', 'Right'], Height:['Top', 'Bottom'] } function getWH( node, name,extra ) {//注意 name是首字母大写 var none = 0, getter = dom.cssAdapter["_default:get"], which = cssPair[name]; if(getter(node,"display") === "none" ){ none ++; node.style.display = "block"; } var rect = node[RECT] && node[RECT]() || node.ownerDocument.getBoxObjectFor(node), val = node["offset" + name] || rect[which[1].toLowerCase()] - rect[which[0].toLowerCase()]; extra = extra || 0; which.forEach(function(direction){ if(extra < 1) val -= parseFloat(getter(node, 'padding' + direction)) || 0; if(extra < 2) val -= parseFloat(getter(node, 'border' + direction + 'Width')) || 0; if(extra === 3){ val += parseFloat(getter(node, 'margin' + direction )) || 0; } }); none && (node.style.display = "none"); return val; } "width,height".replace(dom.rword,function(name){ dom.cssAdapter[ name+":get" ] = function(node, name){ return getWH(node, name == "width" ? "Width" : "Height") + "px"; } }); // clientWidth = node.style.width + padding // https://developer.mozilla.org/en/DOM/element.clientWidth // offsetWidth = node.style.width + padding + border // https://developer.mozilla.org/en/DOM/element.offsetWidth // getBoundingClientRect = node.style.width + padding + border // https://developer.mozilla.org/en/DOM/element.getBoundingClientRect // [CSS2.1 盒子模型] http://www.w3.org/TR/CSS2/box.html // B-------border----------+ -> border // | | // | P----padding----+ | -> padding // | | | | // | | C-content-+ | | -> content // | | | | | | // | | | | | | // | | +---------+ | | // | | | | // | +---------------+ | // | | // +-----------------------+ // B = event.offsetX/Y in WebKit // event.layerX/Y in Gecko // P = event.offsetX/Y in IE6 ~ IE8 // C = event.offsetX/Y in Opera "Height,Width".replace(dom.rword, function( name ) { dom.fn[ name.toLowerCase() ] = function(size) { var target = this[0]; if ( !target ) { return size == null ? null : this; } if ( dom.type(target, "Window")) {//取得浏览器工作区的大小 var doc = target.document, prop = doc.documentElement[ "client" + name ], body = doc.body; return doc.compatMode === "CSS1Compat" && prop || body && body[ "client" + name ] || prop; } else if ( target.nodeType === 9 ) {//取得页面的大小(包括不可见部分) return Math.max( target.documentElement["client" + name], target.body["scroll" + name], target.documentElement["scroll" + name], target.body["offset" + name], target.documentElement["offset" + name] ); } else if ( size === void 0 ) { return getWH(target,name, 0) } else { return dom.css(this,name.toLowerCase(),size); } }; dom.fn[ "inner" + name ] = function() { var node = this[0]; return node && node.style ? getWH(node,name, 1) : null; }; // outerHeight and outerWidth dom.fn[ "outer" + name ] = function( margin ) { var node = this[0], extra = margin === "margin" ? 3 : 2; return node && node.style ? getWH(node,name, extra) : null; }; }); //========================= 处理 user-select ========================= //https://developer.mozilla.org/en/CSS/-moz-user-select //http://www.w3.org/TR/2000/WD-css3-userint-20000216#user-select //具体支持情况可见下面网址 //http://help.dottoro.com/lcrlukea.php adapter[ "userSelect:set" ] = function( node, name, value ) { name = dom.cssName(name); if(typeof name === "string"){ return node.style[name] = value } var allow = /none/.test(value||"all"); node.unselectable = allow ? "" : "on"; node.onselectstart = allow ? "" : function(){ return false; }; }; //======================================================= //获取body的offset function getBodyOffsetNoMargin(){ var el = DOC.body, ret = parseFloat(dom.getStyle(el,"margin-top"))!== el.offsetTop; function getBodyOffsetNoMargin(){ return ret;//一次之后的执行结果 } return ret;//第一次执行结果 } dom.fn.offset = function(){ var node = this[0], owner = node && node.ownerDocument, pos = { left:0, top:0 }; if ( !node || !owner ) { return pos; } if(node.tagName === "BODY"){ pos.top = node.offsetTop; pos.left = body.offsetLeft; //http://hkom.blog1.fc2.com/?mode=m&no=750 body的偏移量是不包含margin的 if(getBodyOffsetNoMargin()){ pos.top += parseFloat( getter(node, "marginTop") ) || 0; pos.left += parseFloat( getter(node, "marginLeft")) || 0; } return pos; }else if (dom.html[RECT]) { //如果支持getBoundingClientRect //我们可以通过getBoundingClientRect来获得元素相对于client的rect. //http://msdn.microsoft.com/en-us/library/ms536433.aspx var box = node[RECT](),win = getWindow(owner), root = owner.documentElement,body = owner.body, clientTop = root.clientTop || body.clientTop || 0, clientLeft = root.clientLeft || body.clientLeft || 0, scrollTop = win.pageYOffset || dom.support.boxModel && root.scrollTop || body.scrollTop, scrollLeft = win.pageXOffset || dom.support.boxModel && root.scrollLeft || body.scrollLeft; // 加上document的scroll的部分尺寸到left,top中。 // IE一些版本中会自动为HTML元素加上2px的border,我们需要去掉它 // http://msdn.microsoft.com/en-us/library/ms533564(VS.85).aspx pos.top = box.top + scrollTop - clientTop, pos.left = box.left + scrollLeft - clientLeft; } return pos; } //========================================================== //http://msdn.microsoft.com/en-us/library/cc304082(v=vs.85).aspx var test = dom('<div style="background-position: 3px 5px">'); try{ dom.support.backgroundPosition = test.css('backgroundPosition') === "3px 5px" ? true : false; dom.support.backgroundPositionXY = test.css('backgroundPositionX') === "3px" ? true : false; }catch(e){ } test = null; //如果像IE67那样,只支持backgroundPositionXY,不支持backgroundPosition var XY = ["X","Y"],prefix = "backgroundPosition"; if (!dom.support.backgroundPosition && dom.support.backgroundPositionXY) { adapter[prefix+":get"] = function( node) { return XY.map(function(which){ return adapter[ "_default:get" ](node,prefix+which) }).join(" "); } adapter[prefix+":set"] =function(node, name, value){ XY.forEach(function(which,i){ node.style[ prefix +which ] = value.split(/\s/)[i] }) } } function parseBgPos(bgPos) { var parts = bgPos.split(/\s/), values = { "X": parts[0], "Y": parts[1] }; return values; } if (dom.support.backgroundPosition && !dom.support.backgroundPositionXY) { XY.forEach(function(which){ adapter[prefix+which+":get"] = function(node,name){ var values = parseBgPos( adapter[ "_default:get" ](node,prefix) ); return values[ which]; } adapter[prefix+which+":set"] = function(node,name,value){ var values = parseBgPos( adapter[ "_default:get" ](node,prefix) ), isX = which === "X"; node.style.backgroundPosition = (isX ? value : values[ "X" ]) + " " + (isX ? values[ "Y" ] : value); } }) } var rroot = /^(?:body|html)$/i; dom.implement({ position: function() { var ret = this.offset(), node = this[0]; if ( node && node.nodeType ===1 ) { var offsetParent = this.offsetParent(), parentOffset = rroot.test(offsetParent[0].nodeName) ? { top:0, left:0 } : offsetParent.offset(); ret.top -= parseFloat( getter(node, "marginTop") ) || 0; ret.left -= parseFloat( getter(node, "marginLeft") ) || 0; parentOffset.top += parseFloat( getter(offsetParent[0], "borderTopWidth") ) || 0; parentOffset.left += parseFloat( getter(offsetParent[0], "borderLeftWidth") ) || 0; ret.top -= parentOffset.top; ret.left -= parentOffset.left } return ret; }, offsetParent: function() { return this.map(function() { var offsetParent = this.offsetParent || DOC.body; while ( offsetParent && (!rroot.test(offsetParent.nodeName) && getter(offsetParent, "position") === "static") ) { offsetParent = offsetParent.offsetParent; } return offsetParent; }); } }); "Left,Top".replace(dom.rword,function( name ) { var method = "scroll" + name; dom.fn[ method ] = function( val ) { var node, win, i = name == "Top"; if ( val === void 0 ) { node = this[ 0 ]; if ( !node ) { return null; } win = getWindow( node ); // Return the scroll offset return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : dom.support.boxModel && win.document.documentElement[ method ] || win.document.body[ method ] : node[ method ]; } // Set the scroll offset return this.each(function() { win = getWindow( this ); if ( win ) { win.scrollTo( !i ? val : dom( win ).scrollLeft(), i ? val : dom( win ).scrollTop() ); } else { this[ method ] = val; } }); }; }); function getWindow( node ) { return dom.type(node,"Window") ? node : node.nodeType === 9 ? node.defaultView || node.parentWindow : false; } }); })(this,this.document); //2011.9.5 //将cssName改为隋性函数,修正msTransform Bug //2011.9.19 添加dom.fn.offset width height innerWidth innerHeight outerWidth outerHeight scrollTop scrollLeft offset position //2011.10.10 重构position offset保持这两者行为一致, //2011.10.14 Fix dom.css BUG,如果传入一个对象,它把到getter分支了。 //2011.10.15 Fix dom.css BUG 添加transform rotate API //2011.10.20 getWH不能获取隐藏元素的BUG //2011.10.21 修正width height的BUG //https://github.com/heygrady/transform/blob/master/src/jquery.matrix.js //http://ie.microsoft.com/testdrive/HTML5/getComputedStyle/Default.html