mass Framework css模块 v2
它包含两个JS,其中css_ie是用于兼容旧式IE的。
css_ie.js
(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);
css.js
//=========================================
// 样式操作模块 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
机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
浙公网安备 33010602011771号