如何在页面加载10秒后从javascript小部件运行代码?

时间:2016-09-03 08:38:26

标签: javascript jquery dom

我创建了一个显示弹出窗口的javascript小部件,任何人都可以在关闭</body>代码之前粘贴几行代码将其嵌入到他们的网站上。

配置它时,用户可以指定他希望在页面加载10秒后显示弹出窗口。但由于我的脚本依赖于jQuery并且在执行其主代码之前必须首先加载它 - 有时脚本执行其main()函数的时间要晚于10秒......

目前的步骤是:

  1. 网页已加载(我不知道需要多长时间)
  2. 我的脚本已加载(我不知道需要多长时间)
  3. 我的脚本在必要时加载jQuery(我不知道需要花多少时间)
  4. 只有在加载jQuery时,它才开始计算10秒,然后运行displayPopup函数
  5. 正如您所看到的,displayPopup事件发生后10秒内运行$(document).ready函数是不安全的,因为它可能无法加载jQuery或其自身。这没关系 - 这是技术上的限制我无能为力(对吗?)。

    我只需要一种方法来了解自$(document).ready事件以来已经过了多少时间。然后我将检查main()函数中的这个秒数,并决定是否需要立即显示弹出窗口(如果页面已加载&gt; 10秒前)或等待几秒钟。

    脚本安装代码:

    <script>
    (function() {
        var scriptTag = document.createElement("script");
        scriptTag.type = "text/javascript";
        scriptTag.async = true;
        scriptTag.src = "https://www.server.com/script.js";
    
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(scriptTag, s);
    })();
    </script>
    

    加载script.js的jQuery部分

    if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.12.4') {
        var script_tag = document.createElement('script');
        script_tag.setAttribute("type","text/javascript");
        script_tag.setAttribute("src",                             
            "//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"
        );
    
        if (script_tag.readyState) {
          script_tag.onreadystatechange = function () { 
            if (this.readyState == 'complete' || this.readyState == 'loaded') {
              scriptLoadHandler();            
            }
          };
        } 
        else { 
          script_tag.onload = scriptLoadHandler;
        }
    
        (document.getElementsByTagName("head")[0] || 
            document.documentElement).appendChild(script_tag);
    } 
    else {
      jQuery = window.jQuery;
      main();
    }
    
    function scriptLoadHandler() {
      jQuery = window.jQuery.noConflict(true);
      main();
    }
    

    主要功能:

    function main() {
      setTimeout(function() {
        displayPopup();
      }, settings['numberOfSeconds'] * 1000);
    }
    

4 个答案:

答案 0 :(得分:1)

在安装代码中,设置一个捕获当前时间的全局变量。由于这是在<body>结束之前,它应该在DOM加载时正确启动。然后在main()函数中,检查变量中经过了多少时间。如果超过10秒,您可以立即显示弹出窗口。如果它更少,你可以计算已经过去的时间,并设置一个10秒后真正通过的超时:

<script>
(function() {
  window.myPopupWidgetStartDate = Date.now();

  var scriptTag = document.createElement("script");
  scriptTag.type = "text/javascript";
  scriptTag.async = true;
  scriptTag.src = "https://www.server.com/script.js";

  var s = document.getElementsByTagName('script')[0];
  s.parentNode.insertBefore(scriptTag, s);
})();
</script>


function main() {
  var secondsSinceInstall = Math.round((window.myPopupWidgetStartDate - Date.now());

  if (secondsSinceInstall > settings['numberOfSeconds']) {
    displayPopup();
  } else {
    setTimeout(function() {
      displayPopup();
    }, settings['numberOfSeconds' - secondsSinceInstall] * 1000);
  }
}

答案 1 :(得分:1)

你不必为时间或间隔而烦恼。从我的观点来看,它非常简单,考虑到我把一切都搞定了。

获得document.ready后获取当前时间戳。设为documentReadyAt

加载jquery后再次获取当前时间戳。设为jqReadyAt

jqReadyAtdocumentReadyAt进行比较,找出差异。如果jQuery已经存在,差异将是微不足道的。几毫秒的问题。如果必须加载jquery将超过100ms到几秒。

开始计算您喜欢的任何内容。

var documentReadyAt, jqReadyAt;
document.onreadystatechange = function () {
    if (document.readyState === "complete" && documentReadyAt === undefined) {
        documentReadyAt = new Date();
        loadJQ(); // Loading jQuery part of script.js. 
    }
}

//function loadJQ(){ ...whatever you wrote to load jquery }

//For the sake of handling same logic in one place will assign a variable to jqReadyAt here. Could also be done at `main()` without noticeable cost.
function scriptLoadHandler() {
  jqReadyAt = new Date();
  jQuery = window.jQuery.noConflict(true);
  main();
}

//Main will change to that one.
function main() {
  var millisPassedSinceDocLoaded = jqReadyAt.getTime() - documentReadyAt.getTime();
  setTimeout(function() {
    displayPopup();
  }, (settings['numberOfSeconds'] * 1000) - millisPassedSinceDocLoaded );
}

答案 2 :(得分:1)

您需要使用 performance.timing API。有很多有用的数据可供使用,例如domContentLoadedEventEnd,domContentLoadedEventStart,loadEventStart,loadEventEnd等,用于测量自dom ready事件被触发以来经过的时间,在 main 函数中使用下面的代码获得通过的时间。一旦完成,您现在可以决定如何继续。

var timePassedSinceDomReady = new Date() - new Date(performance.timing.domContentLoadedEventEnd);
console.log('total time passed: ' + timePassedSinceDomReady + 'ms');

大多数现代浏览器都支持它。有关时间 API的更多详细信息,请参阅topichttps://developer.mozilla.org/en-US/docs/Web/API/PerformanceTiming

答案 3 :(得分:-1)

您可以尝试为加载jQuery时设置一个标志,然后直接从document.ready启动setTimeout,并在显示弹出窗口之前检查是否加载了jQuery。

否则你可能想看一下这个question