如何创建一个函数generateSelector来生成DOM元素的CSS选择器路径
在这篇文章中,我们将学习关于 CSS 选择器,并且我们还将实现一个generateSelector()函数,它返回一个字符串值来提供有效的选择器给目标DOM元素。
**什么是 **CSS选择器?
CSS选择器用于选择遵循特定模式的一组元素(或DOM树中的节点)。
示例: 下面是CSS选择器的一个示例。
HTML
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
/* h2 selector selects all the h2
elements present in body */
h2 {
background-color: red;
}
/* div > h3 selector selects all the
h3 elements which are direct
descendants of div */
div>h3 {
background-color: blue;
}
</style>
</head>
<body>
<h2>Welcome To GFG</h2>
<div>
<h3>Hello World!</h3>
</div>
</body>
</html>
输出:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h2>Welcome To GFG</h2>
<div>
<h3>Hello World!</h3>
<div>
<p>Some random text</p>
</div>
</div>
<script>
let target = document.querySelector('h3');
generateSelector(target);
// Expected output -
//"HTML > BODY:nth-child(2) > DIV:nth-child(3) > H3"
target = document.querySelector('h2');
generateSelector(target);
// "HTML > BODY:nth-child(2) > H2:nth-child(2)"
target = document.querySelector('p');
generateSelector(target);
// "HTML > BODY:nth-child(2) > DIV:nth-child(3)
// > DIV:nth-child(2) > P"
</script>
</body>
</html>
上述代码只是一个伪代码,没有对generateSelector函数进行具体实现。这只是为了帮助你理解这个函数的作用。我们将在下一节中实现这个函数。
预期输出:
HTML > BODY:nth-child(2) > DIV:nth-child(3) > H3
HTML > BODY:nth-child(2) > H2:nth-child(2)
HTML > BODY:nth-child(2) > DIV:nth-child(3) > DIV:nth-child(2) > P
示例:
实现 generateSelector()函数: 现在,我们对generateSelector函数有了很好的理解,让我们试着实现它。
HTML
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h2>Welcome To GFG</h2>
<div>
<h3>Hello World!</h3>
<div>
Some random text
</div>
</div>
<script>
// Let's write a generateSelector() function
// that should return selector path to h3
// inside the div
const generateSelector = (target) => {
const selectorPath = [];
while (target.tagName) {
let i = 0;
if (target.parentNode) {
const children = target.parentNode.children;
while (i < children.length && children[i] !== target) {
i++;
}
}
selectorPath.unshift(target.nodeName + (
i > 0 ? `:nth-child(${i + 1})` : ''));
target = target.parentNode;
}
return selectorPath.join(' > ');
}
let target = document.querySelector('h3');
console.log(generateSelector(target));
// Expected output -
// "HTML > BODY:nth-child(2) > DIV:nth-child(3) > H3"
target = document.querySelector('h2');
console.log(generateSelector(target));
// "HTML > BODY:nth-child(2) > H2:nth-child(2)"
target = document.querySelector('p');
console.log(generateSelector(target));
// "HTML > BODY:nth-child(2) > DIV:nth-child(3)
// > DIV:nth-child(2) > P"
</script>
</body>
</html>
让我们逐步解读上述代码 –
- 我们创建一个 selectorPath 数组,以反向顺序存储选择器元素(当我们从目标元素向上遍历DOM树时,我们会逐层包含选择器元素)
- 我们运行一个循环,向上遍历DOM树,直到达到一个 NULL ,即遍历到DOM树的根节点。
- 我们遍历目标元素的 parentNode 的子元素,直到我们遍历到目标元素为止。通过这样做,我们可以确定目标元素在其父元素的子元素中的索引,从而将其添加到选择器中。
- 我们更新 selectorPath 数组,将当前选择器路径的值添加进去,同时将目标元素更新为其父元素。
- 我们继续重复以上步骤,直到遍历完整个DOM树。
- 循环结束后,我们使用’>’符号将selectorPath数组元素连接在一起,这表示父元素的子元素是一个CSS选择器。
- 结果字符串就是我们要找的最终CSS选择器字符串。
输出:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>Welcome to GFG</h1>
<div>
<h2>Random text</h2>
<button>Click me</button>
Hello world
</div>
<script>
// Let's write a generateSelector() function
// that should return selector path to h3
// inside the div
const generateSelector = (target) => {
const selectorPath = [];
while (target.tagName) {
let i = 0;
if (target.parentNode) {
const children = target.parentNode.children;
while (i < children.length && children[i] !== target) {
i++;
}
}
selectorPath.unshift(target.nodeName +
(i > 0 ? `:nth-child(${i + 1})` : ''));
target = target.parentNode;
}
return selectorPath.join(' > ');
}
let target = document.querySelector('h1');
console.log(generateSelector(target));
target = document.querySelector('h2');
console.log(generateSelector(target));
target = document.querySelector('button');
console.log(generateSelector(target));
target = document.querySelector('p');
console.log(generateSelector(target));
</script>
</body>
</html>
输出:

极客教程