querySelector/getElementByClassName 嵌套项目中的顺序

querySelector/getElementByClassName order in nested items

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

<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')

what would this return and why?

它将return这个元素:

<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)。或者换个说法,就是元素的一个depth-first search


重新编辑:

I want to make sure to always get the element ('.thisClass') from the parent, no matter what is the order of the parent's child elements, and using the best possible script.

完全改变了问题。答案是:你不能为此使用 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;
    }
}

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

#2 对浏览器来说更多的工作,在这种情况下可能很难证明你只是在寻找像 class 名称这样简单的东西,但这是捏造的 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 上创建了一个演示来尝试一下:demo

如您所见,document.querySelector 总是 returns 文档顺序中的第一个元素。