mailto链接(在chrome中)触发window.onbeforeunload - 我可以阻止这个吗?

时间:2012-03-16 15:54:42

标签: javascript mailto onbeforeunload

可能与How to open mailto link in Chrome with Window.open without creating a new tab?

有关

大家好。我有一个表单页面,我已经放了一个窗口.onbeforeunload确认,以阻止人们导航并意外丢失他们的更改:

window.onbeforeunload = function(){
  if(changed)
    return "You have unsaved changes.  Do you really want to leave this page without saving?";
};  

其中changed是一个变量,只要用户做出任何更改,我就会设置为true。那一切都很好。但是,我还添加了一些指向页面的mailto链接,如下所示:

<a class="button button-alt" href="mailto:foo@foo.com">Report a problem</a>

即使mailto没有离开页面(它正在打开用户的默认邮件应用程序),它仍然会触发onb​​eforeunload事件,提示确认框,这很烦人。我可以在链接上设置target="_blank",然后用户将坐在空白标签中。

我可以将mailto链接设置为不触发onb​​eforeunload事件吗?我想到了一个可怕的hacky方式,通过使用另一个临时的javascript变量,导致onbeforeunload确认不触发,但它似乎有点脏。无论如何,当我等待回复时,我会做到这一点,但有没有人有更好的解决方案?

谢谢,最大

8 个答案:

答案 0 :(得分:17)

对此的一个非常简单的解决方法是做这样的事情:

<a href="mailto:foo@bar.com" target="hidden-iframe">Email me</a>
<iframe name="hidden-iframe" style="visibility:hidden;position:absolute;"></iframe>

(当然,将样式移动到自己的样式表而不是内联它们。)

答案 1 :(得分:11)

建立epascarello的解决方案,以下JQuery代码应该可以解决这个问题:

    var ignore_onbeforeunload = false;
    $('a[href^=mailto]').on('click',function(){
        ignore_onbeforeunload = true;
    });

    window.onbeforeunload = function() {
        if (!ignore_onbeforeunload){
            return "Halt! you are not supposed to leave!";
        }
        ignore_onbeforeunload = false;
    };

答案 2 :(得分:4)

添加一个标志并查看它是否被翻转,在链接点击上设置标志。

var ignore = false
window.onbeforeunload = function() {
    if (changed && !ignore) {
        return "You have unsaved changes.  Do you really want to leave this page without saving?";
    } else {
        ignore = false;
    }
}

和链接

<a class="button button-alt" href="mailto:foo@foo.com" onclick="ignore=true">Report a problem</a>

最好使用JavaScript代码添加onclick。

答案 3 :(得分:3)

我通过检查event.target设法在onbeforeunload事件内部解决了此问题。这样,您就不必使用外部变量或任何其他绑定。

window.onbeforeunload = function (event) {

    var activeElement = $(event.target.activeElement);
    // console.log('onbeforeunload', activeElement);

    var isMailto = activeElement && activeElement.is('[href^=mailto:]');
    var isTel = activeElement && activeElement.is('[href^=tel:]');

    if(!isMailto && !isTel) {
        // logic when link is "normal"
    }
};

答案 4 :(得分:1)

另一个选项,也有点hacky但有点通用的方法使beforeunload忽略某些类型的链接:

在beforeunload中,检查导致beforeunload的链接,如果它不是http或https链接,请不要打扰用户。

不幸的是,检查导致beforeunload的链接并不容易,所以这就是onclick处理程序和全局变量有点hacky的地方。

var lastClicked = null;
window.onclick = function(e){
    e = e || window.event;
    lastClicked = e.target
}
window.onbeforeunload = function(e){
    if (changed && lastClicked && lastClicked.href 
        && lastClicked.href.substring(0,4) == 'http')
        return "You have unsaved changes";
}

编辑:差点忘了,这个答案来自这里:https://stackoverflow.com/a/12065766/421243

答案 5 :(得分:0)

使用纯JS并使用focused元素的其他解决方案:

window.addEventListener("beforeunload", () => {
  const isMailTo = document.activeElement.protocol === "mailto:";

  if (!isMailTo) {
    // do your stuff
  }
});

答案 6 :(得分:0)

根据 Theiaz 的答案,您可以添加一个布尔全局变量 protectUnload,后跟一个正则表达式,以允许除链接(http(s))之外的所有外部协议:

window.onbeforeunload = function (event) {
    return (protectUnload && (typeof document.activeElement.protocol !== "undefined" && /^http(s)?:$/.test(document.activeElement.protocol))) || null; // return null == no confirm
};

它不会阻止使用 location.href 被踢出页面,但在这种情况下,您可以在公式中再添加 1 个布尔值以始终保护卸载页面(将其设置为 {{1} } 在 true 的新值之前)。

答案 7 :(得分:-1)

基于John Kurlak答案,您可以简单地使用:

def most_frequent_letter(s):
    st = s.lower().replace(' ', '')
    st = st[::-1]
    frequencies = {}
    for items in st:
        if items in frequencies:
            frequencies[items] += 1
        else:
            frequencies[items] = 1

    return max(frequencies, key=frequencies.get)