在w3c草案对属性选择器[att~=val]提到一个点,val不能为空白字符,否则比较值flag(flag为val与元素实际值的比较结果)总返回false,而我写选择器过程中,发现这要求对其他操作符也有效果。
<!DOCTYPE html>
<html>
<head>
<title>属性选择器</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script>
window.onload = function(){
console.log(document.querySelector("#test1[title='']"));
console.log(document.querySelector("#test1[title~='']"));
console.log(document.querySelector("#test1[title|='']"));
console.log(document.querySelector("#test1[title^='']"));
console.log(document.querySelector("#test1[title$='']"));
console.log(document.querySelector("#test1[title*='']"));
console.log("===========================================")
console.log(document.querySelector("#test2[title='']"));
console.log(document.querySelector("#test2[title~='']"));
console.log(document.querySelector("#test2[title|='']"));
console.log(document.querySelector("#test2[title^='']"));
console.log(document.querySelector("#test2[title$='']"));
console.log(document.querySelector("#test2[title*='']"));
}
</script>
</head>
<body>
<div title="" id="test1"></div>
<div title="aaa" id="test2"></div>
</body>
</html>
日志: [object HTMLDivElement] 日志: null 日志: [object HTMLDivElement] 日志: null 日志: null 日志: null 日志: =========================================== 日志: null 日志: null 日志: null 日志: null 日志: null 日志: null
换言之,只要val为空,除=或|=外,flag必为false,并且,对于非=,!=操作符,如果取得值为空白字符,flag也必为false。
下面是我第五代选择器Icarus的相关代码:
for (i = 0, ri = 0, elem; elem = elems[i++];) {
if(!op){
flag = Icarus.hasAttribute(elem,name,flag_xml);//[title]
}else if(val === "" && op > 3){
flag = false
}else{
attr = Icarus.getAttribute(elem,name,flag_xml);
switch (op) {
case 1:// = 属性值全等于给出值
flag = attr === val;
break;
case 2://!= 非标准,属性值不等于给出值
flag = attr !== val;
break;
case 3://|= 属性值以“-”分割成两部分,给出值等于其中一部分,或全等于属性值
flag = attr === val || attr.substring(0, val.length + 1) === val + "-";
break;
case 4://~= 属性值为多个单词,给出值为其中一个。
flag = attr !== "" && (" " + attr + " ").indexOf(val) >= 0;
break;
case 5://^= 属性值以给出值开头
flag = attr !== "" && attr.indexOf(val) === 0 ;
break;
case 6://$= 属性值以给出值结尾
flag = attr !== "" && attr.lastIndexOf(val) + val.length === attr.length;
break;
case 7://*= 属性值包含给出值
flag = attr !== "" && attr.indexOf(val) >= 0;
break;
}
}
if (flag ^ flag_not)
tmp[ri++] = elem;
}