【问题标题】:Safari not letting function finish before page unload?Safari在页面卸载之前不让功能完成?
【发布时间】:2011-09-15 20:45:39
【问题描述】:
function log(name, value)
{
    mylog.push({'name':name, 'value':value});
}

function flush()
{   
    for (i = 0 ; i < mylog.length ; i++){
        url_str += '&n[]=' + mylog[i].name + '&v[]=' + mylog[i].value;
    }
    url_str += '&r='+Math.floor(Math.random() * 100000);

    var img = new Image();
    var url = 'http://somedomain.com/pixel.php?' + url_str;
    img.src = url;
}

if (window.attachEvent) 
    window.attachEvent('onunload', flush);
else if (window.addEventListener) 
    window.addEventListener('unload', flush, false);

我正在编写一些代码来跟踪用户交互以查找页面上的热点。其中大部分已经完成并且可以在大多数浏览器上运行,但我目前对 Safari 5.0.5/Mac 10.6 感到困惑(顺便说一句,它也可以在 Windows XP 上使用 Safari 5.0.1 进行复制)。给我带来困难的部分是页面传输期间的链接点击。例如,下面的代码将我带到 someotherpage.html:

<form onclick="log('LINK_CLICKED', 'some other page'); this.submit();" action="someotherpage.html">Some other page</form>

该站点在所有浏览器中都将我带到 someotherpage.html,但只有 Safari 5.0.5/Mac 10.6 不会在日志中显示 LINK_CLICKED。在 Safari 检查器中进行一些控制台检查后,我发现 Safari 出现“加载资源失败”错误。我怀疑这是因为虽然可以调用 URL,但浏览器决定继续前进(?)。

无论如何,我已经尝试了 beforeunload 事件并使用 setTimeout 来延迟页面卸载。我是 考虑完全更改 HTML 表单,但这将是一项相当大的努力。尽管如此,我还是愿意接受它,除非有人有跳过我注意力的想法。关于它如何在 Safari 5.0.5 (Mac 10.6) 上运行的任何建议?

【问题讨论】:

    标签: javascript dom safari osx-snow-leopard


    【解决方案1】:

    我认为您只是遇到了一种竞争状况,可以通过对跟踪像素负载的回调来缓解这种状况。

    function log(name, value, callback)
    {
        mylog.push({'name':name, 'value':value, 'callback':callback});
    }
    
    
    function flush()
    {   
        for (i = 0 ; i < mylog.length ; i++){
            url_str += '&n[]=' + mylog[i].name + '&v[]=' + mylog[i].value;
        }
        url_str += '&r='+Math.floor(Math.random() * 100000);
    
        var img = new Image();
        img.onload = logReady;
        var url = 'http://somedomain.com/pixel.php?' + url_str;
        img.src = url;
    }
    
    function logReady()
    {
      for (i = 0 ; i < mylog.length ; i++){
           mylog[i].callback();
        }
    }
    
    
    
    <form onclick="log('LINK_CLICKED', 'some other page', function() { form.submit(); });" action="someotherpage.html">Some other page</form>
    

    【讨论】:

    • 谢谢!我混合使用了您的解决方案和stackoverflow.com/questions/4945764/…。通过 log 函数发送回调并让 CORS 进行调用。有一些权衡,但它们或多或少是可以容忍的。
    猜你喜欢
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    相关资源
    最近更新 更多