【问题标题】:How do you grab an element relative to an Element instance with a selector?如何使用选择器获取相对于 Element 实例的元素?
【发布时间】:2016-01-30 14:54:19
【问题描述】:

我正在写一个small library,我需要通过querySelector 方法选择与目标元素相关的元素。

例如:

HTML

<div class="target"></div>
<div class="relative"></div>

<!-- querySelector will select only this .target element -->
<div class="target"></div>
<div class="relative"></div>

<div class="target"></div>
<div class="relative"></div>

JavaScript

var target = document.querySelectorAll('.target')[1];

// Something like this which doesn't work actually
var relativeElement = target.querySelector('this + .relative');

在上面的例子中,我试图选择 .relative 类元素,该元素仅与 .target 元素相关,其值存储在 target 变量中。任何样式都不应应用于其他 .relative 类元素。

PS:选择器可能会有所不同。所以,我不能使用 JavaScript 的预定义方法,例如 previousElementSiblingnextElementSibling

我不需要 jQuery 或其他 JavaScript 库中的解决方案。

【问题讨论】:

  • 关系是否总是兄弟关系(相邻或一般)关系(或)可以是子/后代、兄弟的子等?
  • @Harry 它可以是任何东西。就像 CSS 选择器一样。

标签: javascript html css-selectors


【解决方案1】:

理想情况下应该是这样的:

var relativeElement = target.querySelector('.relative');

但这实际上会尝试选择目标元素内的某些内容。 因此,只有当您的 html 结构类似于:

<div class="target">
 <div class="relative"></div>
</div>

在这种情况下,您最好的选择可能是使用nextElementSibling,我知道您很难使用它。

【讨论】:

    【解决方案2】:

    你不能。 如果你坚持使用主题元素的querySelector,答案是没有办法。

    规范和MDN 都明确表示Element.querySelector 必须返回“调用它的元素的后代”,而您想要的对象元素不满足此限制。

    你必须上去并使用其他元素,例如document.querySelector,如果你想爆发。

    您始终可以覆盖Element.prototype.querySelector 来进行竞价,包括实施您自己的 CSS 引擎,该引擎以您想要的任何语法选择您想要的任何元素。 我没有提到这一点,因为你会破坏一个非常重要的功能的假设,很容易破坏其他库甚至正常代码,或者充其量会减慢它们的速度。

    【讨论】:

    • 但是总有一种解决方法..对吗?我要求同样的。
    • 就像我在 JS 聊天室中所说的那样 - 你可以实现自己的 CSS 引擎来支持 this 并覆盖默认的 querySelector。你想走这条路线吗?
    【解决方案3】:
    target.querySelector('.relative');
    

    通过在目标而不是文档上使用 querySelector,您可以将 DOM 遍历范围限定为目标元素。 从你的解释中并不完全清楚,但我认为你的意思是后代?

    要获取所有可以使用的目标元素

    document.querySelectorAll('.target')
    

    然后迭代结果

    【讨论】:

      【解决方案4】:

      我找到了一种适用于我的图书馆的方法。

      我将用唯一的自定义属性值替换 querySelector 中的 "this "。像这样的:

      Element.prototype.customQuerySelector = function(selector){
          // Adding a custom attribute to refer for selector
          this.setAttribute('data-unique-id', '1');
      
          // Replace "this " string with custom attribute's value
          // You can also add a unique class name instead of adding custom attribute
          selector = selector.replace("this ", '[data-unique-id="1"] ');
      
          // Get the relative element
          var relativeElement = document.querySelector(selector);
      
          // After getting the relative element, the added custom attribute is useless
          // So, remove it
          this.removeAttribute('data-unique-id');
      
          // return the fetched element
          return relativeElement;
      }
      
      var element = document.querySelectorAll('.target')[1];
      var targetElement = element.customQuerySelector('this + .relative');
      
      // Now, do anything with the fetched relative element
      targetElement.style.color = "red";
      

      Working Fiddle

      【讨论】:

      • 如果我输入规则“this + #this.this[attr=this]”会怎样?
      • 这里的this 只是具体的元素。我看不出我会多次使用它的原因。在这种情况下,你上面提到的字符串是无效的。
      • 我的意思是,简单的字符串替换(regx 或 nor)不能替换正确的 css 规则解析。 “this”可以是任何类名、id 或属性选择器的一部分。当然这是你的图书馆,所以你总是可以说你知道你需要什么,我就到此为止。
      猜你喜欢
      • 2014-11-15
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 2021-06-26
      • 2014-10-15
      • 2012-03-29
      • 1970-01-01
      相关资源
      最近更新 更多