$.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 属性、它返回的值的类型以及动画的复杂性,可能需要更多的自定义代码。