确认关闭标签页/浏览器

115

如何在用户离开页面之前向其请求确认,例如Gmail中的功能?

我在各种地方搜索了这个问题,但他们提到的都是使用JavaScript的 window.unloadwindow.onbeforeunload。而且在Chrome浏览器中大多数时间不起作用,因为它会被阻止。


我尝试了window.unload和window.onbeforeunload,但它们没有按照要求工作。 - user1349661
3
不,不是。那个问题是关于正确使用'onbeforeunload'的问题。 - Bergi
9个回答

154

试试这个:

<script>
window.onbeforeunload = function (e) {
    e = e || window.event;

    // For IE and Firefox prior to version 4
    if (e) {
        e.returnValue = 'Sure?';
    }

    // For Safari
    return 'Sure?';
};
</script>

这里有一个运行正常的jsFiddle


2
同时,由于它源自用户的点击,因此不会被任何浏览器禁用。 - gopi1410
@gopi1410 - 我可以添加自己的JavaScript代码来替代这个确认框吗? - Musaddiq Khan
有没有特定的方法只在浏览器或选项卡关闭时使用,而不是在导航上使用? - dipak_pusti
12
我尝试了一下,只有在点击其他东西之后才有效,例如右键单击链接。然后,如果我点击浏览器关闭按钮,它会如预期一样提示我是否要关闭。否则,如果我直接进入页面并立即单击关闭按钮,则不起作用,页面会关闭。在 onbeforeunload 函数内的代码每次都被执行,但在最后一种情况下明显没有效果。 - nickornotto
1
这段代码用于早期(2012年发布)的工作,由于安全问题,现在大多数浏览器都无法正常工作。 - Kapila Perera
显示剩余11条评论

17

2020年最简短的解决方案(适用于不需要支持IE的幸福人群)

在Chrome、Firefox和Safari中测试通过。

function onBeforeUnload(e) {
    if (thereAreUnsavedChanges()) {
        e.preventDefault();
        e.returnValue = '';
        return;
    }

    delete e['returnValue'];
}

window.addEventListener('beforeunload', onBeforeUnload);

实际上,现代浏览器(Chrome、Firefox、Safari)不会将"返回值"作为问题显示给用户,而是展示它们自己的确认文本(这取决于浏览器)。但我们仍然需要返回一些(即使是空字符串)来在Chrome上触发确认。

更多解释请参见MDN 这里这里


这在2021年还能用吗?我尝试了但是不起作用。 - user9437856
beforeunload在iOS中不再受支持。还有其他解决方案吗? - Kalleshwar Kalshetty

15

试一下这个:

<script>
    window.onbeforeunload = function(e) {
       return 'Dialog text here.';
    };
</script>

更多信息请查看MDN


请注意,现在此处链接的官方文档提到了这种方式: addEventListener("beforeunload", (event) => {}); - Valerio Bozz

7

我看到对答案的评论被标记为“好”的。大多数用户都在询问是否允许点击按钮和某些链接。这里需要添加一行代码来实现。

<script type="text/javascript">
  var hook = true;
  window.onbeforeunload = function() {
    if (hook) {

      return "Did you save your stuff?"
    }
  }
  function unhook() {
    hook=false;
  }

为了允许某些按钮和链接使用,可以在点击时调用unhook()。例如:

<a href="#" onClick="unhook()">This link will allow navigation</a>

1
你可以直接使用 onclick="hook = false;" - undefined

6

简单地说

function goodbye(e) {
        if(!e) e = window.event;
        //e.cancelBubble is supported by IE - this will kill the bubbling process.
        e.cancelBubble = true;
        e.returnValue = 'You sure you want to leave?'; //This is displayed on the dialog

        //e.stopPropagation works in Firefox.
        if (e.stopPropagation) {
            e.stopPropagation();
            e.preventDefault();
        }
    }
window.onbeforeunload=goodbye;

beforeunload在IOS中不再受支持。如果您有其他解决方案,能否帮助我? - Kalleshwar Kalshetty
@KalleshwarKalshetty 在 IOS 上使用 window.unloaddocument.pagehide 替代 onbeforeunload。 - Dev Matee
我尝试使用“pagehide”事件,但它是不可取消的。我想要像在“beforeunload”事件中一样具有取消页面重新加载的能力。 - Kalleshwar Kalshetty

3

如果您想根据条件进行查询:

var ask = true
window.onbeforeunload = function (e) {
    if(!ask) return null
    e = e || window.event;
    //old browsers
    if (e) {e.returnValue = 'Sure?';}
    //safari, chrome(chrome ignores text)
    return 'Sure?';
};

谢谢。这个答案非常类似于在此处建议的跨平台解决方案:https://developer.mozilla.org/en-US/docs/Web/API/BeforeUnloadEvent - Valerio Bozz

0
  1. 假设我想在没有选择任何内容的情况下关闭窗口
  2. 我想关闭有选定内容的窗口,但不要提示我。
  3. 我想关闭一个窗口,但是有东西被选中,请提示我。

针对这三种情况,我在以下代码中进行了大量搜索,并进行了更改以适应我的需求,希望能帮助其他人。 ask是一个关键字,如果我想弹出提示,则为“true”,否则不会。假设我想打印我的文档并重定向我的页面,则ask将为false,不会有提示。 假设您的页面具有数据,则检查条件是我的情况下的小计值,如果小计为零,则不会提示,否则请提示我您的页面上有某些内容。

<pre>
    var ask = true;
    window.onbeforeunload = function(e) {
       if (!ask) return null
       var subtotal = $('#lblgtwithsgst').text();
         if (subtotal != '0') {
          e = e || window.event;
          //old browsers
            if (e) {
             e.returnValue = 'Sure?';
            }
            //safari, chrome(chrome ignores text)
            return 'Sure?';
         }  
      }
      $('#btnPrint').click(function(){
        ask = false;
        ///print your doc no prompt if ask is false;
      )};

-2
// use jquery version older than 1.6
var preventUnloadPrompt;
var messageBeforeUnload =
  'my message here - Are you sure you want to leave this page?';
$('a').live('click', function () {
  preventUnloadPrompt = true;
});
$('form').live('submit', function () {
  preventUnloadPrompt = true;
});

$(window).bind('beforeunload', function (e) {
  var rval;
  if (preventUnloadPrompt) {
    return;
  } else {
    return messageBeforeUnload;
  }

  return rval;
});

目前你的回答不够清晰,请[编辑]以添加更多细节,帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

-2

对于Angular, 更改组件表单名称并将其粘贴到需要显示警报的组件中。

  @HostListener('window:beforeunload', ['$event'])
  beforeunloadHandler(event) {
    return !this.form.dirty;
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接