供应商前缀伪选择器在Safari中崩溃了element.matches()Web API

时间:2017-08-16 21:42:38

标签: safari css-selectors vendor-prefix

我在一个样式指南生成器中构建一个实用程序,它自动收集每个元素的CSS并将其显示在输出中的元素旁边。我用来收集和解析CSS的脚本基于an answer from SO并使用element.matches() web API

在大多数情况下,代码都能正常运行,但是如果有一个供应商前缀&#39; - 特定的伪元素选择器(例如Bootstrap 4.0中的::-webkit-inner-spin-button),< strong> Safari 在最嵌套的if语句(即if (a.matches(rules[r].selectorText)) {)处抛出错误:

  

SyntaxError(DOM Exception 12):字符串与预期的模式不匹配。

我已尝试专门搜索此错误,我发现this question that talks about missing array endings,但我不认为答案与我的问题有关。

我有一个正则表达式解决方法,它将删除违规规则,因此该函数至少可以运行,但正如您所看到的,该规则中的属性({background-color:black;})在输出中完全被忽略,即使它们&# 39;重新应用于渲染元素。

我可以修改我的正则表达式来解析字符串并切除有问题的选择器,同时保留可解析的规则,但总体来说这种类型的非常特定的黑客对我来说感觉不优雅,而且我关注的是如果我的团队最终添加依赖于那些类型的供应商前缀伪选择器的规则,它可能会导致问题。

关于如何更准确地解决(或解决)这个问题的任何想法?

工作代码段

&#13;
&#13;
window.css = function (a) {
var sheets = document.styleSheets, o = [];
  a.matches = a.matches || a.webkitMatchesSelector || a.mozMatchesSelector || a.msMatchesSelector || a.oMatchesSelector;

  for (var i in sheets) {
    var rules = sheets[i].rules || sheets[i].cssRules;
    for (var r in rules) {
      if (a.matches(rules[r].selectorText)) {
          o.push(rules[r].cssText);
      }
    }
  }
  return o;
}
$(document).ready(function(){
  $('button').on('click',function(){
    $('#styles').text(css( $(  $('input').val()  )[0] ));
  });
});
&#13;
div * {border-left:2px solid black;margin:1em 0;padding:.5em;}

a {text-decoration:none;display:block;cursor:pointer;}
#red {color:red;}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" value="#red"><button>Get styles</button>

<div>
  <a id="red">#red anchor</a>
</div>

<aside id="styles"></aside>
&#13;
&#13;
&#13;

Broken Snippet

(只更改是添加1行的CSS)

&#13;
&#13;
window.css = function (a) {
  var sheets = document.styleSheets, o = [];
  a.matches = a.matches || a.webkitMatchesSelector || a.mozMatchesSelector || a.msMatchesSelector || a.oMatchesSelector;

  for (var i in sheets) {
    var rules = sheets[i].rules || sheets[i].cssRules;
    for (var r in rules) {
      if (a.matches(rules[r].selectorText)) {
          o.push(rules[r].cssText);
      }
    }
  }
  return o;
}
$(document).ready(function(){
  $('button').on('click',function(){
    $('#styles').text(css( $(  $('input').val()  )[0] ));
  });
});
&#13;
div * {border-left:2px solid black;margin:1em 0;padding:.5em;}

a {text-decoration:none;display:block;cursor:pointer;}
#red {color:red;}

/* v ADDED THIS LINE - THIS IS THE ONLY CHANGE v */
[type="submit"]::-webkit-inner-spin-button {background-color:black;}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" value="#red"><button>Get styles</button>

<div>
  <a id="red">#red anchor</a>
</div>

<aside id="styles"></aside>
&#13;
&#13;
&#13;

Reg-Ex解决方法

&#13;
&#13;
window.css = function (a) {
  var sheets = document.styleSheets, o = [];
  a.matches = a.matches || a.webkitMatchesSelector || a.mozMatchesSelector || a.msMatchesSelector || a.oMatchesSelector;

  // v NEW FUNCTION v
  function removeVendorPrefixSelectors (selectorText) {
    if (/::-/.test(selectorText)) {
      //do nothing
    } else {
      return selectorText;
    }
  }

  for (var i in sheets) {
    var rules = sheets[i].rules || sheets[i].cssRules;
    for (var r in rules) {

      // v NEW LINE v
      rule = removeVendorPrefixSelectors(rules[r].selectorText);

      if (a.matches(rule)) {
          o.push(rules[r].cssText);
      }
    }
  }
  return o;
}
$(document).ready(function(){
  $('button').on('click',function(){
    $('#styles').text(css( $(  $('input').val()  )[0] ));
  });
});
&#13;
div * {border-left:2px solid black;margin:1em 0;padding:.5em;}

a {text-decoration:none;display:block;cursor:pointer;}
#red {color:red;}

a, [type="submit"]::-webkit-inner-spin-button {background-color:black;}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" value="#red"><button>Get styles</button>

<div>
  <a id="red">#red anchor</a>
</div>

<aside id="styles"></aside>
&#13;
&#13;
&#13;

0 个答案:

没有答案