$.cssHooks 對象提供了一種方法來定義用於獲取和設置特定 CSS 值的函數。它也可以用來創建新的 cssHooks 來規範化 CSS3 特性,比如盒子陰影和漸變。
例如,某些基於 Webkit 的瀏覽器版本需要 -webkit-border-radius 才能在元素上設置 border-radius,而早期的 Firefox 版本需要 -moz-border-radius 。 css 鉤子可以規範化這些供應商前綴屬性,讓 .css() 接受單個標準屬性名稱(border-radius,或使用 DOM 屬性語法,borderRadius)。
除了提供對如何處理特定樣式屬性的細粒度控製之外,$.cssHooks 還擴展了 .animate() 方法可用的屬性集。
定義一個新的 CSS 鉤子是straight-forward。下麵的骨架模板可以作為創建自己的模板的指南。
(function( $ ) {
// First, check to see if cssHooks are supported
if ( !$.cssHooks ) {
// If not, output an error message
throw( new Error( "jQuery 1.4.3 or above is required for this plugin to work" ) );
}
// Wrap in a document ready call, because jQuery writes
// cssHooks at this time and will blow away your functions
// if they exist.
$(function () {
$.cssHooks[ "someCSSProp" ] = {
get: function( elem, computed, extra ) {
// Handle getting the CSS property
},
set: function( elem, value ) {
// Handle setting the CSS value
}
};
});
})( jQuery );
|
函數測試
在規範化供應商特定的 CSS 屬性之前,首先確定瀏覽器是否支持標準屬性或供應商前綴的變體。例如,要檢查是否支持 border-radius 屬性,請查看是否有任何變體是臨時元素的 style 對象的成員。
(function( $ ) {
function styleSupport( prop ) {
var vendorProp, supportedProp,
// Capitalize first character of the prop to test vendor prefix
capProp = prop.charAt( 0 ).toUpperCase() + prop.slice( 1 ),
prefixes = [ "Moz", "Webkit", "ms" ],
div = document.createElement( "div" );
if ( prop in div.style ) {
// Browser supports standard CSS property name
supportedProp = prop;
} else {
// Otherwise test support for vendor-prefixed property names
for ( var i = 0; i < prefixes.length; i++ ) {
vendorProp = prefixes[ i ] + capProp;
if ( vendorProp in div.style ) {
supportedProp = vendorProp;
break;
}
}
}
// Avoid memory leak in IE
div = null;
// Add property to $.support so it can be accessed elsewhere
$.support[ prop ] = supportedProp;
return supportedProp;
}
// Call the function, e.g. testing for "border-radius" support:
styleSupport( "borderRadius" );
})( jQuery );
|
定義一個完整的 CSS 鉤子
要定義一個完整的 css 鉤子,請將支持測試與第一個示例中提供的骨架模板的填充版本結合起來:
(function( $ ) {
if ( !$.cssHooks ) {
throw( new Error( "jQuery 1.4.3+ is needed for this plugin to work" ) );
}
function styleSupport( prop ) {
var vendorProp, supportedProp,
capProp = prop.charAt( 0 ).toUpperCase() + prop.slice( 1 ),
prefixes = [ "Moz", "Webkit", "ms" ],
div = document.createElement( "div" );
if ( prop in div.style ) {
supportedProp = prop;
} else {
for ( var i = 0; i < prefixes.length; i++ ) {
vendorProp = prefixes[ i ] + capProp;
if ( vendorProp in div.style ) {
supportedProp = vendorProp;
break;
}
}
}
div = null;
$.support[ prop ] = supportedProp;
return supportedProp;
}
var borderRadius = styleSupport( "borderRadius" );
// Set cssHooks only for browsers that support a vendor-prefixed border radius
if ( borderRadius && borderRadius !== "borderRadius" ) {
$.cssHooks.borderRadius = {
get: function( elem, computed, extra ) {
return $.css( elem, borderRadius );
},
set: function( elem, value) {
elem.style[ borderRadius ] = value;
}
};
}
})( jQuery );
|
然後,您可以使用 DOM(camelCased)樣式或 CSS(連字符)樣式在受支持的瀏覽器中設置邊框半徑:
$( "#element" ).css( "borderRadius", "10px" );
$( "#another" ).css( "border-radius", "20px" );
|
如果瀏覽器不支持任何形式的 CSS 屬性,無論是否帶有供應商前綴,樣式都不會應用於元素。但是,如果瀏覽器支持專有替代方案,則可以將其應用於 cssHooks。
(function( $ ) {
// Feature test for support of a CSS property
// and a proprietary alternative
// ...
if ( $.support.someCSSProp && $.support.someCSSProp !== "someCSSProp" ) {
// Set cssHooks for browsers that
// support only a vendor-prefixed someCSSProp
$.cssHooks.someCSSProp = {
get: function( elem, computed, extra ) {
return $.css( elem, $.support.someCSSProp );
},
set: function( elem, value) {
elem.style[ $.support.someCSSProp ] = value;
}
};
} else if ( supportsProprietaryAlternative ) {
$.cssHooks.someCSSProp = {
get: function( elem, computed, extra ) {
// Handle crazy conversion from the proprietary alternative
},
set: function( elem, value ) {
// Handle crazy conversion to the proprietary alternative
}
}
}
})( jQuery );
|
特殊單位
默認情況下,jQuery 將 "px" 單元添加到傳遞給 .css() 方法的值。可以通過將屬性添加到 jQuery.cssNumber 對象來防止這種行為
$.cssNumber.someCSSProp = true;
|
使用 cssHooks 製作動畫
css hook 還可以通過向jQuery.fx.step 對象添加屬性來鉤子到 jQuery 的動畫機製:
$.fx.step.someCSSProp = function( fx ) {
$.cssHooks.someCSSProp.set( fx.elem, fx.now + fx.unit );
};
|
請注意,這最適用於簡單的numeric-value 動畫。根據 CSS 屬性、它返回的值的類型以及動畫的複雜性,可能需要更多的自定義代碼。