演示地址:
被 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').
本文介绍了YUI3中两个CSS处理的bug,包括优先级错误导致的样式冲突和属性选择符处理不当导致的选择器失效问题,并提出了相应的解决方案。
1万+

被折叠的 条评论
为什么被折叠?



