@AlTerminator

Как заставить предупреждение срабатывать только после нажатия «Да/Нет» в диалоговом окне?

Как заставить alert("!") всплывать только после выполнения функции Myconfirmselect()? Пока хотя бы одна кнопка в диалоге не нажата - не позволять alert всплывать.

<html>
<body onload="Load()">
<dialog></dialog>
<script>
function Load()
{
 setTimeout(() => {
  Myconfirmselect(
  "Готовы?" + "¤" +
  "Да" + "¥" + "alert('Да');" + "º" +
  "Нет" + "¥" + "alert('Нет');"
  );
  alert("!");//нужно исправить преждевременное всплытие этого алерта
 }, 500);
}

function Myconfirmselect(VarInput)
{
   document.querySelector("dialog").innerHTML += `
   <div>
    <textarea></textarea>
   </div>
   `;
   document.querySelector("dialog").style.textAlign = "center";
   document.querySelector("dialog").querySelector("div").querySelector("textarea").style.width = "100%";
   document.querySelector("dialog").querySelector("div").querySelector("textarea").style.textAlign = "center";
   document.querySelector("dialog").querySelector("div").querySelector("textarea").style.resize = "none";
   document.querySelector("dialog").querySelector("div").querySelector("textarea").readOnly = true;
   document.querySelector("dialog").querySelector("div").querySelector("textarea").value = VarInput.split("¤")[0];
   for (var i = 0; i < VarInput.split("¤")[1].split("º").length; i++)
   {
    var VarButton = document.createElement("button");
    VarButton.textContent = VarInput.split("¤")[1].split("º")[i].split("¥")[0];
    VarButton.id = VarInput.split("¤")[1].split("º")[i].split("¥")[1];
    VarButton.style.marginLeft = "10px";
    VarButton.style.marginTop = "10px";
    VarButton.addEventListener("click", () =>
    {
     eval(event.target.id);
     //ButtonClosealert();
    });
    document.querySelector("dialog").querySelector("div").appendChild(VarButton);
   }
   function ButtonClosealert()
   {
    document.querySelector("dialog").style.animation = "AnimFormHide 0.1s both";
    setTimeout(() =>
    {
     document.querySelector("dialog").style.textAlign = "initial";
     document.querySelector("dialog").removeChild(document.querySelector("dialog").querySelector("div"));
     document.querySelector("dialog").close();
    }, 100);
   }
   document.querySelector("dialog").style.animation = "AnimFormShow 0.25s both";
   document.querySelector("dialog").showModal();
}
</script>
<style>
@keyframes AnimFormShow
{
 0%
 {
  transform: translateY(-150%);
 }
}

@keyframes AnimFormHide
{
 100%
 {
  transform: translateY(-150%);
  display: none;
 }
}

dialog, #DialogCycle
{
 border: 2px solid black;
 border-radius: 15px;
}

dialog div, #DialogCycle div
{
 position: initial;
}

dialog::backdrop, #DialogCycle::backdrop
{
 background: rgba(0,0,0,.6);
}
</style>
</body>
</html>
  • Вопрос задан
  • 117 просмотров
Пригласить эксперта
Ответы на вопрос 1
Первое, что вам надо сделать - изучить самые базовые основы Javascript и DOM, и как это всё работает.
Вы должны понимать, что Javascript - это не PHP. PHP работает только в один поток и выполняет операции исключительно одну за другой по порядку. В Javascript же есть возможность выполнять код асинхронно с использованием такого инструмента, как Event Loop. Ещё обязательно изучить, что такое Promise и как подсластить его использование при помощи сахарка async - await

Т.е. ваш обычный код, который выполняется по порядку, может выполняться как бы "одновременно" с кодом, который выполняется при нажатии на кнопку. Т.е. пока ваша кнопка ждёт события click, чтобы выполнить какой-то код по нажатию, остальная программа спокойно себе исполняется по порядку. Таким образом, пользователь еще не успел кликнуть, но ваша программа уже создала диалог при помощи функции Myconfirmselect, и спокойно себе приступила к следующей операции. А этой следующей операцией как раз и является тот самый alert("!"). Вот он и появляется на экране.

