Модальное окно 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, время: 21:05. |