Модальное окно JS
Вопрос знатокам: можно ли без сторонних библиотек сделать такое модальное окно (не alert и не confirm), которое будет выводится раз в x дней. Как записать в кеш без помощи JQuery? Т.е. окно вызывается через некоторый промежуток времени после открытия сайта (settimeout) пользователь нажимает на одну из кнопок окна и окно скрывается
|
|
ABitOfJS,
<dialog id="secretDialog"> Пора выполнить действие <span class="actions"> <button id="action-1">Выполнить</button> <button id="action-2">Отвергнуть</button> </span> </dialog> <script> var dialog = document.getElementById("secretDialog"); // кол-во дней между показами диалога var days = 1; // некоторый промежуток времени после открытия сайта, через который окно вызывается var timeout = 2000; var D = 24 * 3600 * 1000; var date = new Date(); var t = date.getTime() + date.getTimezoneOffset() * 60 * 1000; var lastT = +localStorage.dialogLastT || 0; function getDay(t) { return Math.floor((t - 0.25 * D) / D); } if(t - lastT > 0.25 * D && getDay(t) - getDay(lastT) >= days) setTimeout(dialog.setAttribute.bind(dialog, "open", "true"), timeout); dialog.addEventListener("click", function(event) { var button = event.target; if(!button.matches(".actions button")) return; localStorage.dialogLastT = t; this.removeAttribute("open"); // какие-то действия при нажатии на кнопки }); </script> <style> #secretDialog { all: unset; position: absolute; top: 20px; left: 20px; right: 20px; z-index: 100; margin: auto; width: max-content; max-width: calc(100% - 40px); box-sizing: border-box; display: flex; justify-content: center; align-items: center; transition: all .25s; will-change: opacity, transform; box-shadow: 0 10px 10px rgba(0, 0, 0, .1); padding: 10px 30px; color: #333; border-radius: 100px; background: #f1f5f5; pointer-events: none; opacity: 0; transform: translateY(-10px) scale(.95); } #secretDialog[open] { pointer-events: all; opacity: 1; transform: translateY(0px) scale(1); } #secretDialog .actions button { font: inherit; border: none; display: inline-block; padding: 8px 10px; background: #e1e5e5; border-radius: 4px; margin: 5px; color: #333; } </style> |
Malleys,
зачем нужно проверять, что прошло 8 часов? и разве не проще так function getDay(t) { return Math.floor(t / D); } if(getDay(t - lastT) >= days) setTimeout(dialog.setAttribute.bind(dialog, "open", "true"), timeout); |
рони, не 8, а 6 часов! Когда человек посмотрит вечером, а потом встанет утром, то хотя не прошло 24 часа, но для человека это уже другой день.
|
Malleys,
тогда можно так ... if(t - lastT > (days - 0.75) * D ) без getDay(t) |
Не нужно, чтобы в тот же день сообщение появлялось 2 раза, например утром и вечером.
Условие t - lastT > 0.25 * D && getDay(t) - getDay(lastT) >= daysозначает, что
Если days = 1, то... Если человек посмотрит вечером в 22 часа и увидит диалог, то на следующее утро в 8 часов тоже увидит диалог. Если человек посмотрит ночью в 1 час и увидит диалог, то на следующее утро в 8 часов тоже увидит диалог. А если посмотрит утром в 8 часов и увидит диалог, то вечером в 22 часа не увидит диалог. |
Цитата:
я в курсе что проверяет условие, я не знаю в каком месте находится телепат который знает что к одному дню относится промежуток с шести часов утра до шести часов следующего утра. |
Malleys,
максимум на что хватает моего разумения ... <dialog id="secretDialog"> Пора выполнить действие <span class="actions"> <button id="action-1">Выполнить</button> <button id="action-2">Отвергнуть</button> </span> </dialog> <script> var dialog = document.getElementById("secretDialog"); // кол-во дней между показами диалога var days = 1; // некоторый промежуток времени после открытия сайта, через который окно вызывается var timeout = 2000; var D = 24 * 3600 * 1000; var date = new Date(); date.setHours(0,0,0,0); var t = date.getTime(); var lastT = +localStorage.dialogLastT || 0; if(t - lastT >= D * days) setTimeout(dialog.setAttribute.bind(dialog, "open", "true"), timeout); dialog.addEventListener("click", function(event) { var button = event.target; if(!button.matches(".actions button")) return; localStorage.dialogLastT = t; this.removeAttribute("open"); // какие-то действия при нажатии на кнопки }); </script> <style> #secretDialog { all: unset; position: absolute; top: 20px; left: 20px; right: 20px; z-index: 100; margin: auto; width: max-content; max-width: calc(100% - 40px); box-sizing: border-box; display: flex; justify-content: center; align-items: center; transition: all .25s; will-change: opacity, transform; box-shadow: 0 10px 10px rgba(0, 0, 0, .1); padding: 10px 30px; color: #333; border-radius: 100px; background: #f1f5f5; pointer-events: none; opacity: 0; transform: translateY(-10px) scale(.95); } #secretDialog[open] { pointer-events: all; opacity: 1; transform: translateY(0px) scale(1); } #secretDialog .actions button { font: inherit; border: none; display: inline-block; padding: 8px 10px; background: #e1e5e5; border-radius: 4px; margin: 5px; color: #333; } </style> |
Цитата:
Глянь, например, в расписание автобусов — там в конце таблицы поездки, относящиеся к следующему дню, указаны так, как будто это продолжение предыдущего дня... 23:11 23:27 23:44 0:01 0:22 0:46 И это на самом деле удобно, поскольку указание времён после полуночи в начале таблицы привело бы к такому пониманию, что последняя поездка в 23:44, а не в 0:46 |
Часовой пояс GMT +3, время: 23:19. |