jQuery перша дитина "цього"


317

Я намагаюсь передати "це" від натиснутого проміжку до функції jQuery, яка може потім виконати jQuery на першому дочірнім елементі цього клацання. Не можу, здається, все правильно ...

<p onclick="toggleSection($(this));"><span class="redClass"></span></p>

Javascript:

function toggleSection(element) {
  element.toggleClass("redClass");
}

Як я можу посилатись на: первістка елемента?


4
Якщо ви використовуєте jQuery, чому б вам також не зв’язати обробники подій, використовуючи jQuery?
Vivin Paliath

2
тому що обробники подій прив'язки повинні бути ініціалізовані в document.ready (), який додає звернення до продуктивності (це додаток для IE6). чи є інший спосіб?
macca1

Гм .. не впевнений. Зв'язування за допомогою jQuery - це стандартний спосіб (якщо ви вже використовуєте jQuery). Який хіт продуктивності ви відчуваєте, коли використовуєте jQuery(document).ready(...)?
Вівін Паліяф

Це великий додаток із 7+ розробниками. Спочатку було 4+ секунди, перш ніж я спробував її трохи почистити. Тому я краще уникати додати більше цього, коли мені не доведеться :)
macca1

Відповіді:


482

Якщо ви хочете застосувати селектор до контексту, наданого наявним набором jQuery, спробуйте функцію find () :

element.find(">:first-child").toggleClass("redClass");

Джорн Шоу-Роде зазначив, що ви, мабуть, хочете знайти лише першого прямого нащадка елемента контексту, отже, добірника (>). Він також вказує, що ви можете так само добре використовувати функцію дітей () , яка дуже схожа на пошук (), але здійснює пошук лише на рівні рівня в ієрархії (що все, що вам потрібно ...):

element.children(":first").toggleClass("redClass");

1
Дякую! працює чудово. Я думаю, інші способи, перелічені нижче, також будуть працювати.
macca1

6
Я вважаю, що find()пошук здійснюється через усіх нащадків і :first-childможе відповідати одному елементу на одного з батьків. Отже, цей запит, ймовірно, може повернути кілька елементів. Або я помиляюся?
Jørn Schou-Rode

19
Я знаю, що це старе питання / відповідь, але використання ">" селектора без батьків у цьому селекторі амортизується (наприклад, ">: первістка") на jQuery 1.8. Я пропоную замість цього використовувати element.children(":first-child")абоelement.children().first();
Кевін Б

3
@KevinB, мабуть, вони вирішили не зневажити це
Alnitak

1
кращим підходом було б НЕ повторювати всі предмети, а потім вибрати перший, як тут пропонують деякі. Це було б БАД.
vsync


51

Я додав тест jsperf, щоб побачити різницю швидкості для різних підходів, щоб отримати першу дитину (всього 1000+ дітей)

дано, notif = $('#foo')

Способи jQuery:

  1. $(":first-child", notif) - 4 304 Оп / сек - найшвидший
  2. notif.children(":first") - 653 ops / sec - на 85% повільніше
  3. notif.children()[0] - 1416 ops / sec - 67% повільніше

Рідні способи:

  1. JavaScript native ' ele.firstChild- 4,934,323 ops / sec (всі вищезазначені підходи на 100% повільніше порівняно з firstChild)
  2. Рідний DOM ele від jQery: notif[0].firstChild- 4,913,658 ops / sec

Отже, перші 3 підходи jQuery не рекомендуються, принаймні для першої дитини (я сумніваюся, що це було б і з багатьма іншими). Якщо у вас є об'єкт jQuery і вам потрібно отримати первістка, то отримайте нативний елемент DOM від об’єкта jQuery, використовуючи посилання масиву [0] (рекомендовано) або .get(0)скористайтеся ele.firstChild. Це дає такі ж ідентичні результати, що і звичайне використання JavaScript.

всі тести виконуються в Chrome Canary build v15.0.854.0


20
Насправді, firstChildце не дасть таких самих результатів, як children()запити jQuery або селектор. firstChildбуде включати текстові вузли, які рідко бажані. JQuery в contents()функції буде включати їх, але children()не буде. Більш нові браузери підтримують, firstElementChildщо дасть перший дочірній елемент, але IE <9 не підтримує його. Отже, якщо ви користуєтеся, firstChildвам доведеться вручну знайти перший нетекстовий дочірній вузол.
Макс

1
$(":first-child", notif)має бути $(":first", notif)для очікуваної поведінки. Перші повернуть всіх нащадків стихії першої дитини.
Дражен Беловук

18
element.children().first();

Знайдіть усіх дітей і отримайте першого з них.


1
На сьогоднішній день найпростіший і більш ефективний метод .children(':first').
Гра "Подвійний"

3
Наскільки це ефективніше? Здається, що вона отримує всіх дітей, потім бере першого, а не тільки першу дитину.
Ентоні МакГрат

9

Ти намагався

$(":first-child", element).toggleClass("redClass");

Я думаю, ви хочете встановити свій елемент як контекст для вашого пошуку. Можливо, є кращий спосіб зробити це, який якийсь інший гуру jQuery вскочить сюди і викине на вас :)


3
це не вдасться, якщо elementє онуки
Альнітак

4

Я тільки що написав плагін, який використовує, .firstElementChildякщо це можливо, і при необхідності повертається до ітерації над кожним окремим вузлом:

(function ($) {
    var useElementChild = ('firstElementChild' in document.createElement('div'));

    $.fn.firstChild = function () {
        return this.map(function() {
            if (useElementChild) {
                return this.firstElementChild;
            } else {
                var node = this.firstChild;
                while (node) {
                    if (node.type === 1) {
                        break;
                    }
                    node = node.nextSibling;
                }
                return node;
            }
        });
    };
})(jQuery);

Це не так швидко, як чисте рішення DOM, але в тестах jsperf під Chrome 24 це було на пару порядків швидше, ніж будь-який інший метод на основі селектора jQuery.


1
Мені подобається цей плагін - але є 2 питання: 1) Сценарій плагінів не може бути включений в голову, оскільки він document.bodyще не ініціалізований; Лише для кількох дітей (скажімо, менше 10) $('>:first-child',context)це трохи швидше. На продуктивність впливає тільки кількість дітей, а не глибина.
кодофактор

@codefactor хороший момент document.body- я вивчу це.
Альнітак

4

ви можете використовувати DOM

$(this).children().first()
// is equivalent to
$(this.firstChild)


1

будь ласка, використовуйте його, як це перше, дайте ім'я класу, щоб тег p як "myp"

то на використання наступного коду

$(document).ready(function() {
    $(".myp").click(function() {
        $(this).children(":first").toggleClass("classname"); // this will access the span.
    })
})

-3

Якщо ви хочете негайно першої дитини вам потрібно

    $(element).first();

Якщо ви хочете певного першого елемента в домі від свого елемента, тоді використовуйте нижче

    var spanElement = $(elementId).find(".redClass :first");
    $(spanElement).addClass("yourClassHere");

спробуйте: http://jsfiddle.net/vgGbc/2/


11
це просто неправильно - якщо elementвузол DOM, то $(element).first()він еквівалентний $(element), а не його первістка.
Альнітак

1
Погоджено, якщо елементом є DOM-вузол $ (element) .first () еквівалентний $ (element), це спричинило мені проблему з прив'язкою
нокаута JS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.