element[attribute]:nth-of-type(n) 选择器的可行性

Posted

技术标签:

【中文标题】element[attribute]:nth-of-type(n) 选择器的可行性【英文标题】:Feasability of element[attribute]:nth-of-type(n) selector 【发布时间】:2016-04-02 15:24:14 【问题描述】:

这个问题与选择器的工作方式有关,不是我遇到的问题。我正在使用一些类似于此的 html

<div class="example">
    <textarea>...</textarea>
    <textarea for="1">foo</textarea>
    <textarea for="2">bar</textarea>
    <textarea for="3">hello</textarea>
    <textarea for="4">world</textarea>
</div>

我试图使用$('.example').children('textarea[for]:nth-of-type(1)') 选择具有for 属性的第一个文本区域。我一直不确定。我重读了documentation 并注意到那行说

选择与其父级的第 n 个子级相对于具有相同元素名称的兄弟级的所有元素。

textarea[for]:nth-of-type(1) 将返回 undefined 是有道理的,因为第一个 textarea 没有 for 属性。

那么我的问题是,element[attribute]:nth-of-type(n) 选择器将来是否有可能返回具有指定属性的第 n 个元素?由于 jQuery/CSS 的工作方式,这是否需要一个全新的选择器?

【问题讨论】:

“将来element[attribute]:nth-of-type(n) 选择器是否有可能返回具有指定属性的第 n 个元素” - 不,因为正如您已经指出的那样,那就是不是:nth-of-type() 的工作方式。它基于元素的标签type。您可能已经知道这一点,但为了记录,您可以使用:eq() 选择器或.eq() 方法通过其索引基于匹配元素的集合 获取元素。在您的情况下,$('.example').children('textarea[for]:eq(0)') - 使用0 的索引,因为eq 是从零开始的,而:nth-of-type 不是, @JoshCrozier 实际上我确实使用了:eq() 选择器。所以我猜想一个全新的选择器需要与属性选择器一起进行第 n 个类型的选择? 【参考方案1】:

那么我的问题是,将来element[attribute]:nth-of-type(n) 选择器是否有可能返回具有指定属性的第 n 个元素?

并非如此,因为:nth-of-type() 中的“类型”具有非常特定的含义,并且因为对于一个简单的选择器来说,根据除了在 DOM 中反映的元素自身特征之外的任何其他条件来匹配元素并不是很直观或类似的。

由于 jQuery/CSS 的工作方式,这是否需要一个全新的选择器?

是的,这就是选择器 4 引入 :nth-match() 的原因,它已成为现有 :nth-child() 的扩展,它仅根据选择器参数考虑元素的子集。请参阅我对this question 的回答。在你的情况下,它会是

$('.example').children(':nth-child(1 of textarea[for])')

这仍然没有在任何地方实现;希望新的一年会有所改变。

由于这是 jQuery,您可以使用 :eq(0),但除非您只有一个这样的 .example 和一个这样的 textarea,否则您可能需要使用 .each() 迭代 .example 元素(感谢如何unintuitive 这些非标准选择器是)。

【讨论】:

这太好了,谢谢!在我看来,整个:nth-child(1 of textarea[for]) 有点丑,但我想我必须处理它。希望浏览器支持很快就会出现。 @mcon:我同意。它的唯一优势在于它的实际作用更加明显。【参考方案2】:

nth-of-type 使用来自实际 DOM 而非过滤列表的索引,因此 nth-of-type(1) 将找到您的第一个 textarea &lt;textarea&gt;...&lt;/textarea&gt; 但您通过 [for] 过滤它 ... nth-of-type(2)&lt;textarea for="1"&gt;foo&lt;/textarea&gt;

nth-of-type(3)&lt;textarea for="2"&gt;bar&lt;/textarea&gt; 等等...

所以答案是否定的,您不能为此使用nth-of-type

要使用“for”获取第一个 textarea 子项,您可以使用 document.querySelector

var first = document.querySelector('.example > textarea[for]');
var first = document.querySelectorAll('.example > textarea[for]')[0];
//or jQuery
var first = $('.example > textarea[for]:eq(0)');

nth-of-type 中的 BTW 索引从 1 开始,而不是从 0...

【讨论】:

【参考方案3】:

在我看来,这不是一个限制,它对模式的实现已经足够好。但不适用于您的情况(选择单个节点),我们也根本不需要它。

在您的情况下,您不需要使用 nth-type-of(n) ,因为您选择的是单个节点而不是具有某种模式的集合,例如 (odd , even , 2n+1)

对于您的情况,您可以尝试以下方法

 $('.example textarea[for]').first()

如果您有一个场景来选择具有 nth-of-type(n) 的节点集。是的,它可以在没有任何问题的情况下工作。

$('.example textarea[for]:nth-of-type(2n)')  This selector is working well enough.

查看演示 > 运行代码片段

$(document).ready(function() 
  setTimeout(function() 
    $('.example textarea[for]:nth-of-type(2n)').css('background-color', 'red');
  , 1000);
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="example">
  <textarea>...</textarea>
  <textarea for="1">foo</textarea>
  <textarea for="2">bar</textarea>
  <textarea for="3">hello</textarea>
  <textarea for="4">world</textarea>
</div>

【讨论】:

以上是关于element[attribute]:nth-of-type(n) 选择器的可行性的主要内容,如果未能解决你的问题,请参考以下文章

在XSLT中test =“element [@attribute]”做了什么?

Element link doesn't have required attribute property

如何添加 element with a href attribut in multipleelement? [duplicate]

Missing &#39;name&#39; key attribute on element activity at AndroidMan

SimpleXML 属性到数组

Eclipse报错:Attribute "xmlns" was already specified for element "web-app".