Есть такое медиа — «Кинжал», которое рассказывает про полезные навыки и подходы к жизни. Так сложилось, что наш главред Максим также работает и там. Он придумал такую мульку: чтобы статьи «Кинжала» напоминали всем, кто читает их после 10 вечера, что пора лечь спать. А если на улице уже утро, то и напоминать не нужно.
Это мы и сделаем.
Логика проекта
В конце каждой статьи «Кинжала» есть плашка с заключительной мыслью, в конце которой стоит картинка кинжала:
Нам нужно, чтобы с 10 вечера и до 5 утра в каждую такую плашку перед кинжалом добавлялась фраза «А теперь ложитесь спать». Для этого сделаем так:
- Ждём, пока загрузится вся страница
- Находим в структуре HTML-документа эту плашку и получаем её содержимое.
- Смотрим на текущее время у пользователя.
- Если оно попадает в нужный нам диапазон — выполняем всё, что ниже, а если не попадает — ничего не делаем.
- Если на плашке есть картинка кинжала — добавляем текст перед ней.
- Если картинки кинжала нет — добавляем текст в самый конец плашки.
Готовим каркас
Чтобы код ждал, когда загрузится вся страница, и только потом начинал работать, нам понадобится обработчик события полной загрузки. Это значит, что когда содержимое страницы загрузится у пользователя, сработает событие полной загрузки и можно выполнять код скрипта.
За это в 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, условие не выполнится и делать внутри несуществующей плашки ничего не нужно.
Теперь всё остальное напишем внутри этой проверки.
Добавляем текст на плашку
У нас может быть две ситуации: картинка с кинжалом есть на плашке или её там нет. Если есть — надо добавить текст до неё, а если картинки нет — просто поставить текст в конец.
Чтобы поставить текст до картинки, нам нужно сделать так:
- Ищем в тексте начало тега картинки "<img" и смотрим, на какой позиции он начинается.
- Если такой текст внутри плашки есть и поиск нам вернул конкретную позицию, то берём фрагмент текста до этой позиции, добавляем наш текст, а потом приклеиваем тег с картинкой.
- Если тега с картинкой на плашке нет, то приклеиваем наш текст в конец исходной надписи.
- Результат отправляем в плашку вместо старого.
Запишем это в виде кода:
// получаем содержимое финальной плашки
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;
}
}
});