dom选择器
2017/05/04
github项目地址:https://github.com/liupishui/domQuery
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/test.scss">
</head>
<body style="background:#f00;">
<div>
ffff
</div>
<div>
<div>
gg
<a href="mailto:joe@example.com?subject=feedback" "email me">email me</a>
</div>
</div>
<div id="rest">
</div>
</body>
<script type="text/javascript">
//选择器 html .test a
function _(selectorStr){
if(typeof(document.querySelectorAll)=='function'){
return document.querySelectorAll(selectorStr);
}
var documentAll=document.getElementsByTagName('*');
var selectorStr=selectorStr.replace(/s+/g,' ').replace(/^s+/,'').replace(/s+$/,'');
var selectorArr=selectorStr.split(' ');
var selectorNodesBase=[];//存放匹配最底层的元素
var selectorNodesResult=[];//存放过滤后的元素
var selectorBase=selectorArr.pop();
//获取所有的最底层Dom元素
if(selectorBase.indexOf('.')!=-1){//如果是class
var queryClassName=selectorBase.substr(1);
if(typeof(getElementsByClassName)=='function'){
var eleClassName=document.getElementsByClassName('queryClassName');
for(var x=0;x<eleClassName.length;x++){
selectorNodesBase.push(eleClassName[x]);
}
}else{
for(var i=0;i<documentAll.length;i++){
if(typeof(documentAll[i].className)!='undefined'){
var eleClassNameN=' '+documentAll[i].className+' ';
if(eleClassNameN.indexOf(' '+queryClassName+' ')!=-1){
selectorNodesBase.push(documentAll[i]);
};
}
}
}
}else if(selectorBase.indexOf('#')!=-1){//如果是ID
selectorNodesBase.push(document.getElementById(selectorBase.substr(1)));
}else{//如果是TagName
var eleTagName=document.getElementsByTagName(selectorBase);
for(var x=0;x<eleTagName.length;x++){
selectorNodesBase.push(eleTagName[x]);
}
}
//过滤所有的符合底层的元素
for(var i=0;i<selectorNodesBase.length;i++){
var filterEachElement=function(ele,selectorArr){
var isMatch=false,eleBase=ele,selectorArr;
//已知,最底层元素ele和selectorArrNow(父级所有选择器)
//判断 该元素是否在这个选择器下面
//递归向上查找,找到上个节点,返回上个节点,继续查找上个节点上面的选择器对应的元素
//找到html根节点前找到了,isMath=true
var queryParent=function(eleParentNode,selectorStr){
if(eleParentNode==document){
isSelectorStr=false;
}else{
var isSearch=false;
if(selectorStr.indexOf('.')!=-1){//如果是class
var queryClassName=selectorStr.substr(1);
if(typeof(eleParentNode.className)!='undefined'){
var eleClassNameN=' '+eleParentNode.className+' ';
if(eleClassNameN.indexOf(' '+queryClassName+' ')!=-1){
isSearch=true;
rstParent=eleParentNode;
};
}
}else if(selectorStr.indexOf('#')!=-1){//如果是ID
if(document.getElementById(selectorStr.substr(1))==eleParentNode){
isSearch=true;
rstParent=eleParentNode;
}
}else{//如果是TagName
//console.log(eleParentNode,selectorStr);
//console.log(eleParentNode.tagName.toLowerCase(),selectorStr);
if(eleParentNode.tagName.toLowerCase()==selectorStr.toLowerCase()){
isSearch=true;
rstParent=eleParentNode;
}
}
if(!isSearch){
//console.log(ele,eleParentNode.parentNode,selectorStr);
queryParent(eleParentNode.parentNode,selectorStr);
}
}
}
var t=selectorArr.length;
if(t==0){
isMatch=true;
}else{
var eleParentNodeNow=ele,rstParent='',isSelectorStr=true;
while(t--){//按选择器从下到上一级一级查找
var selectorStr=selectorArr[t];
if(!isSelectorStr){
return;
}
if(selectorArr[t]=='*'){
if(eleParentNodeNow.parentNode==document){
isSelectorStr=false;
}else{
eleParentNodeNow=eleParentNodeNow.parentNode;
}
}else{
queryParent(eleParentNodeNow.parentNode,selectorArr[t]);
eleParentNodeNow=rstParent;
}
if(t==0){
if(isSelectorStr){
isMatch=true;
}
}
}
}
if(isMatch){
selectorNodesResult.push(eleBase);
}
}
filterEachElement(selectorNodesBase[i],selectorArr);
}
return selectorNodesResult;
// console.log(selectorNodes);
}
var arrDiv=_('* * * * * * * div');
document.write(arrDiv.length);
//_('html .test #nihao a')
</script>
</html>静水缘首页
文章分类
最新文章
- nodejs私钥加密公钥解密的一个例子
- uniapp和微信小程序判断程序运行在开发或者测试或者线上版本的方法分别是什么
- electron使用electron-builder打包后模块包含exe文件执行失败
- Compile is disallowed on the main thread, if the buffer size is larger than 4KB
- better-sqlite3简介及常用操作
- nodejs 操作数据库的库
- nodejs使用http-proxy库实现多个域名代理和同时代理websocket的例子,代理包含https和http两种协议
- iis配置反向代理
- javascript伪多线程代码
- ip所在地址段判断