像alert()函数一样停止页面执行

Stop page execution like the alert() function

本文关键字:执行 alert 函数 一样      更新时间:2023-09-26

当我写入alert('Hello')时,页面执行停止并等待批准继续。

我有一个div设置显示为假警报,使用HTML -这个div有一个'OK'按钮。

我希望页面停止执行(就像alert一样),直到用户点击'OK'。

可能吗?

不可能。只有特殊的内置设备才能做到这一点。有一段时间,showModalDialog特殊的内置功能允许您为内容指定一个URI,从而自定义它,但它从未被广泛支持,现在甚至被曾经支持它的浏览器弃用。

相反,让使用div的当前警报函数在警报关闭时接受回调(或在关闭时返回已解决的承诺),以允许您继续处理。

例如,如果你的代码使用alert,并像这样工作:

function foo() {
    var x;
    x = doSomething();
    alert("Alert! Alert!");
    doSomethingAfterTheAlertIsCleared(x);
    doAnotherThingAfterward();
}

…你可以把它改成:

function foo() {
    var x;
    x = doSomething();
    fakeAlert("Alert! Alert!", function() {
        doSomethingAfterTheAlertIsCleared(x);
        doAnotherThingAfterward();
    });
}

注意,现在警报之后的所有代码都在一个函数中,我们将其引用传递给fakeAlert。当假警报仍然显示时,foo函数返回,但最终用户驳回假警报,我们的回调被调用。请注意,我们的回调代码可以访问我们正在处理的foo调用中的局部变量,因为我们的回调是一个闭包(如果这是一个相当新的和/或神秘的术语,不要担心,闭包并不复杂)。

当然,如果警报之后的唯一内容是一个不带任何参数的函数调用,则可以直接传递该函数引用。如:

function foo() {
    doSomething();
    alert("Alert! Alert!");
    doSomethingAfterTheAlertIsCleared();
}

就变成:

function foo() {
    doSomething();
    fakeAlert("Alert! Alert!", doSomethingAfterTheAlertIsCleared);
}

(注意,在doSomethingAfterTheAlertIsCleared之后没有()——我们引用函数对象,而不是调用函数;fakeAlert将调用它)

如果您不确定fakeAlert将如何调用回调,它将在用户"关闭"警报div的事件处理程序中,您只需调用回调的参数,就像您使用任何其他对函数的引用一样。所以如果fakeAlert接收到的是callback,你就把它叫做callback();

是的,这是可能的,我做了一个不准确的,没有经过很好测试的演示。

主要概念:

  1. 在这个例子中,我们有一个正在执行的Login.Try()方法Login.Proceed()方法。Login.Proceed()进行AJAX查询想要等待它的执行,但不想绑定任何处理程序(只需像window.alert()那样等待)
  2. 代替直接函数的执行登录。继续,我们使用async()和await()方法(如c#)
  3. 当我们需要"暂停"脚本并等待某事时,我们停止方法执行使用抛出,并解析调用者的函数,以运行当wait (async)方法完成它的第二部分时执行。

范围之外的内容:

    简洁代码
  1. 测试不同浏览器的解决方案
  2. 保存/恢复本地变量
  3. Not works for loops.
演示:

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
Login.Try(); // START!! START!! START!!
var Login = {
    Url: "http://xxxx",
    Try: async(this, function (T) {
        console.log('before login');
        //var success = call(this, Login.Proceed); // normal call
        var success = await(this, Login.Proceed);  // that we want!
        console.log('after login');
        console.log('success ' + success);
    }),
    Proceed: function (callback) {
        console.log('before ajax');
        $.ajax({
            url: this.Url,
            context: document.body
        }).done(function () {
            console.log('after ajax');
            callback("role=admin");
        });
    }
}

function async(T, method){
   console.log('before async create');
   return function () { return method.apply(T); };
   console.log('after async create');
};
function await(T, method) {
    var fn = arguments.callee.caller.toString();
    var pos = fn.indexOf('await(');
    var allBeforeAwait = fn.substring(0, pos);
    var pos1 = fn.indexOf('await(');
    pos1 = fn.indexOf(',', pos1) + 1;
    var pos2 = fn.indexOf(')', pos1);
    var cc = fn.substring(pos1, pos2);

    pos = allBeforeAwait.lastIndexOf(';');
    var allBeforeCall = allBeforeAwait.substring(0, pos + 1) + "}";
    var callResult = allBeforeAwait.substring(pos + 1);
    var result = 10;
    var allAfterCall = "("+fn.substring(0, fn.indexOf(")")) + ",V){" + callResult + "V;";
    pos = fn.indexOf(')', pos) + 2;
    allAfterCall = allAfterCall + fn.substring(pos)+")";
    //uncomment to see function's parts after split
    //console.debug(allBeforeCall);
    //console.debug(cc);
    //console.debug(allAfterCall);
    method.apply(T, [function (value) {
        console.log('ajax response ' + value);
        eval(allAfterCall).apply(T, [T, value]);
    } ]);
    throw "";
};
</script>

希望这个演示能给你一些启发。

您还可以查看http://blogs.msdn.com/b/rbuckton/archive/2011/08/15/promise-js-2-0-promise-framework-for-javascript.aspx

您可以使用以下代码长时间暂停执行:

PauseExcecution()函数{
//做一些事情
睡眠
(1000);//做一些事情…

}

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

不可能像警告那样,但您可以使其看起来像警报。

例如,你创建了一个调用其他函数的函数。:)然后你用一个巨大的IF创建一个函数。

