供应商前缀使Web开发人员可以在到达候选推荐阶段之前尝试新的标准。 之前,我曾写过这些前缀也是浏览器供应商用来处理实现和规范之间的时序冲突的一种机制。 在为IE Test Drive网站构建新功能的演示并进行各种演示时,IE团队中的许多人都在广泛处理供应商前缀。
本文介绍了一种使用我们的团队在使用供应商前缀进行开发时可以大大简化工作的模式。 我们想与您分享它,并听听您对这种方法或您认为是最佳做法的其他想法。
错误密码
使用脚本访问带有供应商前缀的CSS属性时,很容易得到如下所示的代码:
var elm = document.getElementById("myElement"); elm.style.msTransitionProperty = "all"; elm.style.msTransitionDuration = "3s"; elm.style.msTransitionDelay = "0s"; elm.style.webkitTransitionProperty = "all"; elm.style.webkitTransitionDuration = "3s"; elm.style.webkitTransitionDelay = "0s"; elm.style.MozTransitionProperty = "all"; elm.style.MozTransitionDuration = "3s"; elm.style.MozTransitionDelay = "0s"; elm.style.OTransitionProperty = "all"; elm.style.OTransitionDuration = "3s"; elm.style.OTransitionDelay = "0s";
虽然功能强大,但它肿,丑陋且容易出错。
将供应商前缀的属性合并为一个名称
更好的模式是定义一个方法,该方法循环遍历属性名称列表,并返回第一个受支持的属性;如果浏览器不支持其中任何一个,则返回null。
function FirstSupportedPropertyName(prefixedPropertyNames) { var tempDiv = document.createElement("div"); for (var i = 0; i < prefixedPropertyNames.length; ++i) { if (typeof tempDiv.style[prefixedPropertyNames[i]] != 'undefined') return prefixedPropertyNames[i]; } return null; }
然后,我们为使用的每个供应商前缀属性初始化一个变量,并按照我们希望使用它们的顺序将可能的属性数组传递给该变量。
var transformName = FirstSupportedPropertyName(["transform", "msTransform", "MozTransform", "WebkitTransform", "OTransform"]); var backfaceVisibilityName = FirstSupportedPropertyName(["backfaceVisibility", "msBackfaceVisibility", "MozBackfaceVisibility", "WebkitBackfaceVisibility", "OBackfaceVisibility"]); var transitionName = FirstSupportedPropertyName(["transition", "msTransition", "MozTransition", "WebkitTransition", "OTransition"]); var animationName = FirstSupportedPropertyName(["animation", "msAnimation", "MozAnimation", "WebkitAnimation", "OAnimation"]); var gridName = FirstSupportedPropertyName(["gridRow", "msGridRow", "MozGridRow", "WebkitGridRow", "OGridRow"]); var regionsName = FirstSupportedPropertyName(["flowFrom", "msFlowFrom", "MozFlowFrom", "WebkitFlowFrom", "OFlowFrom"]); var hyphensName = FirstSupportedPropertyName(["hyphens", "msHyphens", "MozHyphens", "WebkitHyphens", "OHyphens"]); var columnName = FirstSupportedPropertyName(["columnCount", "msColumnCount", "MozColumnCount", "WebkitColumnCount", "OColumnCount"]);
然后,使用这些属性的整个站点中的代码将变成这样:
var elm = document.getElementById("myElement"); if (transitionName) { elm.style[transitionName + "Property"] = "all"; elm.style[transitionName + "Duration"] = "3s"; elm.style[transitionName + "Delay"] = "0s"; } else { // fallback for browsers without CSS3 transitions }
请注意,通过在FirstSupportedPropertyName
返回null
来启用简单功能检测 。
当CSS 属性具有供应商前缀时,该模式也适用。 对于CSS 值 (例如,线性渐变)具有供应商前缀的情况,可以使用稍微不同的模式:
function FirstSupportedFunctionName(property, prefixedFunctionNames, argString) { var tempDiv = document.createElement("div"); for (var i = 0; i < prefixedFunctionNames.length; ++i) { tempDiv.style[property] = prefixedFunctionNames[i] + argString; if (tempDiv.style[property] != "") return prefixedFunctionNames[i]; } return null; } var linearGradientName = FirstSupportedFunctionName("backgroundImage", ["-ms-linear-gradient", "-moz-linear-gradient", "-webkit-linear-gradient", "-o-linear-gradient"], "(top, black, white)"); var radialGradientName = FirstSupportedFunctionName("backgroundImage", ["-ms-radial-gradient", "-moz-radial-gradient", "-webkit-radial-gradient", "-o-radial-gradient"], "(50% 50%, circle cover, black, white)");
测试使用供应商前缀属性的站点
一个常见的问题是,如果某些浏览器尚不支持该属性,或者如果没有浏览器支持不带前缀的基于标准的属性,则使用什么属性名称。 有几种方法,每种都有优点:
- 始终包括所有期望的名称,即使它们尚未在浏览器中使用也是如此。 此路径的好处是,随着浏览器添加带有其供应商前缀的支持或添加对非前缀属性的支持,您的站点将“正常运行”而无需更改。 风险在于该网站将自动接受您从未测试过的行为。 供应商名称表示行为没有最后确定,所有的前缀属性和不带前缀的属性可能不具有相同的行为,从而为浏览器添加支持您的网站可能“只是没有工作。”
- 仅包括可以测试的属性名称。 这样做的好处是,即使浏览器添加了对新属性的支持,您的站点也将与您首次编写时的行为相同。 风险是您不必要地降低了功能。 对于示例站点或演示站点,人们可以将其解释为根本没有功能的浏览器。
您需要确定站点的正确路径。 在我们的大多数演示中,我们希望在任何支持它的浏览器中展示新的Web平台功能。 由于这些演示中的小错误不会给用户带来大问题,因此我们通常选择选项#1。 另一方面,如果您的生产现场的行为改变会给您的业务造成问题,那么您可以选择更规避风险的途径。
无论选择哪种路径,一个常数都是测试。 使用供应商前缀的属性时,您会利用早期的经常不稳定的功能,即使在浏览器首次引入对属性的支持之后,这些功能也可能会发生变化,因此,对每个浏览器进行更新以确保您的站点按预期运行至关重要。
From: https://www.sitepoint.com/best-practice-for-programming-with-vendor-prefixes/