根据网页内容查找dom元素进行操作的四种方式
比如网页有倒计时功能,只有倒计时结束按钮才出来,这个时候需要js快速进行判断点击,已知条件只有按钮文本的情况下,要进行代码实现。
<body>
<div class="child-1">
<div class="child-1-1">
<div class="child-1-1-1">
<button>
确定
</button>
</div>
</div>
</div>
<div class="child-2">
<div class="child-2-1">
A
</div>
<div class="child-2-2">
<button>
联系我们
</button>
</div>
</div>
</body>
比如目前有个需求是只知道按钮文字—“确定”,不确定dom结构以及class、id的情况下,需要对元素进行点击操作。
方式一,遍历
一开始是想遍历节点,但需要深层遍历dom节点才行,用深层遍历节点判断标签与文本内容是否符合,如果一致则取该节点来进行操作。但这个会有性能问题,不能一直计时器挂着遍历吧。
上面的dom结构其实很像二叉树,可以简化成下图这样:
二叉树遍历的方式可以分为两种,深度优先遍历
和广度优先遍历
深度优先遍历 顺序: 1 2 4 5 7 8 3 6 (二叉树中又叫做先序遍历)
广度优先遍历 顺序:1 2 3 4 5 6 7 8 (二叉树中又叫做层级遍历)
深度遍历查找
let deepDom = (node,tag,text,result=[])=>{
if (node) {
let children = node.children;
for (let i = 0; i < children.length; i++) {
if(children[i].children.length!=0){ //如果还有子节点则继续递归
deepDom(children[i],tag,text,result);
}else if(children[i].tagName == tag.toUpperCase() && children[i].innerText == text){
result.push(children[i])
}
}
}
return result
}
let result_list = deepDom(document.querySelector("body"),"button","按钮的文本") //如果有相同需求,改变后面两个参数即可
result_list[0].click() //如果出现多个相同的情况下再另行判断即可
广度遍历查找
let widthDeepDoom=(node,tag,text)=>{
let stack=[];
let result = []
if(node){
stack.push(node); //压入栈
while(stack.length){
let item=stack.shift(); // 删除数组中的第一个元素 并且返回
let children=item.children;
for(let i=0;i<children.length;i++){
if(children[i].children.length!=0){
stack.push(children[i])
}else if(children[i].tagName == tag.toUpperCase() && children[i].innerText == text){
// result.push(children[i])
result = children[i]
}
}
}
}
return result
}
let result_list = widthDeepDoom(document.querySelector("body"),"button","按钮的文本") //如果有相同需求,改变后面两个参数即可
result_list.click() //点击按钮
方式二,正则
使用正则表达式进行匹配,直接匹配所需的节点信息
let regexpDom = (tag,text)=>{
let reg = new RegExp(`<${tag} .*>${text}<\/${tag}>`, "gi");
return Array.prototype.slice.call(document.querySelectorAll(tag)).filter(function(element) {
var match = element.outerHTML.match(reg);
if (match == null) {
return false;
}
if (match == void 0) {
return false;
}
return true;
})
}
let result_list = regexpDom('button','登录')
result_list[0].click()
参考文档 : how to access DOM elements using javascript Regex - Stack Overflow
方式三,Jquery
使用jquery
的选择器,该选择器可以选取包含指定字符串的元素。
$(":button:contains('按钮的文本')")
这种情况的话,需要网站自带Jquery,否则需要自行添加jq地址进行引用
if(typeof jQuery=="undefined"){
script=document.createElement("script");
script.setAttribute("charset","utf-8");
script.src="http://code.jquery.com/jquery-migrate-1.2.1.min.js";
document.head.appendChild(script);
}
方式四,xpath
目前感觉最好的一种匹配方式,xpath
let matchDOM = document.evaluate("//button[contains(., '按钮的文本')]", document, null, XPathResult.ANY_TYPE, null );
let thisHeading = matchDOM.iterateNext();
if(thisHeading) thisHeading.click();
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。