【问题标题】:How to get individual element's CSS selector/Xpath如何获取单个元素的 CSS 选择器/Xpath
【发布时间】:2020-11-20 22:54:30
【问题描述】:

我想要完成的基本上是获取元素列表(当前使用document.querySelectorAll() 以便使用通用选择器获取元素列表。 例如:获取文档中.note 类的所有元素。

document.querySelectorAll('.note')

因为它从整个 DOM 中收集它们,所以我需要一个 JS 函数来使用与不使用 NodeList 的库不同的函数来迭代所有这些元素,并且我需要它来单独查询所有这些元素(这是一项自动化任务,因此忽略速度带来的好处在这里无关紧要)。

由于这些元素出现在 DOM 的不同部分和层次结构中,我无法使用像 :nth-of-type 这样的 CSS 选择器单独获取它们,我需要每个元素的特定 CSS 选择器/XPath。 例如,对于页面上的所有 .note 类元素,我需要结果类似于:

['.my-first-class .inner .note', 'section .different-class .inner .note', '.profile .profile-notes .note']

这种风格的东西对我非常有帮助。

非常感谢您提供的任何帮助!

【问题讨论】:

  • 我的意见:使用id - 这就是我所做的 - 我在这里受到反对:“查询选择器等等等等!”
  • 是否因为支持旧IE,所以需要使用不使用NodeList的函数?
  • 那么你需要三级父级的列表吗?
  • @iAmOren 如果可以为我没有直接编辑权限的网站上的数百个元素追溯添加 ID,那肯定是有益的。不幸的是,我必须使用我得到的东西,而特定的 CSS/Xpath 就是这样。
  • @camaulay 我不是通过浏览器使用它,而是使用 Nightwatch.js 中内置的自动化测试,Nightwatch 不直接与浏览器交互,而是通过 Selenium 驱动程序,它不会给我回馈节点列表对象。

标签: javascript html css dom css-selectors


【解决方案1】:

我从this answer 借用了generateQuerySelector 函数,并简单地循环了.note 查询选择的结果,确保将NodeList 转换为数组。

const notes = Array.from(document.querySelectorAll('.note'))
notes.forEach(note => {
  console.log(generateQuerySelector(note))
})

function generateQuerySelector (el) {
  if (el.tagName.toLowerCase() == "html")
      return "HTML";
  var str = el.tagName;
  str += (el.id != "") ? "#" + el.id : "";
  if (el.className) {
      var classes = el.className.split(/\s/);
      for (var i = 0; i < classes.length; i++) {
          str += "." + classes[i]
      }
  }
  return generateQuerySelector(el.parentNode) + " > " + str;
}
<div class="content">
  <div class="primary">
    <div class="article">
      <div class="note">
      </div>
    </div>
  </div>
  <div class="secondary">
    <div class="aside">
      <div class="note">
      </div>
    </div>
  </div>
  <div class="note">
  </div>
  <div id="contact-form">
    <div class="note"></div>
  </div>
</div>

【讨论】:

  • 哇,不敢相信我没想到只对父母进行递归!我想我也担心性能,但就像我说的,速度不是一个大问题,所以这很有帮助!我确实注意到这不会唯一标识元素,但我决定通过将先前查询的元素与列表中的当前元素进行比较来解决这个问题,如果它们相同,请根据计数器向选择器添加 nth-child()。谢谢!
  • 啊是的nth-child() 将允许您选择特定的兄弟姐妹,祝你好运!
【解决方案2】:

Css 写不下来,它只能用你想要的方式显示你想要的任何东西

body *{ display: block} /* only if you want single column */  
.wanted::after{ content: ' wanted '; float: right; background: red; color: #000; margin: 0 5px; padding: 0 5px}  
p.wanted::after{ content: 'I am a <p>'; background: #cf8;}  
div.wanted::after{ content: 'I am a <div>'; background: yellow}  
a.wanted::after{ content: 'href me';background: orange}  

<div>div</div>  
<a href="">link</a>  
<p>paragraph</p>  
<a class="wanted">link</a>  
<a href="">link</a>  
<div>div</div>  
<div class="wanted">div</div>  
<a href="">link</a>  
<a class="wanted">link</a>  
<nav class="wanted">nav</nav>  
<div class="wanted"> div </div>  
<div>div</div>  
<p>paragraph</p>  
<div class="wanted"> div </div>  
<p class="wanted">paragraph</p>  
<a href="">link</a>  
<div class="wanted"> div </div>  
<a class="wanted">link</a>  
<a class="wanted">link</a>  
<div class="wanted"> div </div>  
<p class="wanted">paragraph</p>  
<div>div</div>  
<div class="wanted"> div </div>  
<a href="">link</a>  
<div class="wanted"> div </div>  
<p class="wanted">paragraph</p>  
<div>div</div>  
<a class="wanted">link</a>  
<div class="wanted"> div </div>  
<div>div</div>  
<p>paragraph</p>  
<div class="wanted"> div </div>  
<div>div</div>  
<p class="wanted">paragraph</p>  
<a href="">link</a>  
<a class="wanted">link</a>  
<div>div</div>  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2014-09-14
    • 2012-07-18
    • 2011-01-10
    • 2020-03-05
    • 1970-01-01
    • 2023-01-29
    相关资源
    最近更新 更多