Адаптируем статью под время суток

Адаптируем статью под время суток

Простая игрушка на JS.

Есть такое медиа — «Кинжал», которое рассказывает про полезные навыки и подходы к жизни. Так сложилось, что наш главред Максим также работает и там. Он придумал такую мульку: чтобы статьи «Кинжала» напоминали всем, кто читает их после 10 вечера, что пора лечь спать. А если на улице уже утро, то и напоминать не нужно. 

Это мы и сделаем. 

Логика проекта

В конце каждой статьи «Кинжала» есть плашка с заключительной мыслью, в конце которой стоит картинка кинжала:

Адаптируем статью под время суток

Нам нужно, чтобы с 10 вечера и до 5 утра в каждую такую плашку перед кинжалом добавлялась фраза «А теперь ложитесь спать». Для этого сделаем так:

  1. Ждём, пока загрузится вся страница
  2. Находим в структуре HTML-документа эту плашку и получаем её содержимое.
  3. Смотрим на текущее время у пользователя.
  4. Если оно попадает в нужный нам диапазон — выполняем всё, что ниже, а если не попадает — ничего не делаем.
  5. Если на плашке есть картинка кинжала — добавляем текст перед ней.
  6. Если картинки кинжала нет — добавляем текст в самый конец плашки.

Готовим каркас

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

За это в JavaScript отвечает обработчик addEventListener с параметром
"DOMContentLoaded":

// ждём, пока страница полностью загрузится, потом алгоритм начинает работать
document.addEventListener("DOMContentLoaded", () => {
  // получаем текущую дату и время пользователя
  const now = new Date();
});

Всё остальное мы будем писать тоже внутри этого обработчика.

Находим финальную плашку

Чтобы не тащить в проект jQuery ради одного запроса, реализуем поиск нужного объекта родными средствами JavaScript:

// находим в документе среди всех разделов, которые относятся к статье, финальную плашку
const finalTexts = document
  .querySelector(".article-content")
  .querySelectorAll(".final");
// находим нужную и единственную плашку, с которой будем работать
const lastFinalText = finalTexts[finalTexts.length - 1];

Теперь поясним код.

Мы знаем от ребят из «Кинжала», что у них на странице есть один раздел с классом ".article-content", внутри которого лежит плашка с классом ".final". Мы могли бы просто найти элемент с классом ".final" и работать с ним, но мы хотим перестраховаться: вдруг их на странице будет несколько. Для этого мы сначала находим раздел со статьёй и уже внутри неё находим нужную плашку.

Последней строчкой мы получаем сам объект с плашкой, потому что команда поиска .querySelectorAll (".final") выдаст нам массив из объектов, а не конкретную плашку. Чтобы получить именно плашку как один объект, мы берём первый элемент массива. А так как нумерация начинается с нуля, мы берём размер массива (там один элемент, поэтому он равен единице) и вычитаем из него единицу. Получаем ноль — то, что нам нужно.

Добавляем проверку времени

Для проверки времени мы извлекаем из полной даты значение текущего часа. Так как нам нужно, чтобы код срабатывал с 10 вечера до 5 утра, то значение часа должно быть больше 21 и меньше 5:

// проверяем время — если наступил нужный нам диапазон
if ((now.getHours() > 21 || now.getHours() < 5) && finalTexts) { }

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

Теперь всё остальное напишем внутри этой проверки.

Добавляем текст на плашку

У нас может быть две ситуации: картинка с кинжалом есть на плашке или её там нет. Если есть — надо добавить текст до неё, а если картинки нет — просто поставить текст в конец.

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

  1. Ищем в тексте начало тега картинки "<img" и смотрим, на какой позиции он начинается.
  2. Если такой текст внутри плашки есть и поиск нам вернул конкретную позицию, то берём фрагмент текста до этой позиции, добавляем наш текст, а потом приклеиваем тег с картинкой.
  3. Если тега с картинкой на плашке нет, то приклеиваем наш текст в конец исходной надписи.
  4. Результат отправляем в плашку вместо старого.

Запишем это в виде кода:

