querySelector/getElementByClassName嵌套项的顺序

querySelector/getElementByClassName order in nested items

本文关键字:顺序 嵌套 getElementByClassName querySelector      更新时间:2023-09-26

我需要了解这是如何工作的,这样我才能编写正确的代码。

<div class="element">
  <div class="content">
    <contents>
    <div class="element">
      <contents>
      <div class="thisClass"></div>
    </div>
  </div>
  <div class="thisClass"></div>
</div>

我有一个元素,它包括一个具有类似结构和类的子元素。如果我做

var element = document.querySelector('.element'); // this returns the parent
element.querySelector('.thisClass') // ok I got it so far

编辑:我希望确保始终从父级获取元素(".thisClass"),无论父级的子元素的顺序如何,并使用尽可能好的脚本。

我像一个工作狂一样工作很累,我是一个原生JS的新手,我希望这一点足够清楚。

var element = document.querySelector('.element'); // this returns the parent
element.querySelector('.thisClass')

这会带来什么回报,为什么?

它将返回以下元素:

<div class="element">
  <div class="content">
    <contents>
    <div class="element">
      <contents>
      <div class="thisClass"></div><!-- <===== Here -->
    </div>
  </div>
  <div class="thisClass"></div>
</div>

";为什么";是因为querySelector和类似的方法以文档顺序工作,这是文档从上到下的顺序(例如,就像写成HTML一样)。或者换句话说,这是对元素的深度优先搜索。


重新编辑:

我希望确保始终从父级获取元素(".thisClass"),无论父级的子元素的顺序如何,并使用尽可能好的脚本。

完全改变了这个问题。答案是:你不能用querySelector来做这件事(好吧,这也有点敷衍了事)。你有两个选择:

  1. 循环遍历父元素的childNodes(或children)列表或

  2. 稍微调整一下并使用querySelector

#1是相当明显的,但为了完整性:

var element = document.querySelector('.element');
var targetElement, node;
for (node = element.firstChild; node; node = node.nextSibling) {
    if (node.nodeType === 1 && node.className.match(/'bthisClass'b/)) {
        targetElement = node;
        break;
    }
}

或者,如果您可以使用现代ish浏览器,则可以使用firstElementChildnextElementSibling并跳过nodeType检查。

#2对浏览器来说是更多的工作,在这种情况下可能很难证明你只是在寻找一个简单的东西,比如类名,但以下是伪造querySelector的样子:

var markerId = "some-unique-string-you-know-is-not-used-as-an-id-in-your-document";
var element = document.querySelector('.element');
if (!element.id) {
    element.id = markerId;
}
var targetElement = document.querySelector('#' + markerId + ' > .thisClass');
if (element.id == markerId) {
    element.id = "";
}

您可以看到它是如何工作的:我们确保元素有一个id,然后使用带有document.querySelector(而不是element.querySelector)的直接子组合子来查找带有该id的元素的第一个直接子。然后,如果我们设置了id,我们就会将其删除。

同样,浏览器需要做更多的工作,代码也不短,但如果你有复杂的选择器,可能会有一些用例。。。

尝试以下代码将其可视化:

(function () {
  'use strict'
  var element1 = document.querySelector('.element')
  var element2 = document.querySelector('.thisClass')
  /* .element will have a red border */
  /* .thisClass will have a yellow border */
  element1.style.border = '5px solid red'
  element2.style.border = '5px solid yellow'
})()

我在jsBin上创建了一个演示来尝试:演示

正如您所看到的,document.querySelector总是返回文档顺序中的第一个元素。