Рассмотрю два метода, которые похожи внешне и внутренне, как может показаться с первого взгляда. Однако, между ними есть тонкая разница.

Метод first

Метод

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

<div class="wrapper">
  <ul id="primo" class="block">
    <li class="block__item"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
</div>

Вот такая большая разметка

1
div class="wrapper"
с четырьмя блоками
1
ul class="block"
, у каждого из которых есть элементы-потомки
1
li class="block__item"
.

И создам небольшой скрипт на JS/jQuery такого плана:

$(function(){
  var wrapper = $('.wrapper');
  wrapper.find('li:first').addClass('block__item--firstSimple');
});

Работа вышеприведенного js-кода будет сводиться к следующему:

  • создается переменная
    1
    
    wrapper
    
    , в которую помещается результат выборки
    1
    
    $('.wrapper')
    
  • в переменной
    1
    
    wrapper
    
    находим элемент
    1
    
    li
    
    , который является первым в коллекции -
    1
    
    .find('li:first')
    
  • этому элементу добавляется класс -
    1
    
    .addClass('block__item--firstSimple')
    

Код несложный и вроде бы все понятно. Но вот вопрос - а какой элемент

1
li
с точки зрения данного кода является первым в коллекции?

Чтобы не ломать понапрасну голову, приведу сразу ответ:

<div class="wrapper">
  <ul id="primo" class="block">
    <li class="block__item block__item--firstSimple"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
</div>

Вот так - только он один и только этот элемент является первым в коллекции элементов

1
li
.

Это объяснимо, если слегка подумать. В переменной

1
wrapper
хранится коллекция элементов; и элементов
1
li
- в том числе.

Коллекция элементов - это не что иное, как массив. А в массиве только один элемент может быть первым. То есть, иметь индекс 0.

Именно поэтому метод

1
.first()
- это всего лишь синоним (alias) другого, более универсального метода
1
.eq()
и может быть записан таким способом -
1
.eq(0)
- вернуть элемент с нулевым индексом, то есть - первый элемент массива.

Антагонистом метода

1
.first()
является метод
1
last()
, который возвращает последний элемент массива. И метод
1
.last()
также можно записать по другому -
1
.eq(-1)
; это также вернет последний элемент массива.

Ок, с методом

1
.first()
вроде разобрались. Двигаемся дальше и рассмотрим метод
1
.first-child()
.

Метод first-child()

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

$(function(){
  var wrapper = $('.wrapper');
  wrapper.find('li:first-child').addClass('block__item--firstChild');
});

Что делает приведенный выше код? А вот что:

  • создает переменную
    1
    
    wrapper
    
    и присваивает ей значение выборки - $(‘.wrapper’)
  • в переменной
    1
    
    wrapper
    
    находим первый элемент
    1
    
    li
    
    -
    1
    
    .find('li:first-child')
    
  • этому элементу присваивается класс -
    1
    
    .addClass('block__item--firstChild')
    

Все просто и вроде бы точно также, как и в случае с методом

1
.first()
. Вроде бы да, но возникает вопрос - а какой элемент
1
li
данный код считает первым в данном случае?

Чтобы не гадать, снова приведу готовый ответ:

<div class="wrapper">
  <ul id="primo" class="block">
    <li class="block__item block__item--firstChild"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item block__item--firstChild"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item block__item--firstChild"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
  <ul class="block">
    <li class="block__item block__item--firstChild"></li>
    <li class="block__item"></li>
    <li class="block__item"></li>
  </ul>
</div>

Вот она - разница в подходе отбора первого элемента. Другими словами, метод

1
.first-child()
находит все элементы, которые являются первыми потомками у своих непосредственных родителей. А в данном случае таких потомков насчиталось аж 4 штуки.

Конечно, можно провести аналогию и рассмотреть метод

1
.last-child()
. Но мне кажется, смысла в этом особого нет - все и так понятно. Выборка будет производиться с точностью до наоборот и будут отбираться последние потомки своих неспосредственных родителей.

На этом думаю закончить сравнительный обзор двух методов -

1
.first()
и
1
.first-child()
.


Mangling Angular

Angular Builder поддерживает параметры среды:- NG_BUILD_MANGLE- NG_BUILD_MINIFY- NG_BUILD_BEAUTIFYМожно установить их при запуске скрипта...… Continue reading

Constructor parameter without access modifier

Published on February 04, 2024

RxJs and DestroyRef Provider

Published on January 24, 2024