Т.е. нам надо как бы подсунуть этот alert внутрь функции Myconfirmselect. Как это сделать? В Javascript функции - это такие же объекты. Т.е. функцию можно назначить какой-то переменной и передать эту переменную в другую функцию. Вот мы и передаём наш callback в функцию Myconfirmselect просто в качестве аргумента, и вызываем этот аргумент как функцию уже в том месте, где обрабатывается событие click на кнопку.

P.S. В коде постоянно происходит выборка одного и того же элемента. Это не очень хорошо, потому что такая выборка не бесплатна, все операции с DOM - довольно медленные, поэтому я позволил себе переписать часть кода, не меняя самой его структуры, чтобы вам было понятнее. Выбрав один раз наш конкретный dialog нет смысла выбирать его постоянно еще и еще раз. Запихнём его в переменную и будем с ним работать. То же самое касается и textarea и div

<html>
    <body onload="Load()">
        <dialog></dialog>
        <script>
            function Load() {
                setTimeout(() => {
                    // Создаём колбэк, функцию, которая будет вызываться только после нажатия на кнопку
                    const callback = function () {
                        alert("!");
                    };

                    Myconfirmselect(
                        "Готовы?" +
                            "¤" +
                            "Да" +
                            "¥" +
                            "alert('Да');" +
                            "º" +
                            "Нет" +
                            "¥" +
                            "alert('Нет');",
                        callback, // Передаём колбэк в функцию создания диалога
                    );
                }, 500);
            }

            function Myconfirmselect(VarInput, callback) {
                const dialog = document.querySelector("dialog");
                dialog.innerHTML += `
   <div>
    <textarea></textarea>
   </div>
   `;

                const textarea = dialog.querySelector("textarea");
                const div = dialog.querySelector("div");
                dialog.style.textAlign = "center";
                textarea.style.width = "100%";
                textarea.style.textAlign = "center";
                textarea.style.resize = "none";
                textarea.readOnly = true;
                textarea.value = VarInput.split("¤")[0];
                for (
                    let i = 0;
                    i < VarInput.split("¤")[1].split("º").length;
                    i++
                ) {
                    const VarButton = document.createElement("button");
                    VarButton.textContent = VarInput.split("¤")[1]
                        .split("º")
                        [i].split("¥")[0];
                    VarButton.id = VarInput.split("¤")[1]
                        .split("º")
                        [i].split("¥")[1];
                    VarButton.style.marginLeft = "10px";
                    VarButton.style.marginTop = "10px";
                    VarButton.addEventListener("click", () => {
                        eval(event.target.id);
                        // Вызов того самого callback после нажатия на кнопку
                        callback();
                        //ButtonClosealert();
                    });
                    div.appendChild(VarButton);
                }
                function ButtonClosealert() {
                    dialog.style.animation = "AnimFormHide 0.1s both";
                    setTimeout(() => {
                        dialog.style.textAlign = "initial";
                        const div = dialog.querySelector("div");
                        dialog.removeChild(div);
                        dialog.close();
                    }, 100);
                }
                dialog.style.animation = "AnimFormShow 0.25s both";
                dialog.showModal();
            }
        </script>
        <style>
            @keyframes AnimFormShow {
                0% {
                    transform: translateY(-150%);
                }
            }

            @keyframes AnimFormHide {
                100% {
                    transform: translateY(-150%);
                    display: none;
                }
            }

            dialog,
            #DialogCycle {
                border: 2px solid black;
                border-radius: 15px;
            }

            dialog div,
            #DialogCycle div {
                position: initial;
            }

            dialog::backdrop,
            #DialogCycle::backdrop {
                background: rgba(0, 0, 0, 0.6);
            }
        </style>
    </body>
</html>
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы