jQuery первый дочерний элемент этого

Я пытаюсь передать «this» из диапазона, по которому щелкнул элемент, в функцию jQuery, которая затем может выполнить jQuery для первого дочернего элемента этого элемента. Кажется, не могу понять ...

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

Javascript:

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

Как мне сослаться на: first-child элемента?


person macca1    schedule 16.02.2010    source источник
comment
Если вы используете jQuery, почему бы вам также не привязать обработчики событий с помощью jQuery?   -  person Vivin Paliath    schedule 16.02.2010
comment
потому что обработчики событий привязки должны быть инициализированы в document.ready (), что увеличивает производительность (это приложение для IE6). или есть другой способ?   -  person macca1    schedule 16.02.2010
comment
Хм .. не уверен. Связывание с использованием jQuery - стандартный способ (если вы уже используете jQuery). Какого рода снижение производительности наблюдается при использовании jQuery(document).ready(...)?   -  person Vivin Paliath    schedule 16.02.2010
comment
Это большое приложение с 7+ разработчиками. Первоначально это было 4+ секунды, прежде чем я попытался немного его очистить. Так что я бы предпочел не добавлять к нему больше, когда мне не нужно :)   -  person macca1    schedule 16.02.2010


Ответы (10)


Если вы хотите применить селектор к контексту, предоставленному существующим набором jQuery, попробуйте функцию find ():

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

Йорн Скоу-Роде отметил, что вы, вероятно, хотите найти только первого прямого потомка элемента контекста, поэтому дочерний селектор (>). Он также указывает, что с таким же успехом можно использовать children () function, которая очень похожа на find (), но выполняет поиск только на одном уровне в глубине иерархии (т.е. все, что тебе нужно...):

element.children(":first").toggleClass("redClass");
person Shog9    schedule 16.02.2010
comment
Благодарность! работает отлично. Я полагаю, что другие способы, перечисленные ниже, также будут работать. - person macca1; 16.02.2010
comment
Я считаю, что find() выполняет поиск по всем потомкам, а :first-child может соответствовать одному элементу для каждого родителя. Следовательно, этот запрос может вернуть несколько элементов. Или я ошибаюсь? - person Jørn Schou-Rode; 16.02.2010
comment
@ Йорн: вы правы, я не думал об этом - если есть иерархия, то неквалифицированный селектор: первый ребенок даст несколько результатов. - person Shog9; 16.02.2010
comment
Я знаю, что это старый вопрос / ответ, но использование селектора ›без родительского элемента в этом селекторе обесценивается (например,›: firstchild) с jQuery 1.8. Я предлагаю вместо этого использовать element.children(":first-child") или element.children().first(); - person Kevin B; 06.09.2012
comment
@KevinB, видимо, они решили не осуждать его - person Alnitak; 13.02.2013
comment
Лучшим подходом было бы НЕ повторять все элементы, а затем выбирать первый, как некоторые предлагают здесь. Это было бы ПЛОХО. - person vsync; 08.05.2014

Используйте children функцию с _ 2_ selector, чтобы получить единственный первый дочерний элемент element:

element.children(":first").toggleClass("redClass");
person Jørn Schou-Rode    schedule 16.02.2010
comment
element.children () [0] .toggleClass (redClass); - person Zakos; 16.11.2013
comment
@ Закос: TypeError: Object [object HTMLAnchorElement] has no method 'toggleClass' - person Jørn Schou-Rode; 23.11.2013

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

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

Способы jQuery:

  1. $(":first-child", notif) - 4,304 операций в секунду - самый быстрый
  2. notif.children(":first") - 653 операций / сек - на 85% медленнее
  3. notif.children()[0] - 1416 операций в секунду - на 67% медленнее

Собственные способы:

  1. Собственный JavaScript 'ele.firstChild - 4 934 323 операций / сек (все вышеперечисленные подходы на 100% медленнее по сравнению с firstChild)
  2. Собственный элемент DOM из jQery: notif[0].firstChild - 4 913 658 операций / сек.

Итак, первые 3 подхода jQuery не рекомендуются, по крайней мере, для первого ребенка (я сомневаюсь, что так будет и со многими другими). Если у вас есть объект jQuery и вам нужно получить первый дочерний элемент, тогда получите собственный элемент DOM из объекта jQuery, используя ссылку на массив [0] (рекомендуется) или .get(0) и используйте ele.firstChild. Это дает те же результаты, что и при обычном использовании JavaScript.

все тесты проводятся в сборке Chrome Canary v15.0.854.0

person manikanta    schedule 16.08.2011
comment
На самом деле firstChild не даст таких же результатов, как children() jQuery или запросы селектора. firstChild будет включать текстовые узлы, которые редко используются. contents() функция jQuery будет включать их, но children() не будет. Новые браузеры поддерживают firstElementChild, который предоставит первый дочерний элемент, но IE ‹9 не поддерживает его. Итак, если вы используете firstChild, вам нужно вручную найти первый нетекстовый дочерний узел. - person Max; 28.11.2011
comment
$(":first-child", notif) должен быть $(":first", notif) для ожидаемого поведения. Первый вернет всех потомков первого дочернего элемента. - person Drazen Bjelovuk; 06.03.2017

element.children().first();

Найдите всех детей и станьте первым из них.

person Bishal Paudel    schedule 20.12.2015
comment
Безусловно, самый простой метод и более эффективный, чем .children(':first'). - person Gras Double; 05.08.2016
comment
Как это эффективнее? Кажется, что он берет всех детей, затем берет первого, а не только первого ребенка. - person Anthony McGrath; 21.03.2018
comment
@AnthonyMcGrath stackoverflow.com/a/14757072/940098 - person Wtower; 13.12.2020

Ты пробовал

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

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

person theIV    schedule 16.02.2010
comment
это не удастся, если у element есть внуки - person Alnitak; 13.02.2013

вы можете использовать DOM

$(this).children().first()
// is equivalent to
$(this.firstChild)
person Yukulélé    schedule 14.02.2018

Я только что написал плагин, который по возможности использует .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.

person Alnitak    schedule 13.02.2013
comment
Мне нравится этот плагин, но есть 2 проблемы: 1) сценарий плагина не может быть включен в заголовок, потому что document.body еще не инициализирован, 2) Производительность намного лучше, чем у альтернатив, только если количество дочерних узлов очень велико. Только для нескольких детей (скажем, менее 10) $('>:first-child',context) немного быстрее. На производительность влияет только количество детей, а не глубина. - person codefactor; 15.11.2013
comment
@codefactor хороший момент о document.body - я разберусь с этим. - person Alnitak; 15.11.2013

пожалуйста, используйте это так, во-первых, дайте имя класса для тега p, например "myp"

затем используйте следующий код

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

Это можно сделать с помощью такой простой магии:

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

Ссылка: http://www.snoopcode.com/jquery/jquery-first-child-selector

person Prabhakar Undurthi    schedule 10.11.2015

Если вы хотите, чтобы сразу появился первый ребенок, вам нужно

    $(element).first();

Если вам нужен конкретный первый элемент в dom из вашего элемента, используйте ниже

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

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

person Amit Rathod    schedule 30.10.2012
comment
это просто неправильно - если element является узлом DOM, то $(element).first() эквивалентен $(element), а не его первому дочернему элементу. - person Alnitak; 13.02.2013
comment
Согласен, если элемент является узлом DOM $ (element) .first () эквивалентен $ (element), это вызвало у меня проблему с привязкой knockoutJS - person drgn; 06.05.2014