检测浏览器中的 flex-wrap 支持
Posted
技术标签:
【中文标题】检测浏览器中的 flex-wrap 支持【英文标题】:Detecting flex-wrap support in browsers 【发布时间】:2015-01-01 21:17:08 【问题描述】:我正在做一个项目,其中我有一个使用 flex wrap 属性实现的响应式网格。由于我支持 IE9 及更低版本的 Firefox,28 及以下版本,我如何通过 javascript 找出对相同的支持。目前我只能通过条件语句识别 IE9 浏览器,但现在有人如何通过 javascript 检测 Firefox 旧版本。
【问题讨论】:
对于过时的软件,您不太可能获得最新的解决方案。 Modernizr 有什么问题? 我在这里第二个@BFDatabaseAdmin。Modernizer 被大量的 Web 开发人员使用,它为测试各种其他属性提供检测支持,不限于 flex。为什么要重复自己。Modernizer 为我工作毫不费力:) @rahulinactionModernizr
很棒,但我要避免的唯一原因是我必须只测试一个特定的属性。我知道他们允许您自定义构建 modernizr.com/download 这使它更加棒,但我仍然只会在绝对值得的时候下载一个插件。
【参考方案1】:
我发现这是最简单的方法:
var d = document.documentElement.style
if (('flexWrap' in d) || ('WebkitFlexWrap' in d) || ('msFlexWrap' in d))
alert('ok');
我也尝试了hasOwnProperty
,但它在 IE 和 FF 中不起作用。
那么,当你只有 3 行 js 时,为什么还要使用 40 KB 的modernizr 呢?
【讨论】:
Modernizr 不仅适用于 flexWrap,还适用于跨浏览器的 CSS 属性。正如我在回答中提到的,请根据需要使用最简单的方法。例如:如果您的应用程序不支持 webkit 浏览器,您甚至不需要检查WebkitFlexWrap
,这是检查正确的少一个条件。
是的。 Safari 需要 WebkitFlexWrap。如果您查看 Modernizr 代码,它使用所有可能的前缀是否效率低下。即使您需要检查 4-5 个属性,您仍然可以获得 10 倍以上的代码:/
我同意你的观点,我个人会检查 4-5 个属性,如果不支持浏览器,我只会要求升级浏览器。如果我正在为公司设计页面并且他们决定支持各种浏览器,那么情况就会改变。现在我可以自己编写代码来测试 4-5 个属性,然后再添加一些等等。最后我将有一个外部 JS 来测试 10-15 个属性。但这不就是modernizr的全部内容吗?我不是想推广modernizr ..但他们确实有自定义构建..我尝试了flexbox,它是1.8k,这似乎是合理的。
自定义构建modernizr.com/download/…
如果你只使用最新的 flexbox 规范,你应该删除msFlexWrap
(换句话说,你失去了对 IE10 的支持:D)。【参考方案2】:
CSS 属性检测
一个简单的 CSS 属性检测技术是直接在一个元素上测试它并检查它是否返回undefined
,如下所示,
element.style.<propertyName> != undefined
.
最简单的方法(但支持有限)
上述方法直接检查属性,对于大多数常见属性应该足够了(不适用于 flex-wrap)。
function isStyleSupported(el, property)
return el.style[property] != undefined;
var testEl = document.getElementById('test');
testEl.innerhtml = (isStyleSupported(testEl, 'flexWrap')) ? "Flex Wrap is supported" : "Flex Wrap is NOT supported";
<div id="test"></div>
您可以添加更多代码来检查该属性是否支持 dom 前缀,
略微扩展以获得更好的支持(适用于 flex-wrap)
var domPrefixes = 'Webkit Moz O ms Khtml'.split(' ');
function toCamelCase(cssProp)
return cssProp.replace(/-([a-z])/gi, function(s, prop)
return prop.toUpperCase();
);
function isStyleSupported(el, property)
if (el.style[toCamelCase(property)] != undefined)
return true;
//supported
property = toCamelCase("-" + property);
for (var i = 0; i < domPrefixes.length; i++) //check with dom prefixes
if (el.style[domPrefixes[i] + property] !== undefined)
return true; //supported with dom prefix
var divEl = document.getElementById('result'), textEl = document.getElementById('textbox');
document.getElementById('checkSupport').onclick = function()
divEl.innerHTML = (isStyleSupported(divEl, textEl.value)) ? textEl.value + " is supported" : textEl.value + " is NOT supported";
;
<input type="text" id="textbox" value="flex-wrap" />
<button id="checkSupport">Check</button>
<div id="result"></div>
当您决定对所有浏览器中的任何属性进行概括时,它确实变得复杂。这就是我们决定使用modernizr
的地方,它扩展了对处理异常情况的支持。
CSS.supports
有一个新的 CSS API CSS.supports
返回一个布尔值以检查浏览器是否支持特定的 CSS 功能。然而,这是一个新的 API,所以我们仍然使用像 modernizr
这样的插件,直到需要对旧版浏览器的支持。
结论:
如果您的要求很简单,请使用最简单的样式检测element.style.<property> != undefined
或domPrefixes
。您可以随时根据需要对其进行更多自定义,但如果它复杂且广泛,请选择modernizr
,它具有用于特征检测的扩展代码。
【讨论】:
【参考方案3】:扩展@AndresTet 的回答,如果你不想要一个完整的modernizr 构建,你可以创建一个custom one,或者提取并重构相关的flexbox 测试,这似乎是:
function testPropsAll(prop, prefixed, elem)
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
if (is(prefixed, "string") || is(prefixed, "undefined"))
return testProps(props, prefixed);
else
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
return testDOMProps(props, prefixed, elem);
tests['flexbox'] = function()
return testPropsAll('flexWrap');
;
tests['flexboxlegacy'] = function()
return testPropsAll('boxDirection');
;
【讨论】:
以上是关于检测浏览器中的 flex-wrap 支持的主要内容,如果未能解决你的问题,请参考以下文章