window.callfunction = function (f, a, b) /* function name, arguments, boolean*/
{
    var handler = window[f];
    if (typeof handler === 'function') {
        handler(a, b);
    } else {
        alert("No function like that mate, sry.");
    }
}
function deleteAfterConfirm(a, b) /* arguments, boolean */
{
    if (b == true) {
        alert("i can delete, confirmed.");
        alert(a);
        return false;
    }
    magicConfirm(a);
}
function magicConfirm(a) {
    /** 
        modals, popovers, etc, anything you want,
    **/
    $("#confirmModal").modal("show");
    /**
        and put the function's name to the binding element's data
    **/
    $("#returntrue").data("call", arguments.callee.caller.name);
    $("#returntrue").data("arguments", a);
    /** 
        the element like OK button in the alert 
        calls the magicConfirm function's caller function 
        with true, which is the deleteAfterConfirm, and 
        because the bool is true, it will alert i can delete... 
    **/
    $("#returntrue").bind("click", function () {
        callfunction($(this).data("call"), $(this).data("arguments"), true);
    });
}

$(document).ready(function () {
    $("#deleteAfterConfirm").on("click", function () {
        deleteAfterConfirm("variable which is needed later.");
    });
});

现在你可以像使用alert()或confirm()函数一样使用deleteAfterConfirm函数,因为它会调用if本身的另一部分。

不是最好的方法,但这可以以某种方式取代确认和警告,以获得更好看的版本。这是一种假警觉性的方式:)

玩得开心- R

你可以用Promise API来做。这只是划分代码并在操作侦听器中放置一些行。下面是示例代码:

在这个例子中,有两个按钮。单击第一个按钮启动代码,其余代码将放在promise.then函数上。

Html代码:

<body>
  <button id='startButton' onclick='start();'>Start Button</button>
  <button id='targetButton'>Target Button</button>
</body>

脚本代码:

<script>
    function start(){
      console.log('first log'); //put your div displayer code here
      let promise = new Promise(function(resolve, reject) {
          console.log('promise started');
          let targetButton = document.getElementById('targetButton');
          targetButton.addEventListener("click",function(){
            resolve();
          });
      });
      promise.then(function() {
          console.log('second log'); //put the rest of your code
      });
    }
</script>

触发启动按钮后,您将看到first logpromise started。点击目标按钮后会显示second log

承诺API资源:

  • MDN: Mozilla Developer Network
  • MSDN: Microsoft Developer Network
  • 非常详细的教程

如果要等待对话框关闭,则"打开";属性指示对话框是打开还是关闭。当它完成后,解决这个承诺。对于同步,请添加计时器以定期测试此属性。

    let d = document.querySelector('dialog')
    d.showModal()
    await new Promise((resolve, reject) => {
        let timer = setInterval(_ => {
            if (!d.open) {
                resolve()
                clearInterval(timer)
            }
        }, 500)
    })

我认为这是可能的使用基本的JavaScript。您可以像这样设置伪按钮:

<button id="fakeButton" value="not" onclick="fakeButtonValChange()">OK</button>

:

function fakeButtonValChange() {
var fakebuttonval = document.getElementById("fakeButton").value;
document.getElementById("fakebutton").value = 
"clicked"
if (fakebuttonval == "clicked") {
*place stuff to show div here (i'm not good with css and that stuff)*
}

使用' Bootstap'模式

然后使用下面的代码删除关闭按钮并禁用模型窗口隐藏

$('#myModal').modal({backdrop: 'static', keyboard: false})

将你的函数和关闭事件绑定到该模态窗口的OK按钮