Как узнать родителя элемента js
Перейти к содержимому

Как узнать родителя элемента js

  • автор:

Свойство parentNode

Свойство parentNode содержит родительский элемент. Существует также почти идентичное свойство parentElement . Отличия: для тега html свойство parentNode возвращает document , а parentElement возвращает null .

Синтаксис

элемент.parentNode;

Пример

Давайте получим родителя элемента #elem и выведем на экран его id :

let elem = document.querySelector(‘#elem’); let >

Результат выполнения кода:

Смотрите также

  • свойство parentElement ,
    которое определяет родительский элемент

Навигация по DOM-элементам

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/dom-navigation.

DOM позволяет делать что угодно с HTML-элементом и его содержимым, но для этого нужно сначала нужный элемент получить.

Доступ к DOM начинается с объекта document . Из него можно добраться до любых узлов.

Так выглядят основные ссылки, по которым можно переходить между узлами DOM:

Посмотрим на них повнимательнее.

Сверху documentElement и body

Самые верхние элементы дерева доступны напрямую из document .

= document.documentElement Первая точка входа – document.documentElement . Это свойство ссылается на DOM-объект для тега . = document.body Вторая точка входа – document.body , который соответствует тегу .

В современных браузерах (кроме IE8-) также есть document.head – прямая ссылка на

Есть одна тонкость: document.body может быть равен null

Нельзя получить доступ к элементу, которого ещё не существует в момент выполнения скрипта.

В частности, если скрипт находится в , то в нём недоступен document.body .

Поэтому в следующем примере первый alert выведет null :

         

В DOM активно используется null

В мире DOM в качестве значения, обозначающего «нет такого элемента» или «узел не найден», используется не undefined , а null .

Дети: childNodes, firstChild, lastChild

Здесь и далее мы будем использовать два принципиально разных термина.

  • Дочерние элементы (или дети) – элементы, которые лежат непосредственно внутри данного. Например, внутри обычно лежат и .
  • Потомки – все элементы, которые лежат внутри данного, вместе с их детьми, детьми их детей и так далее. То есть, всё поддерево DOM.

Псевдо-массив childNodes хранит все дочерние элементы, включая текстовые.

Пример ниже последовательно выведет дочерние элементы document.body :

Обратим внимание на маленькую деталь. Если запустить пример выше, то последним будет выведен элемент . На самом-то деле в документе есть ещё текст (обозначенный троеточием), но на момент выполнения скрипта браузер ещё до него не дошёл.

Пробельный узел будет в итоговом документе, но его ещё нет на момент выполнения скрипта.

Список детей – только для чтения!

Скажем больше – все навигационные свойства, которые перечислены в этой главе – только для чтения. Нельзя просто заменить элемент присвоением childNodes[i] = . .

Изменение DOM осуществляется другими методами, которые мы рассмотрим далее, все навигационные ссылки при этом обновляются автоматически.

Свойства firstChild и lastChild обеспечивают быстрый доступ к первому и последнему элементу.

При наличии дочерних узлов всегда верно:

elem.childNodes[0] === elem.firstChild elem.childNodes[elem.childNodes.length - 1] === elem.lastChild

Коллекции – не массивы

DOM-коллекции, такие как childNodes и другие, которые мы увидим далее, не являются JavaScript-массивами.

В них нет методов массивов, таких как forEach , map , push , pop и других.

var elems = document.documentElement.childNodes; elems.forEach(function(elem) < // нет такого метода! /* . */ >);

Именно поэтому childNodes и называют «коллекция» или «псевдомассив».

Это возможно, основных варианта два:

    Применить метод массива через call/apply :

var elems = document.documentElement.childNodes; [].forEach.call(elems, function(elem) < alert( elem ); // HEAD, текст, BODY >);
var elems = document.documentElement.childNodes; elems = Array.prototype.slice.call(elems); // теперь elems - массив elems.forEach(function(elem) < alert( elem.tagName ); // HEAD, текст, BODY >);

Нельзя перебирать коллекцию через for..in

Ранее мы говорили, что не рекомендуется использовать для перебора массива цикл for..in .

Коллекции – наглядный пример, почему нельзя. Они похожи на массивы, но у них есть свои свойства и методы, которых в массивах нет.

К примеру, код ниже должен перебрать все дочерние элементы . Их, естественно, два: и . Максимум, три, если взять ещё и текст между ними.

Но в примере ниже alert сработает не три, а целых 5 раз!

var elems = document.documentElement.childNodes; for (var key in elems) < alert( key ); // 0, 1, 2, length, item >

Цикл for..in выведет не только ожидаемые индексы 0 , 1 , 2 , по которым лежат узлы в коллекции, но и свойство length (в коллекции оно enumerable), а также функцию item(n) – она никогда не используется, возвращает n-й элемент коллекции, проще обратиться по индексу [n] .

В реальном коде нам нужны только элементы, мы же будем работать с ними, а служебные свойства – не нужны. Поэтому желательно использовать for(var i=0; i

Соседи и родитель

Доступ к элементам слева и справа данного можно получить по ссылкам previousSibling / nextSibling .

Родитель доступен через parentNode . Если долго идти от одного элемента к другому, то рано или поздно дойдёшь до корня DOM, то есть до document.documentElement , а затем и document .

Навигация только по элементам

Навигационные ссылки, описанные выше, равно касаются всех узлов в документе. В частности, в childNodes сосуществуют и текстовые узлы и узлы-элементы и узлы-комментарии, если есть.

Но для большинства задач текстовые узлы нам не интересны.

Поэтому посмотрим на дополнительный набор ссылок, которые их не учитывают:

Эти ссылки похожи на те, что раньше, только в ряде мест стоит слово Element :

  • children – только дочерние узлы-элементы, то есть соответствующие тегам.
  • firstElementChild , lastElementChild – соответственно, первый и последний дети-элементы.
  • previousElementSibling , nextElementSibling – соседи-элементы.
  • parentElement – родитель-элемент.

Зачем parentElement ? Неужели бывают родители не-элементы?

Свойство elem.parentNode возвращает родитель элемента.

Оно всегда равно parentElement , кроме одного исключения:

alert( document.documentElement.parentNode ); // document alert( document.documentElement.parentElement ); // null

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

Модифицируем предыдущий пример, применив children вместо childNodes .

Теперь он будет выводить не все узлы, а только узлы-элементы:

Всегда верны равенства:

elem.firstElementChild === elem.children[0] elem.lastElementChild === elem.children[elem.children.length - 1]

В IE8- поддерживается только children

Других навигационных свойств в этих браузерах нет. Впрочем, как мы увидим далее, можно легко сделать полифил, и они, всё же, будут.

В IE8- в children присутствуют узлы-комментарии

С точки зрения стандарта это ошибка, но IE8- также включает в children узлы, соответствующие HTML-комментариям.

Это может привести к сюрпризам при использовании свойства children , поэтому HTML-комментарии либо убирают либо используют фреймворк, к примеру, jQuery, который даёт свои методы перебора и отфильтрует их.

Особые ссылки для таблиц

У конкретных элементов DOM могут быть свои дополнительные ссылки для большего удобства навигации.

Здесь мы рассмотрим таблицу, так как это важный частный случай и просто для примера.

В списке ниже выделены наиболее полезные:

  • table.rows – коллекция строк TR таблицы.
  • table.caption/tHead/tFoot – ссылки на элементы таблицы CAPTION , THEAD , TFOOT .
  • table.tBodies – коллекция элементов таблицы TBODY , по спецификации их может быть несколько.
  • tbody.rows – коллекция строк TR секции.
  • tr.cells – коллекция ячеек TD/TH
  • tr.sectionRowIndex – номер строки в текущей секции THEAD/TBODY
  • tr.rowIndex – номер строки в таблице
  • td.cellIndex – номер ячейки в строке
 
один два
три четыре

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

Конечно же, таблицы – не исключение.

Аналогичные полезные свойства есть у HTML-форм, они позволяют из формы получить все её элементы, а из них – в свою очередь, форму. Мы рассмотрим их позже.

Интерактивное путешествие

Для того, чтобы убедиться, что вы разобрались с навигацией по DOM-ссылкам – вашему вниманию предлагается интерактивное путешествие по DOM.

Ниже вы найдёте документ (в ифрейме), и кнопки для перехода по нему.

Изначальный элемент – . Попробуйте по ссылкам найти «информацию». Или ещё чего-нибудь.

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

Element.closest()

Метод Element.closest() возвращает ближайший родительский элемент (или сам элемент), который соответствует заданному CSS-селектору или null, если таковых элементов вообще нет.

Синтаксис

var elt = element.closest(selectors);
  • selectors — строка, а точнее DOMString , содержащая CSS-селектор, к примеру: «#id», «.class», «div» .
  • Результат — элемент DOM ( Element ), либо null.

Исключения

Указанный css-селектор не является допустимым («/=21=1», «&@*#», «%’54523» и т.п. приведут к ошибке).

Пример

 
Я ссылка в никуда Я ссылка на сайт

Думаю, стоит рассмотреть несколько примеров:

var div = document.querySelector("#too"); //Это элемент от которого мы начнём поиск div.closest("#block"); //Результат - самый первый блок древа выше div.closest("div"); //Сам блок #too и будет результатом, так как он подходит под селектор "div" div.closest("a"); //null - В предках #too нет ни одного тега "a"! div.closest("div[title]"); //#block - так как ближе нет блоков с атрибутом title. 

Полифил #1 (рекурсивный метод)

Для браузеров не поддерживающих Element.closest(), но позволяющих использовать element.matches() (или префиксный эквивалент) есть полифил:

(function (ELEMENT)  ELEMENT.matches = ELEMENT.matches || ELEMENT.mozMatchesSelector || ELEMENT.msMatchesSelector || ELEMENT.oMatchesSelector || ELEMENT.webkitMatchesSelector; ELEMENT.closest = ELEMENT.closest || function closest(selector)  if (!this) return null; if (this.matches(selector)) return this; if (!this.parentElement)  return null; > else return this.parentElement.closest(selector); >; >)(Element.prototype); 

Полифил #2 (через цикл)

Тем не менее, если вам требуется поддержка IE 8, вы можете использовать следующий полифил. Имейте ввиду — этот способ позволяет использовать CSS селекторы только уровня 2.1 и может жутко тормозить.

(function (e)  e.closest = e.closest || function (css)  var node = this; while (node)  if (node.matches(css)) return node; else node = node.parentElement; > return null; >; >)(Element.prototype); 

Спецификации

Specification
DOM Standard
# ref-for-dom-element-closest①

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также

  • Интерфейс Element .
  • Синтаксис селекторов
  • Другие методы, принимающие селекторы: element.querySelector() и element.matches() .

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 3 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

Как найти родителя родителя родителя в JavaScript?

a58257d8723e48309b0491394561bec8.png

Как найти родителя родителя родительского элемента? Есть блок (см.картинку), в нем есть кнопка ‘.product__shopcard-btn’ мне нужно найти родителя родителя его родительского элемента т.е. ‘.product’ (надеюсь выразился понятно). Способ element.parentNode.parentNode.parentNode работает, но бред же? Интересует чистый js без jquery.

  • Вопрос задан более трёх лет назад
  • 26095 просмотров

7 комментариев

Оценить 7 комментариев

iiiBird

и о каком блоке речь и какого родителя искать?

lazalu68

Sry, но всё же репорт, т.к. по запросу «js element get parent» можно найти всё что нужно.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *