最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

HTML JavaScript querySelector to find an element whose child has a specific data attribute - Stack Overflow

programmeradmin2浏览0评论

In my below HTML markup, I'd like to query the <div> that has a data-parent set to "true", and the contained child has data-child-gender set to "true" and inner html is "male".

    <div id="grandparent">
      <div id="parent1" data-parent="true">
        <div id="child1" data-child-gender="false">
          male
        </div>
      </div>
      <div id="parent2" data-parent="true">
        <div id="child2" data-child-gender="true">
          female
        </div>
      </div>
      <div id="parent3" data-parent="false">
        <div id="child3" data-child-gender="true">
          female
        </div>
      </div>
      <div id="parent4" data-parent="true">
        <div id="child4" data-child-gender="true">
          male
        </div>
      </div>
    </div>

In my below HTML markup, I'd like to query the <div> that has a data-parent set to "true", and the contained child has data-child-gender set to "true" and inner html is "male".

    <div id="grandparent">
      <div id="parent1" data-parent="true">
        <div id="child1" data-child-gender="false">
          male
        </div>
      </div>
      <div id="parent2" data-parent="true">
        <div id="child2" data-child-gender="true">
          female
        </div>
      </div>
      <div id="parent3" data-parent="false">
        <div id="child3" data-child-gender="true">
          female
        </div>
      </div>
      <div id="parent4" data-parent="true">
        <div id="child4" data-child-gender="true">
          male
        </div>
      </div>
    </div>

Given the above scenario, the expected <div> is parent4.

What is the JavaScript querySelector to use?

Share Improve this question edited Jun 21, 2019 at 4:52 Akshay Mulgavkar 1,75812 silver badges22 bronze badges asked Jun 21, 2019 at 4:18 Mark UMark U 5551 gold badge8 silver badges19 bronze badges 1
  • You can’t use querySelector to find text content. There will be a manual check involved. – Ry- Commented Jun 21, 2019 at 4:23
Add a ment  | 

3 Answers 3

Reset to default 3

First use querySelectorAll which will give an array. Then iterate over it and check and get element with required data attribute.

After that you can use use a if & check the content inside it

let k = document.querySelectorAll('[ data-parent=true]').forEach(function(item) {
  let elem = item.querySelector('[data-child-gender=true]');
  if (elem !== null && elem.innerHTML.trim() === 'male') {
    console.log(item.id)
  }
})
<div id="grandparent">
  <div id="parent1" data-parent="true">
    <div id="child1" data-child-gender="false">
      male
    </div>
  </div>
  <div id="parent2" data-parent="true">
    <div id="child2" data-child-gender="true">
      female
    </div>
  </div>
  <div id="parent3" data-parent="false">
    <div id="child3" data-child-gender="true">
      female
    </div>
  </div>
  <div id="parent4" data-parent="true">
    <div id="child4" data-child-gender="true">
      male
    </div>
  </div>
</div>

There isn't one querySelector you can use for this (as you can't use it to select specific text within elements). However, you can use .querySelector() with .filter() to get more specific results:

const true_children = [...document.querySelectorAll("[data-parent='true'] [data-child-gender='true']")];
const res = true_children.filter(({innerHTML:g}) => g.trim() === "male");

console.log(res);
<div id="grandparent">
  <div id="parent1" data-parent="true">
    <div id="child1" data-child-gender="false">
      male
    </div>
  </div>
  <div id="parent2" data-parent="true">
    <div id="child2" data-child-gender="true">
      female
    </div>
  </div>
  <div id="parent3" data-parent="false">
    <div id="child3" data-child-gender="true">
      female
    </div>
  </div>
  <div id="parent4" data-parent="true">
    <div id="child4" data-child-gender="true">
      male
    </div>
  </div>
</div>

The problem that the question describes, cannot be solved using query-selectors alone. This is because of following reasons:

  1. The query selectors always works on descendants, so while evaluating that the child div has data-child-gender="true", there will be no way to return the parent element. The query-selector will return the child div.
  2. There is no way to evaluate the inner text or contained text of an element in query-selector.

These two limitations can be worked around by using JavaScript, provided that you were going to use the query-selector in JS.

Something like the following snippet should work.

document.querySelectorAll('div[data-parent=true] div[data-child-gender=true]')
.filter(function(elem) {
  return elem.innerText === 'male'; // filter the elements containing male string.
})[0].parentElement; // return the parent of matched element.

An equivalent logic could be derived for selenium too. Otherwise if this much logic is unacceptable, you can always use the much richer xpath selectors. xpath wouldn't have either of the limitations mentioned above.

发布评论

评论列表(0)

  1. 暂无评论