嵌套项中的querySelector/getElementByClassName顺序

the*_*dnp -4 javascript dom css-selectors selectors-api

我需要了解它是如何工作的,所以我可以编写正确的东西.

<div class="element">
  <div class="content">
    <contents>
    <div class="element">
      <contents>
      <div class="thisClass"></div>
    </div>
  </div>
  <div class="thisClass"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

我有一个包含具有相似结构和类的子元素的元素.如果我做

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

编辑:我想确保始终从父级获取元素('.thisClass'),无论父级子元素的顺序是什么,并使用最好的脚本.

我非常厌倦像工作狂一样工作,我是原生JS的新手,我希望这很清楚.

T.J*_*der 7

var element = document.querySelector('.element'); // this returns the parent
element.querySelector('.thisClass')
Run Code Online (Sandbox Code Playgroud)

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

它将返回此元素:

<div class="element">
  <div class="content">
    <contents>
    <div class="element">
      <contents>
      <div class="thisClass"></div><!-- <===== Here -->
    </div>
  </div>
  <div class="thisClass"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

"为什么"是因为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;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果你可以依靠使用现代十岁上下的浏览器,你可以使用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 = "";
}
Run Code Online (Sandbox Code Playgroud)

你可以看到它是如何工作:我们确保元素有一个id,然后用直接子组合子document.querySelector(没有element.querySelector)寻找与该元素的第一个直接子id.然后我们删除它们,id如果我们设置它.

同样,它对浏览器来说更多,并且代码不短,但如果你有复杂的选择器,可能会有用例......

  • 我想人们很恼火OP甚至没有试图弄明白,因此不应该得到任何答案 (4认同)
  • 但是,阅读querySelector的简单文档会提供该信息 (4认同)
  • 我也只是在回答一个问题,但是我还是贬低了...我想我不会浪费我的时间. (3认同)
  • 谢谢@TJCrowder,这正是我需要知道的:为什么.投票失败的人非常糟糕.我会删除它以防止进一步"成为巨魔". (2认同)
  • @thednp:querySelector在IE8中完全实现. (2认同)