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

Как получить соседний элемент js

  • автор:

Свойство firstElementChild

Свойство firstElementChild содержит первый дочерний элемент. Дочерними элементами считаются все теги, которые непосредственно расположены внутри блока. Если у элемента нет дочерних элементов — возвращается null .

Синтаксис

элемент.firstElementChild;

Пример

Получим содержимое первого потомка элемента:

1

2

let parent = document.querySelector(‘#parent’); let text = parent.firstElementChild.textContent; console.log(text);

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

Пример

А теперь у элемента нет дочерних элементов и поэтому выведется null :

let parent = document.querySelector(‘#parent’); console.log(parent.firstElementChild);

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

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

  • свойство lastElementChild ,
    которое содержит последний элемент
  • свойство children ,
    которое содержит всех потомков элемента
  • свойство firstChild ,
    которое содержит первый узел

Навигация по 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 и реальным.

js получить дочерний элемент

Рассмотрим пару встроенных возможностей js, чтобы получить дочерний элемент — метод querySelector и свойство children . Например, чтобы получить первый дочерний элемент узла с id «parent», можно написать такой код:

const parent = document.querySelector('#parent'); const firstChild = parent.children[0]; 

Здесь мы сначала получаем элемент с id «parent» с помощью метода querySelector , а затем получаем его первый дочерний элемент с помощью свойства children .

Более специфичными являются методы firstElementChild и lastElementChild , которые также дают возможность обратиться к дочерним элементам: первому и последнему, соответственно.

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.

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

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