【问题标题】:call function after load event end加载事件结束后调用函数
【发布时间】:2016-04-08 23:25:00
【问题描述】:

我正在使用 Navigation timing object 计算导航开始和加载事件结束之间的整页延迟。

我的目标是在加载事件完成后获得performance.timing.loadEventEnd - performance.timing.navigationStart;

但是,在加载事件中调用此代码,加载事件结束无法测量。所以,我需要推迟它并在加载事件之外运行。

这是我的要求

  1. 在加载事件结束后调用myfunction
  2. 我不想使用setTimeout 这样的计时功能。如果setTimeout保证在其他加载事件中不唤醒,则可以使用。
  3. 我不想在load 事件中计算时间延迟。 (比如在load事件的顶部调用new Date().getTime()performance.now(),并在完成之前再次调用它并减去它。)因为我使用了一堆也调用加载事件的第3方库。我无法处理所有这些。
  4. 应该可以跨浏览器环境,IE>=10
$(window).ready(function(){
    console.log("domContentLoadedEventStart: "
        +performance.timing.domContentLoadedEventStart);
    console.log("domContentLoadedEventEnd: "
        +performance.timing.domContentLoadedEventEnd);
});
// result:
// > domContentLoadedEventStart: 1451979544555
// > domContentLoadedEventEnd: 0

$(window).load(function(){
    console.log("domcomplete: "+performance.timing.domComplete);
    console.log("loadEventStart: "+performance.timing.loadEventStart);
    console.log("loadEventEnd: "+performance.timing.loadEventEnd);
});
// result:
// > domcomplete: 1451979906417
// > loadEventStart: 1451979906417
// > loadEventEnd: 0

编辑

我已经测试过这个套件。此测试用例旨在在加载函数回调期间唤醒setTimeout

// myfunction which will be called by setTimeout in firstLoadCallback.
function myfunction(){
    console.log("called myfunction");
}

// first load callback
$(window).load(function firstLoadCallback(){
    var startTicks = performance.now();

    // register myfunction with setTimeout
    setTimeout(myfunction, 0);

    // sleep +500ms
    while(performance.now() - startTicks < 500){
        ;
    }

    var diffTicks = performance.now() - startTicks;

    console.log("first ticks: "+diffTicks);
});

// second load callback
$(window).load(function secondLoadCallback(){
    var startTicks = performance.now();

    // sleep +500ms
    while(performance.now() - startTicks < 500){
        ;
    }

    var diffTicks = performance.now() - startTicks;

    console.log("second ticks: "+diffTicks);
});

// third callback from other file: other-file.js
$(window).load(function thirdLoadCallback(){
    var startTicks = performance.now();

    // sleep +500ms
    while(performance.now() - startTicks < 500){
        ;
    }

    var diffTicks = performance.now() - startTicks;

    console.log("third ticks: "+diffTicks);
});

// result:
// first ticks: 500.005
// second ticks: 500.0050000000001
// third ticks: 500.0049999999999
// called myfunction

从这个结果来看,setTimeout 注册的回调在函数调用树结束之前没有被唤醒。如果这个结果保证跨浏览器工作,@BenjaminGruenbaum 的答案可能是正确的。

我会发布另一个关于它的问题。

【问题讨论】:

  • 您必须安排一个任务在加载事件完成后运行。没有钩子 - 你必须使用 setTimeout(fn, 0) 或类似的东西。
  • @BenjaminGruenbaum 如果在myfunction 之后调用其他加载回调函数怎么办? setTimeout 能保证吗?
  • setTimeout 将注册一个事件以在下一个刻度执行。所以是的。但是正如您已经提到的,您不想使用 setTimeout,您可以查看 promise
  • @Lukabot setTimeout 必须在 $(window).load 事件内。
  • @Rajesh 我的意思是,如果我在第一次加载回调中注册了setTimeout。之后,我的第二个加载回调开始运行。如果第二个功能需要太多时间怎么办? setTimeout 是否在第二个功能运行时唤醒? @BenjaminGruenbaum 是的,我把它放在正确的位置。

标签: javascript jquery events


【解决方案1】:

除了嵌套加载事件和 setTimeout 之外,您别无选择。

$(window).load(function(){ 
    setTimeout(function() { 
        // your above code goes here
    }, 0); // 0, since we just want it to defer.
});

// or without jQuery:
window.addEventListener("load", function() { // IE9+
    setTimeout(function() { 
        // your above code goes here
    }, 0); // 0, since we just want it to defer.
});

【讨论】:

    猜你喜欢
    • 2019-11-11
    • 1970-01-01
    • 2010-10-07
    • 2022-11-29
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 1970-01-01
    相关资源
    最近更新 更多