jQuery1.8 css模塊評析


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幫你寫了剩下的五十行或三百行!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM