2010-01-19 6 views
16

Это удивило меня, что Sizzle (селекторный двигатель jQuery использует) имеет встроенный селектор :nth-child(), но не имеет селектора :nth-of-type().: nth-of-type() в jQuery/Sizzle?

Чтобы проиллюстрировать разницу между :nth-child() и :nth-of-type() и проиллюстрировать эту проблему, рассмотрят the following HTML document:

<!doctype html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <title>:nth-of-type() in Sizzle/jQuery?</title> 
    <style> 
    body p:nth-of-type(2n) { background: red; } 
    </style> 
</head> 
<body> 
    <p>The following CSS is applied to this document:</p> 
    <pre>body p:nth-of-type(2n) { background: red; }</pre> 
    <p>This is paragraph #1.</p> 
    <p>This is paragraph #2. (Should be matched.)</p> 
    <p>This is paragraph #3.</p> 
    <p>This is paragraph #4. (Should be matched.)</p> 
    <div>This is not a paragraph, but a <code>div</code>.</div> 
    <p>This is paragraph #5.</p> 
    <p>This is paragraph #6. (Should be matched.)</p> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
    <script> 
    $(function() { 
    // The following should give every second paragraph (those that had red backgrounds already after the CSS was applied) an orange background. 
    // $('body p:nth-of-type(2n)').css('background', 'orange'); 
    }); 
    </script> 
</body> 
</html> 

С Шипением использует браузер родной querySelector() и querySelectorAll() методы, если таковые присутствуют (т.е. в браузерах, которые уже применяют Selectors API), прочее $('body p:nth-child'); обязательно работа. Однако он не будет работать в старых браузерах, потому что Sizzle не имеет метода возврата для этого селектора.

Можно ли легко добавить селектор :nth-of-type() в Sizzle или реализовать его в jQuery (возможно, используя the built-in :nth-child() selector)? A custom selector with parameters было бы здорово.

+2

Не уверен, но не будет '$ ('p: even')' дать вам то, что вы ищете? У вас уже есть селектор ('p'), поэтому вам просто нужно его отфильтровать. – Kobi

+1

@ Kobi: Это не так просто. Селектор 'p: nth-child (2n)' будет соответствовать каждому второму абзацу * в каждом родительском элементе *. Если есть два DIV, оба из которых содержат три абзаца, следующие абзацы (в порядке DOM) будут сопоставляться с: p: nth-child (2n) ': # 2, # 5. Видеть? Дело не только в том, чтобы получить каждый «P» в документе, а затем отфильтровать его на каждый * mn * th elementh. Да, '$ ('p: even')' является псевдонимом для '$ ('p: nth-child (2n)')', но не для '$ ('p: nth-of-type (2n) «)'. Кроме того, я использую '2n' в этом примере, но, конечно же, должны быть возможны и другие варианты. –

+0

Получил это и удалил мой ответ. – Kobi

ответ

14
/** 
* Return true to include current element 
* Return false to exclude current element 
*/ 
$.expr[':']['nth-of-type'] = function(elem, i, match) { 
    if (match[3].indexOf("n") === -1) return i + 1 == match[3]; 
    var parts = match[3].split("+"); 
    return (i + 1 - (parts[1] || 0)) % parseInt(parts[0], 10) === 0; 
}; 

Test case - (проверка в IE или переименовать селектор)

Вы, конечно, можете добавить даже & нечетное тоже:

match[3] = match[3] == "even" ? "2n" : match[3] == "odd" ? "2n+1" : match[3]; 

+1

Прохладный! Это то, что я искал; короткое, умное, сжатое решение. Как вы знаете, ': odd' и': even' уже поддерживаются в jQuery, просто не в форме ': nth-of-type (odd)'/': nth-of-type (even)', но это приятно иметь их там, а также ради полноты. –

+0

Обновление: еще больше селекторов, см. Https://github.com/keithclark/JQuery-Extended-Selectors –

+1

Приятно, но я просто хотел предупредить других об этом решении, всегда принимая периодичность (n). Я имею в виду, что фильтр типа ': nth-of-type (2n)' и ': nth-of-type (2)' будет таким же (когда последним должен быть только 2-й элемент, а не все четные элементы) , –

1

Я не могу притворяться, что знаю, как реализуется nth-of-type, но jQuery действительно обеспечивает механизм, с помощью которого вы можете создать свой собственный пользовательский селектор.

Следующий вопрос имеет дело с пользовательскими селекторов, и может предоставить полезную информацию для Вас

What useful custom jQuery selectors have you written?

+0

Да, я знаю об этом ... Вероятно, я должен добавить это к своему сообщению. –

4

плагин JQuery moreSelectors поддерживает п-о-типа (и многие другие селекторы). Я предлагаю либо использовать это, либо просто реализовать простой плагин, который реализует только точные селектор, который вам нужен. Вы должны иметь возможность копировать-вставить код оттуда.

Счастливый взлом!

 Смежные вопросы

  • Нет связанных вопросов^_^