确定两个元素之间的关系

Cha*_*lie 1 javascript

假设我有以下 DOM 元素:

<div>test</div>
<div>test</div>
Run Code Online (Sandbox Code Playgroud)

假设我有对每个 div 的引用,但没有对它们的集合的引用。有什么方法可以确定它们之间的关系吗?例如,如果我有div1and div2,有什么方法可以判断是div1之前还是之后(或内部,或者其他什么)div2

我知道我可以使用

var elements = document.querySelectorAll('div');
Run Code Online (Sandbox Code Playgroud)

...然后当然elements[0]是之前elements[1]。但是,如果我没有这些元素的集合,只有单独的引用,有什么方法可以判断吗?

T.J*_*der 5

好的,现在你已经说过问题是关于 JavaScript 的,并且你想知道如何“区分”两个 div 而不使用它们在集合中的位置(querySelectorAll不返回实际的数组,只是非常类似数组的东西) 。我能想到这样做的唯一原因是,如果您没有该集合,您只有对两个 div 的引用,并且想知道文档中哪个排在第一位。

当然,您可以获取集合,然后查找其中的 div,但您也可以使用compareDocumentPosition(链接到规范,规范可能不太清楚;这里是 MDN 文章)。compareDocumentPosition告诉您调用它的元素相对于传递给它的元素的位置:

  • DOCUMENT_POSITION_DISCONNECTED (1)
  • DOCUMENT_POSITION_PRECEDING (2)
  • DOCUMENT_POSITION_FOLLOWING (4)
  • DOCUMENT_POSITION_CONTAINS (8)
  • DOCUMENT_POSITION_CONTAINED_BY (16)
  • DOCUMENT_POSITION_IMPLMENTATION_SPECIFIC (32)

例如:

if (oneDiv.compareDocumentPosition(theOtherDiv) & 2) {
    // oneDiv is prior to theOtherDiv in the document order
} else {
    // could be any of the others, but if we assume that both
    // are actually in the document and that neither contains
    // the other, then theOtherDiv is prior to oneDiv
}
Run Code Online (Sandbox Code Playgroud)

例子:

if (oneDiv.compareDocumentPosition(theOtherDiv) & 2) {
    // oneDiv is prior to theOtherDiv in the document order
} else {
    // could be any of the others, but if we assume that both
    // are actually in the document and that neither contains
    // the other, then theOtherDiv is prior to oneDiv
}
Run Code Online (Sandbox Code Playgroud)
var list = document.querySelectorAll('div');
theoreticalFunction("0, 1", list[0], list[1]);
theoreticalFunction("1, 0", list[1], list[0]);
snippet.log(" "); // Just to move past the divs

function theoreticalFunction(label, oneDiv, theOtherDiv) {
  snippet.log(label);
  // 2 = "preceding"
  if (oneDiv.compareDocumentPosition(theOtherDiv) & 2) {
    snippet.log("theOtherDiv is prior to oneDiv in the document order");
  } else {
    // We're assuming it's following, but of course, there are lots
    // of other possible values:
    // DOCUMENT_POSITION_DISCONNECTED	1
    // DOCUMENT_POSITION_PRECEDING	2
    // DOCUMENT_POSITION_FOLLOWING	4
    // DOCUMENT_POSITION_CONTAINS	8
    // DOCUMENT_POSITION_CONTAINED_BY	16
    // DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC	32
    snippet.log("oneDiv is prior to theOtherDiv in the document order");
  }
}
Run Code Online (Sandbox Code Playgroud)
div {
  position: absolute;
  top: 0px;
  left: 0px;
}
Run Code Online (Sandbox Code Playgroud)


当问题似乎与CSS有关时,原始答案:

听起来正在尝试这样做

  1. 在 CSS 中,以及

  2. 无需向元素添加任何其他识别特征

我不相信你可以,除非它们位于同一个父元素中(或者当然,如果其中一个位于另一个元素内部,但这不是你所显示的),或者除非你可以引用它们的父元素/祖先元素(我们不能在答案中回答,因为问题中没有)。

如果它们属于同一父母,您有两种选择:

如果它们确实如您所显示的那样,彼此相邻,您可以使用相邻的同级组合器,来区分它们+

div + div {
    /* Styles for second div */
}
Run Code Online (Sandbox Code Playgroud)

例子:

<div>test</div>
<div>test</div>
<p id="spacer"></p>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Run Code Online (Sandbox Code Playgroud)
div + div {
    /* Styles for second div */
}
Run Code Online (Sandbox Code Playgroud)

如果它们实际上并不相邻,您可以使用通用同级组合器, ~

div ~ div {
    /* Styles for latter div */
}
Run Code Online (Sandbox Code Playgroud)

例子:

div {
    position: absolute;
    top: 0px;
    left: 0px;
}
div {
  color: blue;
}

div + div {
  top: 20px;
  color: red;
}
Run Code Online (Sandbox Code Playgroud)
<div>test</div>
<div>test</div>
Run Code Online (Sandbox Code Playgroud)