Как с помощью each jquery перебрать неделю календаря и найти необходимые события?

Есть календарь событий (неделя) формируется динамически, структура: days > day(7) > cell(24) > event-item (может быть а может и не быть). Нужно с помощью jQuery each пройтись по всем дням и найти все возможные event-item которые начинаются в одно и тоже время (день и время) и потом им присваивать класс в зависимости сколько их нашлось. Пытался что-то придумать но нит. Помогите плиз буду очень благодарен

<div class="days">
  <div class="day">
   ...
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 08:00">
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 09:00">
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 10:00">
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 11:00">
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 12:00">
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 13:00">
     <div class="event-item" style="border-color: #89D260; top: 0.0px; height: 100.0px; left: 0px; right: 0px"></div>
     <div class="event-item" style="border-color: #89D260; top: 0.0px; height: 100.0px; left: 0px; right: 0px"></div>
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 13:00"></div>
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 14:00">
     <div class="event-item" style="border-color: #89D260; top: 0.0px; height: 100.0px; left: 0px; right: 0px"></div>
   </div>
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 15:00"></div>
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 16:00"></div>
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 17:00">
     <div class="event-item" style="border-color: #89D260; top: 0.0px; height: 100.0px; left: 0px; right: 0px"></div>
     <div class="event-item" style="border-color: #89D260; top: 0.0px; height: 100.0px; left: 0px; right: 0px"></div>
   </div>
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 18:00"></div>
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 19:00"></div>
   <div class="cell" data-date="2020-08-29" data-time-start="August 29, 2020 20:00"></div>
</div>
  <div class="day">.....</div>
  <div class="day">.....</div>
  <div class="day">.....</div>
  <div class="day">.....</div>
  <div class="day">.....</div>
  <div class="day">.....</div>
</div>

$('.days .day').each(function (i, day) {
  const today = new Date()

  const year = today.getFullYear()

  const month = `${today.getMonth() + 1}`.padStart(2, "0")

  const day = `${today.getDate()}`.padStart(2, "0")

  const stringDate = `${year}-${month}-${day}`;

  if ($(this).data("date") == stringDate) {
    $(this).addClass("otherClass")

  }
  
 });

Ответы (1 шт):

Автор решения: Егор Банин

У любого рефакторинга должна быть цель. Что вы хотите получить в итоге? Более гибкий и легко поддерживаемый код? Более компактый и простой код? Код, который удивит вашего оппонента на собеседовании?

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

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

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

Во-вторых, то, что вы пытаетесь сделать через left/rigth можно сделать через flex.

Если класс overlap действительно нужно добавить, то сделать это можно так:

$('.week-view .hour-grid .days .cell').each(function() {
    var $events = $(this).children();
    if ($events.length > 1) { // события в одной ячейке происходят в одно и то же время
        $events.addClass('overlap');
    }
});

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

.week-view .hour-grid .days .cell {
    display: flex;
}
.week-view .hour-grid .days .cell > * {
    flex-grow: 1;
}

Возможно некотрые предусловия, о котрых я не догадываюсь, не позволят сделать это именно так. Но как идея, думаю, вам пригодится.

→ Ссылка