Делаю виджет, который будет извещать пользователей, что заведение не работает с 23 до 9 утра. При этом можно ориентироваться как на локальное время пользователя, если ваша целевая аудитория из вашего региона, так и на серверное, чтобы точно контролировать ситуацию и не зависеть от часового пояса клиента.
Привет, друзья. Небольшое отступление. Понимаю, что не простое время для всех нас. Переживаю по поводу того, что происходит по всей Украине. Людей очень жалко. Я сам из Донецка, живу тут с 2009 года и знаю, что такое прятаться в убежище.
Политики заигрались и нужно это срочно все останавливать. Держитесь. Кто-то скажет, что не время для подобных постов, но для моего блога не было такого понятия как "подходящее время" и он существует как раз со второй половины 2014 года. Я в такой обстановке много лет, поэтому надеюсь, что обойдется без осуждений. Люблю свою родину Украину и земляков украинцев, хорошо отношусь к россиянам. Много друзей, знакомых и близких в этих странах. Благоразумие должно победить.
Вернемся к статье. Итак, как и говорил выше - сегодня сделаем виджет, который показывает уведомление, что заведение не работает в определенные часы. При этом будет возможность выбрать промежуток не только времени, но и дней, месяцев и даже годов. То есть варианты использование виджета, ограничиваются только вашей фантазией.
Это может быть акция в течение определенного времени, например, скидка на обед с 13:00 до 15:00 часов или какие-то подарки только по выходным.
Итак, начнём с разметки. Я сделал небольшой блок с 2 строками текста и кнопкой для закрытия окна:
<div class="time-informer">
<p class="time-informer__title">К сожалению, сегодня мы больше не работаем</p>
<p class="time-informer__description">Завтра с 9:00 мы будем готовы принять ваши заказы</p>
<button class="time-informer__button">Понятно</button>
</div>
Тут все просто. Единственное, на что нужно обратить внимание — это класс обертки "time-informer". Он используется и в js, поэтому, если будете переименовывать, то нужно будет сделать это везде. Также обратите внимание на класс кнопки, он тоже используется в скрипте.
Теперь разберемся с js. Сначала давайте объясню суть, а она в том, что изначально блок скрыт. Затем, при помощи javascript, проверяем время. Если текущее время в выбранном промежутке, то добавляем класс "time-informer_active", что означает - блок показывается.
Теперь давайте подключим файлы стилей и сам скрипт. Исходник в конце статьи. Стили, как обычно, подключаем между тегами <head></head>, а скрипт перед закрывающим тегом body. Вот пример:
Теперь сам код скрипта:
document.addEventListener("DOMContentLoaded", () => {
let timeType = "local"; // local, server
let timeInformer = document.querySelector(".time-informer");
let closeButton = document.querySelector(".time-informer__button");
if (!getCookie("time-informer")) {
if (timeType === "server") {
fetch("/time/time.php")
.then((response) => {
return response.json();
})
.then((data) => {
if (data.hours > 22 || data.hours < 9) {
timeInformer.classList.add("time-informer_active");
}
});
} else {
let data = new Date();
if (data.getHours() > 22 || data.getHours() < 9) {
timeInformer.classList.add("time-informer_active");
}
}
}
function getCookie(name) {
let matches = document.cookie.match(
new RegExp(
"(?:^|; )" +
name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1") +
"=([^;]*)"
)
);
return matches ? decodeURIComponent(matches[1]) : undefined;
}
function setCookie(name, value, options = {}) {
options = {
path: "/",
// при необходимости добавьте другие значения по умолчанию
...options
};
if (options.expires instanceof Date) {
options.expires = options.expires.toUTCString();
}
let updatedCookie =
encodeURIComponent(name) + "=" + encodeURIComponent(value);
for (let optionKey in options) {
updatedCookie += "; " + optionKey;
let optionValue = options[optionKey];
if (optionValue !== true) {
updatedCookie += "=" + optionValue;
}
}
document.cookie = updatedCookie;
}
closeButton.onclick = (e) => {
e.preventDefault();
timeInformer.classList.remove("time-informer_active");
setCookie("time-informer", true);
};
});
Тут нас, в первую очередь, интересуют всего несколько строк.
let timeType = "local"; // local, server
let timeInformer = document.querySelector(".time-informer");
let closeButton = document.querySelector(".time-informer__button");
Переменная timeType — это выбор того, какое время будет учитываться (пользовательское или серверное). Если переменной присвоено "local" - то используется локальное время посетителя. В случае, если присвоено "server", то учитывается серверное время. При этом, для считывания серверного времени используется запрос к файлу time.php.
Переменная timeInformer — это класс обертки виджета, а closeButton - класс кнопки, закрывающей виджет.
Теперь, у нас есть 2 участка кода для работы, где мы будем писать условия. Если используете серверное время, то работать нужно в 13 строке:
if (data.hours > 22 || data.hours < 9) {
Здесь я пишу условие, что если время больше 22 часов, то есть 23 и больше или меньше 9, то добавляем класс "time-informer_active" и показываем виджет.
Доступные настройки для условий:
- data.hours - часы (от 1 до 24);
- data.mday - порядковый номер дня месяца;
- data.minutes - минуты;
- data.mon - порядковый номер месяца;
- data.wday - день месяца. 1 - понедельник;
- data.yday - порядковый номер дня года:
- data.year - год (четырехзначное число).
В примере так:
if (data.hours > 22 || data.hours < 9) {
timeInformer.classList.add("time-informer_active");
}
Рекомендую настроить время на хостинге и использовать именно его, так как пользователь может быть из другого часового пояса.
Посмотреть что именно выдает то или иное свойство можно выведя его в консоль, например, так: console.log(data.year)
Если вы все-таки решили использовать локальное время, то придется воспользоваться чуть другими свойствами.
Обратите внимание на 19 строку, все условия, в случае использования локального времени пешем тут:
if (data.getHours() > 22 || data.getHours() < 9) {
timeInformer.classList.add("time-informer_active");
}
Как и говорил, для локального времени чуть иначе задаются условия:
- date.getHours() - часы от 0 до 23;
- date.getMinutes() - минуты от 0 до 59;
- date.getSeconds() - секунды от 0 до 59;
- date.getMonth() - порядковый номер месяца от 0 до 11, где 0 - январь;
- date.getDate() - день месяца от 1 до 31;
- date.getDay() - номер дня недели от 0 до 6, где 0 - воскресенье;
- date.getFullYear() - год. 4 цифры.
Что касается стилей, то они могут быть любые, главное сделать так, чтобы изначально блок был не видим, а при получении класса "time-informer_active" - показать его. У меня получилось так:
.time-informer {
display: block;
-webkit-box-sizing: border-box;
box-sizing: border-box;
z-index: 10000;
width: 300px;
padding: 60px 30px;
line-height: 1.5;
position: fixed;
font: "Roboto", "Tahoma", sans-serif;
background: #ffda82;
-webkit-box-shadow: 3px 3px 1px rgba(75, 51, 0, 0.2);
box-shadow: 3px 3px 1px rgba(75, 51, 0, 0.2);
-webkit-transition: 0.3s;
transition: 0.3s;
bottom: 30px;
left: -400px;
opacity: 0;
border-radius: 15px 0 15px 0;
visibility: hidden;
}
.time-informer_active {
-webkit-transition: 0.3s;
transition: 0.3s;
opacity: 1;
visibility: visible;
border-radius: 0 15px 0 15px;
left: 30px;
}
Виджет
Размер: 0,6 мб
Если возникнут какие-то сложности или вопросы - пишите. Помогу, чем смогу.
6 комментариев
Спасибо огромное!! Очень полезный виджет!!
По твоему спецзаказу))
Артём, добрый день!
О-о-о-очень интересно!
я работаю с ворпресс, там есть плагин для кнопок maxbutton. а можно такой алгоритм реализовать.
Допустим рабочий день, или лицензия еще действует, на сайте опубликована кнопка [maxbutton id="1"] - ДЕЙСТВУЕТ, зеленая. Как только пришел выходной, или дата, кнопка меняется на [maxbutton id="1"] - НЕ ДЕЙСТВУЕТ, красная.
а для магазина, кроме даты, можно привязать и время.
Как-то подобное можно реализовать?
Спасибо!
Вячеслав, да можно все, что угодно сделать. Просто сравниваете даты и выводите нужный шорткод. В статье я делал при помощи js, вам, вероятно, придется запрашивать дату из БД и делать на PHP.
Дима, как всегда всё на высшем уровне) Спасибо!
кнопка меняется с [maxbutton id="1"] на [maxbutton id="2"]