如何在 javascript 中实现 unload 延迟跳转 或 有效的不访问网络、不抢光 CPU 的 sleep 方法?


最近开发一个项目遇到个问题,需要实现在页面跳转前,发送多个跟踪请求。由于跳转的过程不受我们控制,也不想干预客户网站的代码,所以不能通过跟踪请求完成后回调网站代码来实现。

我的想法就是在跟踪发起时给某个计数器加 1,在每个跟踪结束时给计数器减 1;unload 里判断计数器的值,不等于 0 就 sleep 一些毫秒,等于 0 就返回,unload 就可以继续了。前提是:1.有 sleep 函数 2.sleep 是同步的(阻塞的)

请问有何办法可以实现?当然如果有其他的能实现 unload 延迟(不能弹框哦)的方法也请告知,谢谢了。

注:何为跟踪请求: 就是为了监测页面或商业效果,将页面或商品的一些参数发往不同的监测系统,通常利用 new Image() 来发送(跨域)。


说下提这个问题的原因。我在做一些 web 监测相关的项目,本来遇到这种跳转的问题以前都是让客户自己延时来解决的,但是前几天发现,Google Tag Manager 里增加了一个“事件监听器”的代码类型,其下的“表单提交监听器”有个“等待代码”的选项,可以实现最多 2 秒(如果提前完成就不到 2 秒)的延时跳转。

我想知道他们采用的什么方式,是 submit 事件有什么特殊的办法(点击却没给这个选项)?还是他们自己实现了延时?可惜代码是压缩过的,跟踪了一遍也没得到有价值的信息。


突然想明白了,我想之所以 google 没给点击(也可能跳转呀)也加上延时选项,原因可能就是他们也没能实现延时跳转的功能,而对于 FROM,可以利用 preventDefault 阻止提交,在 2 秒后(或完成后)再触发表单的提交,用一个状态变量来判断是要执行我们的代码还是还是真的提交。貌似链接也可以哦,我有空再试试。

唉,我想可能确实没什么好的办法实现延时!

实验代码如下(用 jQuery 方便就不写原生 JS 了):


 <form action="http://www.baidu.com/">
    <button type="submit">Submit</button>
</form>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
    $(document).submit(function(evt) {
        if (window.TM_FLAG) return;
        else window.TM_FLAG = 1;

        evt.preventDefault();
        setTimeout(function() {
            $(evt.target).submit();
            delete window.TM_FLAG;
        }, 2000);

        console.log("run code 1");
        console.log("run code 2");
        console.log("run code 3");
    });
</script>

web web前端开发 HTML JavaScript

JAPSEN 10 years, 11 months ago

我写一个同步阻塞的sleep吧,这是我在学习setTimeout时看别人的测试例子。


 //占cpu的做法
var sleep=function(delayTime){
    var startTime=new Date();
    while(new Date()-startTime<=delayTime){

    }
};
//jquery Deferred
function wait(ms) {
  var deferred = $.Deferred();
  setTimeout(deferred.resolve, ms);

 // We just need to return the promise not the whole deferred.
 return deferred.promise();
}

// Use it
wait(5500).then(function () {
    alert('hahahaah');
  // Do something brilliant here!
});

真希波マリ answered 10 years, 11 months ago

Your Answer