выбор корневого элемента в jquery - PullRequest
7 голосов
/ 30 октября 2009

Мне нужно иметь возможность выбрать корневой элемент из фрагмента , не зная типов узлов, класса, идентификатора или иерархии.

<div id="0">
    <div id="0a">
        <div id="a01"></div>
    </div>
    <div id="0b">
    </div>
    <div id="0c">
    </div>
</div>

Я хочу иметь возможность делать что-то вроде $ (': root') и выбрать 0 в приведенном выше примере.

Еще лучше, я бы предпочел $(':level(0)'), что означало бы то же, что и выше, $(':level(1)') выберет 0a, 0b и 0c, а $(':level(1)>div') выберет a01.

Есть идеи, как это сделать аккуратно?

Ответы [ 9 ]

4 голосов
/ 04 ноября 2009

ОК, поэтому вам нужно сделать следующее (при условии, что вы используете полученный пример), если вы хотите найти узел верхнего уровня с помощью jquery, выполните следующие действия:

 $('*:not(* *)');  

Здесь вы буквально просите все узлы, которые не являются потомками других узлов. Проблема в том, что для HTML-документа это всегда даст вам только HTML-элемент, который не особенно полезен. Итак, если вы хотите найти элемент верхнего уровня в теле html-документа, вы бы использовали что-то намного более простое:

 $('body > *');

если бы вы тогда хотели второй уровень, вы бы просто пошли

 $('body > * > *');

Но, предполагая, что у вас есть какая-то произвольная структура документа (например, foo, которую вы упоминаете), вы можете использовать первый пример, чтобы найти первый уровень:

 $('*:not(* *)');

и затем для второго уровня

 $('*:not(* *)').find('> *');

и для третьего уровня

 $('*:not(* *)').find('> * > *');

и так далее, и тому подобное. Если вы ищете корневой элемент div (предполагая, что ваш образец похож на вопрос), вы можете сделать это:

 $('div:not(div div)');

и т. Д., Заменяя * на div. Не совсем уверен, почему вы хотите это сделать, но это сработает. Проблема в том, что вопрос не дает нам достаточного контекста, чтобы дать вам лучшую альтернативу.

3 голосов
/ 06 октября 2012

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

$(':eq(0)');

Это выберет первый найденный нетекстовый элемент, поэтому, если dom, через который вы проходите, является недопустимым в его формировании, вы всегда должны получить корневой элемент. Это также очень оптимальный вариант, потому что jQuery должен знать, что нужно остановиться после первого найденного элемента.

Итак, вот кое-что для всех поклонников WSOD:

$(':eq(0)').remove();

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

$(fragment).filter(':eq(0)');

Однако при работе с фрагментами вы можете просто сделать следующее:

$(fragment).get(0);

Хотя имейте в виду, что .get(0) может выбирать узлы текста / комментариев, если они являются первым элементом в вашем документе, тогда как подход фильтра всегда найдет первый фактический элемент.

2 голосов
/ 20 августа 2013

Если у вас есть элементы в виде фрагмента jQuery, например:

var myElements = $('<div id="0">
<div id="0a">
    <div id="a01"></div>
</div>
<div id="0b">
</div>
<div id="0c">
</div>
</div>');

тогда вы можете найти первый элемент по:

myElements.filter(":first")

Функция фильтра просматривает корневой элемент фрагмента.

2 голосов
/ 30 октября 2009

Я скорее из Prototype, но я думаю, что вы можете получить все узлы, а затем получить первый узел в массиве:

$('*')[0]

Затем получите дочерние элементы этого (для 0a, 0b и 0c)

$('*')[0].children()
1 голос
/ 05 ноября 2009

Я, возможно, неправильно понимаю вопрос, но если предположить, что под корнем вы подразумеваете точку, в которой родительский тег отличается от дочернего, тогда должно работать следующее:

function GetRoot(element) {
    while(element.parent().attr("tagName") == element.attr("tagName")) {
        element = element.parent();
    }

    return element;
}

Это в основном идет вверх по дереву, пока не находит родителя с другим тегом, а затем возвращает элемент. Для вашего примера это будет означать, что если ваш элемент находится в, или что-то еще, он обнаружит его как корень и вернет его.

Создание пользовательского селектора jquery с этим тоже возможно, но, очевидно, более сложно.

Также должно быть довольно легко расширить это, чтобы взять целое число, которое определяет уровень. Все, что вам нужно сделать, это пройтись по дереву на указанную глубину, как только вы найдете корень, и вернуть эти элементы.

1 голос
/ 30 октября 2009

jQuery не нужен ...

var root = document.firstChild;
0 голосов
/ 16 марта 2013

Если вы хотите выбрать родительский элемент верхнего уровня, но все еще под телом, я бы пошел

$(obj).parents().filter('body > *')
0 голосов
/ 24 декабря 2012

Я получаю html-фрагмент из вызова ajax, и мне также нужно получить от него root div. Я просто назвал $(data), и jQuery проанализирует возвращаемый текст как HTML и даст вам корень.

$.ajax path,
  type: 'GET'
  contentType: 'application/x-www-form-urlencoded;charset=UTF-8'
  success: (data) ->
    $(data)
0 голосов
/ 30 октября 2009

вы можете изучить использование функций parent () и children (). если вам нужно пройти несколько уровней, вы можете соединить их так.

$("#a01").parent().parent()  //returns <div id="0">

см. Мой комментарий, и я постараюсь найти лучшее решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...