//  получаем содержимое финальной плашки
const s = lastFinalText.innerHTML;
// ищем начало картинки с кинжалом и его запоминаем позицию в строке
const c = s.indexOf("<img");
// если нашли…
if (c !== -1) {
  // то берём текст до картинки
  const s_begin = s.slice(0, c - 1);
  // затем берём текст после картинки
  const s_end = s.slice(c, s.length);
  // и склеиваем обратно, добавляя в середину наш текст
  const s_result = s_begin + ". А теперь ложитесь спать " + s_end;
  // отправляем результат обратно в финальную плашку
  lastFinalText.innerHTML = s_result;
// если картинки в плашке не оказалось…
} else {
  // то просто добавляем концовку
  const s_result = s + ". А теперь ложитесь спать";
 // и отправляем результат обратно в финальную плашку
  lastFinalText.innerHTML = s_result;

Собираем код в одно целое и проверяем результат:

Адаптируем статью под время суток

// ждём, пока страница полностью загрузится, потом алгоритм начинает работать
document.addEventListener("DOMContentLoaded", () => {
  // получаем текущую дату и время пользователя
  const now = new Date();
  // находим в документе среди всех разделов, которые относятся к статье, финальную плашку
  const finalTexts = document
    .querySelector(".article-content")
    .querySelectorAll(".final");
  // находим нужную и единственную плашку, с которой будем работать
  const lastFinalText = finalTexts[finalTexts.length - 1];
  //   проверяем время — если наступил нужный нам диапазон
  if ((now.getHours() > 21 || now.getHours() < 5) && finalTexts) {
    //  получаем содержимое финальной плашки
    const s = lastFinalText.innerHTML;
    // ищем начало картинки с кинжалом и его запоминаем позицию в строке
    const c = s.indexOf("<img");
    // если нашли…
    if (c !== -1) {
      // то берём текст до картинки
      const s_begin = s.slice(0, c - 1);
      // затем берём текст после картинки
      const s_end = s.slice(c, s.length);
      // и склеиваем обратно, добавляя в середину наш текст
      const s_result = s_begin + ". А теперь ложитесь спать " + s_end;
      // отправляем результат обратно в финальную плашку
      lastFinalText.innerHTML = s_result;
    // если картинки в плашке не оказалось…
    } else {
      // то просто добавляем концовку
      const s_result = s + ". А теперь ложитесь спать";
     // и отправляем результат обратно в финальную плашку
      lastFinalText.innerHTML = s_result;
    }
  }
});

Текст:

Михаил Полянин

Редактор:

Максим Ильяхов

Художник:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Соцсети:

Олег Вешкурцев

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства и компенсация, если вы пойдёте работать в «Яндекс».
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Генератор статей для Кода
Генератор статей для Кода

Почти настоящие статьи на цепях Маркова

Я сделяль: главная страница Яндекса
Я сделяль: главная страница Яндекса

Верстаем чистую страницу поисковика.

Проект: собственный поиск по странице на jQuery
Проект: собственный поиск по странице на jQuery

Потому что почему бы и нет.

Красивый цветной текст в CSS: как это сделать
Красивый цветной текст в CSS: как это сделать

Можно раскрасить хоть по диагонали

Делаем свой таймер на Python

Код — проще, возможностей — больше.

Цветной арканоид на JavaScript
Цветной арканоид на JavaScript

Всё как на старых приставках.

Генератор лабиринтов
Генератор лабиринтов

Рисуем лабиринты любого размера.

Телеграм-бот для учёбы

Собираем за 10 минут.

Простейший генератор креативного текста

Без нейросетей, регистрации и СМС.

Создаём статичный сайт на Hugo
Создаём статичный сайт на Hugo

Превращаем простой текст в полноценный сайт.

Что означает ошибка ReferenceError: Invalid left-hand side in assignment
Что означает ошибка ReferenceError: Invalid left-hand side in assignment

Скорее всего, вы используете оператор присваивания вместо сравнения.

Проект: собственный поиск по странице на jQuery
Проект: собственный поиск по странице на jQuery

Потому что почему бы и нет.

Переводим аудио в текст. Часть 2

Python, выручай!

easy