javascript 多个OnBeforeUnload

hgtggwj0  于 2023-05-12  发布在  Java
关注(0)|答案(8)|浏览(87)

bounty还有7天到期。回答此问题可获得+300声望奖励。KyleMit ♦想要奖励现有答案:感谢Lunfel -伟大的答案没有外部库或全球挂钩!

我正在写一个JS,用作插件。JS有onbeforeunload事件。
我需要一些建议,以便我的onbeforeunload事件不会覆盖现有的onbeforeunload事件(如果有)。我可以将我的onbeforeunload附加到现有的吗?
谢谢

nle07wnf

nle07wnf1#

我觉得这个问题还没有得到完全的回答,因为没有使用addEventListener的例子(但是MAZZTer指出了addEventListener的解决方案)。我的解决方案与Julian D相同。但不使用jQuery,仅使用原生javascript。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Before Unload</title>
</head>
<body>
    <p>Test</p>

    <script>
      window.addEventListener('beforeunload', function (event) {
        console.log('handler 1')
        event.preventDefault()
        event.returnValue = ''
      });

      window.addEventListener('beforeunload', function (event) {
        console.log('handler 2')
      });
    </script>
</body>
</html>

在这个例子中,两个监听器都将被执行。如果设置了任何其他beforeunload侦听器,它将不会覆盖它们。我们将得到以下输出(顺序不保证):

handler 1
handler 2

而且,重要的是,如果一个或多个事件侦听器执行event.preventDefault(); event.returnValue = '',则会出现一个提示,询问用户是否真的想要重新加载。
如果你正在编辑一个表单,同时你正在通过 AJAX 下载一个文件,并且不想在这些操作中丢失数据,这可能是有用的。其中每一个都可以有一个侦听器来防止页面重新加载。

const editingForm = function (event) {
  console.log('I am preventing losing form data')
  event.preventDefault()
  event.returnValue = ''
}

const preventDownload = function (event) {
  console.log('I am preventing a download')
  event.preventDefault()
  event.returnValue = ''
}

// Add listener when the download starts
window.addEventListener('beforeunload', preventDownload);
// Add listener when the form is being edited
window.addEventListener('beforeunload', editingForm);

// Remove listener when the download ends
window.removeEventListener('beforeunload', preventDownload);
// Remove listener when the form editing ends
window.removeEventListener('beforeunload', editingForm);
xsuvu9jc

xsuvu9jc2#

如果您不使用事件观察,而是直接附加onbeforeunload处理程序(您不应该这样做),则只需要注意这一点。如果是这样,请使用类似这样的方法来避免覆盖现有的处理程序。

(function() {
    var existingHandler = window.onbeforeunload;
    window.onbeforeunload = function(event) {
        if (existingHandler) existingHandler(event);

        // your own handler code here
    }
})();

不幸的是,您无法阻止其他(以后的)脚本覆盖您的处理程序。但是,这可以通过添加事件侦听器来解决:

$(window).unload(function(event) {
    // your handler code here
});
fafcakar

fafcakar3#

我的想法是:

var callbacks = [];
window.onbeforeunload = function() {
    while (callbacks.length) {
        var cb = callbacks.shift();
        typeof(cb)==="function" && cb();
    }
}

callbacks.push(function() {
    console.log("callback");
});
a64a0gku

a64a0gku4#

试试这个:

var f = window.onbeforeunload;
window.onbeforeunload = function () {
    f();
    /* New code or functions */
}

您可以多次修改此函数,而不会丢失其他函数。

pgvzfuti

pgvzfuti5#

如果使用jQuery绑定,它会将绑定追加到现有列表中,因此无需担心。
jQuery Docs on() method
从jQuery 1.4开始,同一个事件处理程序可以多次绑定到一个元素。

function greet(event) { alert("Hello "+event.data.name); }
$("button").on("beforeunload", { name: "Karl" }, greet);
$("button").on("beforeunload", { name: "Addy" }, greet);
vxbzzdmp

vxbzzdmp6#

你可以使用不同的javascript框架,比如jquery,或者你可以添加一个小的事件添加处理程序来完成这个任务。就像你有一个对象,它包含了你添加的许多函数,然后在onbefore unload中运行添加的函数。所以当你想给事件添加一个新的函数时,你可以把它添加到你的对象中。
就像这样:

var unloadMethods = [];
function addOnBeforeUnloadEvent(newEvent) { //new Event is a function
    unloadMethods[unloadMethods.length] = newEvent;
}

window.onbeforeunload = function() {
    for (var i=0; i<unloadMethods.length; i++) {
        if(typeof unloadMethods[i] === "function") {unloadMethods[i]();}
    }
}
lmyy7pcs

lmyy7pcs7#

上面提到的这些框架在内部使用addEventListener。如果你没有使用框架,那就使用它。
https://developer.mozilla.org/en-US/docs/DOM/element.addEventListener
对于较旧版本的IE,您应该使用attachEvent来替代:
http://msdn.microsoft.com/en-us/library/ie/ms536343(v=vs.85).aspx

0ejtzxu1

0ejtzxu18#

我喜欢Marius的解决方案,但对它进行了修饰,以满足var f为null的情况,并返回链中任何函数返回的第一个字符串:

function eventBeforeUnload(nextFN){
    //some browsers do not support methods in eventAdd above to handle window.onbeforeunload
    //so this is a way of attaching more than one event listener by chaining the functions together 
    //The onbeforeunload expects a string as a return, and will pop its own dialog - this is browser behavior that can't
    //be overridden to prevent sites stopping you from leaving. Some browsers ignore this text and show their own message.
    var firstFN = window.onbeforeunload;
    window.onbeforeunload = function () {
        var x;
        if (firstFN) {
            //see if the first function returns something
            x = firstFN();
            //if it does, return that
            if (x) return x;
        }
        //return whatever is returned from the next function in the chain
        return nextFN();
    }
}

在你的代码中,需要的地方就这样使用它

eventBeforeUnload(myFunction);
//or
eventBeforeUnload(function(){if(whatever) return 'unsaved data';);

相关问题