检测浏览器中的 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 为我工作毫不费力:) @rahulinaction Modernizr 很棒,但我要避免的唯一原因是我必须只测试一个特定的属性。我知道他们允许您自定义构建 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.&lt;property&gt; != undefineddomPrefixes。您可以随时根据需要对其进行更多自定义,但如果它复杂且广泛,请选择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 支持的主要内容,如果未能解决你的问题,请参考以下文章

检测浏览器中的 HTTP2/SPDY 支持

如何检测浏览器是不是支持鼠标悬停事件?

JavaScript 中的浏览器检测? [复制]

JavaScript 中的浏览器检测? [复制]

BOM之navigator对象和用户代理检测

使用平衡的 CSS flex-wrap 容器导航