浏览器抓取网页(网页开发时需要操作相同类名的元素,不足之处的方法)
优采云 发布时间: 2021-12-15 20:03浏览器抓取网页(网页开发时需要操作相同类名的元素,不足之处的方法)
在网页开发中,我们经常需要对具有相同类名的元素进行操作,即具有相同类名的元素。在昨天的笔试中,我没有回答一个相关的问题:
JavaScript获取页面中带有类test的节点
因此,本文采集了一些相关资料,列举了两种较好的方法和不足之处。我希望你能批评和纠正他们。如果你有更好的方法,我希望你能分享
解决方案1 Jeremy keuth解决方案
Jeremy keuth叔叔在《JavaScript DOM编程艺术》(第二版)(英文:使用JavaScript和文档对象模型编写DOM脚本的web设计)第3章第4节中谈到了getelementsbyclass方法,以及如何在不支持此属性的浏览器(IE6、IE7和IE8,让我们瞧不起它们)中使用此方法,此处摘录并在某些地方进行了修改
HTML5DOM中的一个新方法允许我们通过class属性中的类名访问元素,即getelementsbyclassname。由于该方法相对较新,因此在某些DOM实现中不可用,因此在使用它时应小心。让我们看看这个方法能为我们做什么,然后讨论如何可靠地使用这个方法
与getElementsByTagName方法类似,getelementsbyclassname只接受一个参数,即类名:
副本代码如下:
getElementsByClassName(类)
此方法的返回值类似于getElementsByTagName。它是具有相同类名的元素数组。以下代码行返回一个数组,其中收录类名为“sale”的所有元素:
副本代码如下:
文件。getElementsByClassName(“销售”)
使用此方法,还可以查找具有多个类名的元素。要指定多个类名,只需在字符串参数中用空格分隔类名。例如,在
您将在警告框中看到1,表示只有一个元素匹配,因为只有一个元素同时具有“重要”和“销售”类名。请注意,即使元素的class属性中类名的顺序是“sale-important”,而不是参数中指定的“重要sale”,元素仍将匹配。不仅类名的实际顺序无关紧要,元素是否有更多的类名也无关紧要。与getElementsByTagName一样,getelementsbyclassname和getelementbyid可以组合使用。如果您想知道ID为purchase的元素中有多少类名收录test的列表项,可以先找到特定的对象,然后调用getelementsbyclassname:
副本代码如下:
var购物=文档。getElementById(“购买”)
var销售=购物。getElementsByClassName(“出售”)
这样,sales数组只收录“purchase”列表中具有“sales”类的元素。运行以下代码行以查看sales数组收录两项:
副本代码如下:
警报(sales.length)
这个getElementsByCassName方法非常有用,但它只受较新浏览器(Safari3.1、chorme、Firefox 3和opera9.5及更高版本)的支持。为了弥补这一不足,DOM脚本程序员需要使用现有的DOM方法来实现他们自己的GetElementsByCassName,这有点像成年礼。在大多数情况下,它们的实现过程大致类似于下面的getelementsbyclassname。此功能可应用于新浏览器和旧浏览器
副本代码如下:
函数getElementsByClassName(节点,类名){
if(node.getElementsByClassName){
返回节点。getElementsByClassName(类名称)
}否则{
var结果=[]
var elems=节点。getElementsByTagName(“*”)
for(var i=0;i if(elems[i].className.indexOf(className)!=-1){
结果[结果.长度]=元素[i]
}
}
返回结果
}
}
getelementsbyclassname函数接受两个参数。第一个节点表示DOM树中的搜索起点,第二个类名是要搜索的类名。如果传入节点上已经存在相应的getelementsbyclassname函数,则新函数将直接返回相应的节点列表。如果getElementsByCassName函数不存在,新函数将遍历所有标记以查找具有相应类名的元素
此方法的缺点是它不适用于多个类名
如果您使用此函数模拟之前获取购物清单的操作,则可以编写如下:
副本代码如下:
var购物=文档。getElementById(“购买”)
var销售=购物。getElementsByClassName(购物,“测试”)
控制台。日志(销售)
因此,要解决文章开头的问题,代码如下:
副本代码如下:
买什么
别忘了买这东西
解决方案2罗伯特·尼曼解决方案
有许多方法可以搜索匹配的DOM元素,但很少有真正有效的方法。Jeremy keuth叔叔的方法有一个缺点,即它不能用于多个类名。2008年,Robert Nyman在文章最终的getelements byclassname中提供了自己的解决方案,anno 2008。2005年,罗伯特叔叔给出了他自己的getelementsbyclassname函数。2008年,他修改了一些代码并添加了许多新功能:
1.如果当前浏览器支持GetElementsByCassName函数,请调用本机函数
2.如果当前浏览器支持XPath,请使用它//Little flying fish:查找浏览器中内置的XML文档的强大方法,但浏览器支持并不统一
3.支持搜索多个类名,而不考虑顺序
4.返回一个真实的节点数组,而不是本机节点列表//Little flying fish:本机getElementsByCassName方法返回一个类似于数组的节点列表对象。它具有长度和数字索引属性,但不是数组。无法使用特定于数组的方法,如pop和push。在Robert提供的代码中,NodeList对象被转换为数组。将节点列表对象转换为数组的方法:
副本代码如下:
myList=数组。原型片呼叫(myNodeList)
这是罗伯特叔叔的方法。有些地方我不太懂。我会在研究之后更新它
副本代码如下:
/*
由Robert Nyman开发
代码/许可证:
*/
var getElementsByClassName=函数(类名、标记、elm){
if(document.getElementsByClassName){
getElementsByCassName=函数(类名、标记、elm){
elm=elm | |文件
var元素=elm。getElementsByClassName(类名称)
节点名=(标记)?新的RegExp(“\\b”+标记+”\\b,“i”):null
returnElements=[]
电流
对于(var i=0,il=elements.length;icurrent=elements[i]
如果(!nodeName | | nodeName.test(current.nodeName)){
返回元素。推动(电流)
}
}
返回元素
})
}
else if(文档评估){
getElementsByCassName=函数(类名、标记、elm){
标记=标记| |“*”
elm=elm | |文件
var classes=className。拆分(“”)
classesToCheck=“”
xhtmlNamespace=“”
namespaceResolver=(document.documentElement.namespaceURI==xhtmlNamespace)?xhtmlNamespace:null
returnElements=[]
元素
节点
对于(var j=0,jl=classes.length;jclassesToCheck+=”[收录(concat(“”,@class'),“+classes[j]+”)]”
}
试一试{
元素=文档。求值(“./”+标记+classesToCheck,elm,namespacesolver,0,null)
}
捕获(e){
元素=文档。求值(“./”+标记+classesToCheck,elm,null,0,null)
}
while((node=elements.iterateNext()){
返回元素。推送(节点)
}
返回元素
})
}
否则{
getElementsByCassName=函数(类名、标记、elm){
标记=标记| |“*”
elm=elm | |文件
var classes=className。拆分(“”)
classesToCheck=[]
元素=(标记==“*”&&elm.all)?榆树所有人:埃尔姆。getElementsByTagName(标记)
现在,
returnElements=[]
匹配
对于(var k=0,kl=classes.length;kclassesToCheck.push(新的RegExp(“(^ |\\s)”+classes[k]+”(\\s |$)))
}
对于(var l=0,ll=elements.length;LCCurrent=elements[l]
匹配=假
for(var m=0,ml=classesToCheck.length;mmatch=classesToCheck[m].test(current.className)
如果(!匹配){
中断
}
}
如果(匹配){
返回元素。推动(电流)
}
}
返回元素
})
}
返回getElementsByClassName(className,tag,elm)
})