jQuery早期的核心設施早都是DE大神那里拿過來的,什么選擇器,事件系統,精確計算樣式……現在CSS模塊集中了DE大神的兩個偉大的HACK
一個是用於在標准瀏覽器下轉換百分比值為更有用的像素值
// A tribute to the "awesome hack by Dean Edwards"
// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
width = style.width;
minWidth = style.minWidth;
maxWidth = style.maxWidth;
style.minWidth = style.maxWidth = style.width = ret;
ret = computed.width;
style.width = width;
style.minWidth = minWidth;
style.maxWidth = maxWidth;
}
一個是在IE下刷新原始值為當前的計算值(像素值)。
// 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
// but not position css attributes, as those are proportional to the parent element instead
// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
// 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;
瀏覽器內部肯定有一套獲取精確的像素值(對於某些樣式屬性來說)的機制,被DE大神發現了它們的觸發條件。
此外,jquery還提供兩個單獨的API,width, height獲取元素的長寬,它們甚至可以取得隱藏元素的長寬。出於性能的考量,瀏覽器對隱藏元素的樣式是統統不計算的,有一套默認值返回給你,對於長寬就是0。對於動畫來說,這有點不方便,比如show, slideDown等特效!因此jQuery等偷偷讓它們顯示出來,取得精確值,再隱藏回來,這個是由jquery.swap方法來干。不過到了jquery1.8中,是否要調用這swap方法的條件嚴格了,
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
jQuery.each([ "height", "width" ], function( i, name ) {
jQuery.cssHooks[ name ] = {
get: function( elem, computed, extra ) {
if ( computed ) {
// certain elements can have dimension info if we invisibly show them
// however, it must have a current display style that would benefit from this
if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
return jQuery.swap( elem, cssShow, function() {
return getWidthOrHeight( elem, name, extra );
});
} else {
return getWidthOrHeight( elem, name, extra );
}
}
},
set: function( elem, value, extra ) {}
};
});
rdisplayswap這個正則意思是,以 none 或者 table (但后面不是 -ce 或 -ca)開頭的display值。換言之,下面這幾種display值會進入swap分支
none table-column table-column-group table-footer-group table-header-group table-row table-row-group
此外,我們在設置寬高時,jquery會根據當前的box-sizing選擇盒子模型,於是有了augmentWidthOrHeight這個方法。
為了不用用戶自己寫CSS3私有實現的前綴,jquery還會貼心地幫你補上它們,於是有了vendorPropName方法。
由於現在-webkit-的私有屬性基本上事實的標准,opera也開始支持-webkit-前綴,我們可以看到cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]是這樣排列的!
有些樣式,必須添加單位才能效,而jquery搞了個cssNumber,幫你在這些樣式之外的樣式補上“px”。總之,jquery在背后幫你做了許多事情,你寫一行代碼,jQuery幫你寫了剩下的五十行或三百行!
