演示地址:
被 YUI3 接受了,汗我的英语表达能力:
出错代码:
<!doctype html>
<html>
<head>
<title>yui3 stylesheet bug</title>
<style type="text/css" id="test">
div {
color:red;
}
div{
color:green;
}
a{
color:black;
text-decoration:none;
}
a[href='#'][title='note'] {
color:green;
}
</style>
</head>
<body>
<div>
color should be green
</div>
<a href="#" title="note" >color should be red</a>
<script type="text/javascript" src="http://yui.yahooapis.com/3.1.0/build/yui/yui-min.js"></script>
<script type="text/javascript">
YUI().use("node","stylesheet",function(Y){
var skinCss=Y.StyleSheet("#test");
skinCss.set("a[href='#'][title='note']",{color:"red"});
});
</script>
</body>
</html>
bug1:
由于简单的优先级顺序: 后面的 css 规则覆盖前面的 css 规则。则例子中的 div文字应该显示 绿色,而测试代码页面显示红色(前面的css规则占优了)。
分析代码可知:
YUI3 手动合并具有 相同的选择符的css规则,并删除重复选择符的css规则,但是为了方便删除后的下标处理,采用了从后往前的循环:
for (i = sheet[_rules].length - 1; i >= 0; --i) { r = sheet[_rules][i]; sel = r.selectorText; if (cssRules[sel]) { cssRules[sel].style.cssText += ';' + r.style.cssText; _deleteRule(i); } else { cssRules[sel] = r; } }
则可见:循环到第一条会出现:
cssRules["div"].style.cssText="div {color:green;}";
cssRules["div"].style.cssText+=";"+"div {color:red}";
delete(0);
则虽然第一条规则被删,但是第二条规则已经被改为 div {color:red}
解决之道:
需要从前往后循环
或者:
cssRules[sel].style.cssText += ';' + r.style.cssText;
改做:
cssRules[sel].style.cssText = r.style.cssText+";"+cssRules[sel].style.cssText;
bug2:
由于采用了属性选择符 则该bug只对应于 no-ie6,由测试代码发现动态添加的"a[href='#'][title='note']",{color:"red"}根本没起作用。
分析代码:
实际上yui3认为 a[href='#'][title='note'](Multiple attribute selectors ) 为无效:
isValidSelector : function (sel) { var valid = false; if (sel && isString(sel)) { if (!selectors.hasOwnProperty(sel)) { // TEST: there should be nothing but white-space left after // these destructive regexs selectors[sel] = !/\S/.test( // combinators sel.replace(/\s+|\s*[+~>]\s*/g,' '). // attribute selectors (contents not validated) replace(/([^ ])\[.*?\]/g,'$1'). // pseudo-class|element selectors (contents of parens // such as :nth-of-type(2) or :not(...) not validated) replace(/([^ ])::?[a-z][a-z\-]+[a-z](?:\(.*?\))?/ig,'$1'). // element tags replace(/(?:^| )[a-z0-6]+/ig,' '). // escaped characters replace(/\\./g,EMPTY). // class and id identifiers replace(/[.#]\w[\w\-]*/g,EMPTY)); } valid = selectors[sel]; } return valid; }
可以简单实验:
YUI().use("node","stylesheet",function(Y){ alert(Y.StyleSheet.isValidSelector("a[href='#'][title='note']")); });
解决之道:
// attribute selectors (contents not validated) //需要修正!加上 + 允许重复 replace(/([^ ])(\[.*?\])+/g,'$1').