Javascript 如何打印DOM对象的选择器
给定这样的DOM结构:Javascript 如何打印DOM对象的选择器,javascript,arrays,combinations,Javascript,Arrays,Combinations,给定这样的DOM结构: <div> <div> <span> <img/> <i> <span></span> <meter></meter> </i> <a><span></span></a> </span> &l
<div>
<div>
<span>
<img/>
<i>
<span></span>
<meter></meter>
</i>
<a><span></span></a>
</span>
</div>
<nav>
<form>
<input/>
<button></button>
</form>
</nav>
</div>
我的尝试没有成功:
function outputSelectors(array, node) {
var tag = node.tagName
array.push(tag)
for (var i = 0, n = node.children.length; i < n; i++) {
var child = node.children[i]
outputSelectors(array, child)
}
}
outputSelectors([], document.body.children[0])
函数输出选择器(数组、节点){
变量标记=节点标记名
array.push(标记)
for(var i=0,n=node.children.length;i
不确定从这里走到哪里。您可以使用中的
getPath
方法映射页面上的所有元素
最好在您自己的控制台中尝试,因为代码段需要一些时间才能运行,而且代码段的控制台似乎无法正确处理输出
jQuery.fn.extend({
getPath:函数(){
var路径,node=this;
while(节点长度){
var realNode=node[0],name=realNode.localName;
如果(!name)中断;
name=name.toLowerCase();
var parent=node.parent();
var sameTagSiblings=parent.children(名称);
如果(sameTagSiblings.length>1){
allsides=parent.children();
var index=allsibles.index(realNode)+1;
如果(索引>1){
name+=':第n个子项('+index+');
}
}
路径=名称+(路径?'>'+路径:“”);
节点=父节点;
}
返回路径;
}
});
常量等位基因=$(“*”);
const allPaths=allegements.map((_,e)=>$(e.getPath());
console.log(所有路径)代码>
稍微修改解决方案以获取路径,修改一个以获取叶节点
函数getPath(节点)
{
var路径;
while(node.parentNode)
{
name=node.nodeName;
如果(!name)中断;
var parent=node.parentNode;
路径=名称+(路径?'>'+路径:“”);
节点=父节点;
}
返回路径;
}
函数getLeafNodes()
{
var allNodes=document.getElementsByTagName(“*”);
var leafNodes=Array.from(allNodes).filter(函数(elem){
return!elem.hasChildNodes();
});
返回叶节点;
}
var leadNodes=getLeafNodes();
var输出=leadNodes.map(s=>getPath);
控制台日志(输出)代码>
您可以创建递归函数,并使用children()
方法检查当前元素是否包含子元素
const result=[]
const getTag=(el)=>el.prop('tagName').toLowerCase()
函数打印(el,prev=''){
prev=prev.length?prev:getTag(el)
const children=el.children();
如果(!children.length)结果为。推送(上一个)
否则{
children.each(function(){
让tag=getTag($(this))
让str=prev+(prev.length?'>':'')+标记;
打印($(此),str)
})
}
}
打印($(“#开始”))
console.log(结果)
一种可能的非递归方法,从顶部(精确地说是根)到底部:
函数CollectLeafNodePath(根){
常量路径=[];
常量选择器部分=[];
设el=根;
while(el){
常量标记名=el.tagName.toLowerCase();
if(el.childElementCount){
selectorParts.push(标记名);
el=el.firstElementChild;
继续;
}
push(selectorParts.concat([tagName]).join('>');
做{
if(el.nextElementSibling){
el=el.nextElementSibling;
打破
}
el=el.parentNode;
selectorParts.pop();
如果(el==根){
el=零;
}
}while(el);
}
返回路径;
}
const selectors=collectLeafNodePath(document.getElementById('xxx');
控制台日志(选择器)代码>
是否只需要叶节点选择器?是的,只需要叶节点。试试这个^I我正要链接它。使用该代码获取从文档返回的每个元素的路径。querySelectorAll(“*”)
我想知道如何执行该算法,而不是使用内置方法。因此,该算法基本上会找到每个叶节点,然后构建一条到顶部的路径。有趣。这切断了向下遍历节点的算法部分,即jquery中的*
。我想知道是否有一种方法可以在运行时自顶向下构建它,也许这是错误的方法。为什么是jQuery?来自OP:我想知道如何执行该算法,而不是使用内置方法。@Ele:那里没有太多jQuery。只是可读性稍高一点的代码。算法就在那里,用简单的JS。我知道,但我认为jQuery插件的使用非常冗长。@Ele:我添加了一个非jQuery版本:-)现在如果你有重复的兄弟姐妹呢?那么你将不再有有效的选择器。OP在他的问题中没有要求唯一选择器。嗯,这会起作用,但我想尝试自上而下,类似于此:,希望得到类似于这些内容的答案。我想不出来。@gurvinder372:是的,但这不是一个常见的用例HTML@Cerbrus如果需要一个有效的选择器(用于以后的访问),那么我宁愿通过为叶节点生成并分配唯一的ID来实现这一点,并保留这些ID的数组?那么你就没有有效的选择器了。@Cerbrus你能提供一个例子用
替换
吗?你会得到两个“div>div>span>a>span”
,这是无效的。你为什么不使用堆栈段来代替JSFIDLE呢?因为代码段很麻烦。我将用一个片段更新我的答案,但用fiddle构建原型更容易——至少对我来说是这样。
function outputSelectors(array, node) {
var tag = node.tagName
array.push(tag)
for (var i = 0, n = node.children.length; i < n; i++) {
var child = node.children[i]
outputSelectors(array, child)
}
}
outputSelectors([], document.body.children[0])