【问题标题】:Javascript wait until elements are loaded using setInterval?Javascript 等到使用 setInterval 加载元素?
【发布时间】:2017-03-02 15:18:04
【问题描述】:

我正在构建一个模块,该模块将通过 ajax 调用在网站上显示横幅。代码有两个主要部分:

  1. banner.js 异步插入到头部。此 javascript 进行 ajax 调用并将从 ajax 调用检索到的横幅插入页面占位符。

  2. 网站管理员可以将每个横幅占位符插入到页面的任何部分,如下所示:<div id="banner1"></div>

网站管理员最多可以在管理员中定义 5 个横幅并插入相同数量的占位符。问题是因为banner.js 中定义的ajax 调用可以在加载其余html 和占位符之前返回横幅。我可以在结束</body> 标记之前加载banners.js,但这不是最佳解决方案,因为某些元素会延迟DOM 解析并且横幅不会加载得那么快。

到目前为止,我找到的唯一解决方案是:

var bannerScriptListener1 = setInterval(function(){ 
  if(jQuery("#banner1").length>0){                                           
    clearInterval(bannerScriptListener1)    
    jQuery("#banner1").html(banners[1].html)
  }
},10) 
var bannerScriptListener2 = setInterval(function(){ 
  if(jQuery("#banner2").length>0){                                           
    clearInterval(bannerScriptListener2)    
    jQuery("#banner1").html(banners[2].html)
  }
},10) 
//same for banner 3,4,5

该解决方案有多糟糕?我使用谷歌任务管理器工具对其进行了测试,客户端内存消耗没有太大差异。但我可能会遗漏一些东西。有没有更好的解决办法?

编辑: 我给出了整个 html 示例来显示问题。我无法控制其他元素,我唯一的控制是控制banner.js,在banners.js 中通过ajax 调用调用的php 文件,我可以知道网站管理员可以在哪里插入div 占位符。 banner.js 可以插入头部,但我无法控制优先顺序。这只是一个非常简单的例子,实际上像 Magento 这样的平台有更多的文件和脚本,不同的模块可能会造成混乱。

<html>
  <head>
  <script type="text/javascript" src="banners.js"></script>
  <script type="text/javascript" src="othermodulescript1.js"></script>
  <script type="text/javascript" src="othermodulescript2.js"></script>
  </head>
  <body>
  <div id="banner1"></div>
  <!--Some more elements-->
  <div>lorem ipsum</div>

  <div>lorem ipsum</div>
  <!--Example of script from another module that sometimes takes 3 seconds to load
  I don't have control over this-->
  <script type="text/javascript" src="http://www.example.com/externalscript.js"></script>
  <!--Some more elements-->
  <div id="banner2"></div>
  </body>
</html>

【问题讨论】:

  • 使用 JQuery 函数将 ajaxed 横幅的插入推迟到 document.ready 事件。又名$(function() { ... do stuff that has to wait for doc ready here ... }):
  • 既然你已经在用jQuery了,那经典的$( document ).ready(function() {})不就解决了这个问题吗?
  • 香草版是document.addEventListener("DOMContentLoaded", function(event) { ... }); 或者将banner ajaxing脚本移到body底部。
  • 既然你可以控制你运行/加载哪些脚本以及在哪个roder中,为什么不总是在你执行可以阻止DOM的外部脚本之前强制标题先呈现呢?所有 DOM 阻塞都应尽可能延迟,以便您获得良好的渲染时间。加载 html/css -> 加载横幅 -> 渲染横幅 -> 加载所有其他脚本。

标签: javascript jquery html setinterval


【解决方案1】:

这不是一个好主意。如果您进行 AJAX 调用,则可以使用 onload-Event 将代码放入。

$("#myDiv").load("/ajax.js", function() {
   // do stuff after load complete
   console.log("done loading ajax.js");
});

另一个想法,如果你用 PHP 编写代码:

<script>
function loadComplete() { console.log("load complete."); }
</script>
<script src="filetoload.js" onload="loadComplete();"></script>

【讨论】:

  • 我认为您没有正确阅读我的问题。问题不在于何时加载 ajax 调用,而在于何时加载占位符到我应该从 ajax 调用插入内容的位置。
  • 加载后可以填写任意id。因此,您可以将 document.getElementById("banner1").innerHTML = yourdata; 之类的内容放入 loadComplete() 方法中。
  • 如果 #banner1 尚未加载,这将不起作用,因为 banner.js ajax 调用在 #banner1 占位符之前完成。
【解决方案2】:

您至少可以通过生成一个 jQuery 插件来处理加载来清理您的代码。

这是重用代码的最简单方法。

// File: jquery.script-listener.js
(function($) {
  $.fn.scriptListener = function(options) {
    var $target = $(this);
    var config = $.extend({
      onLoadSetValue : null,
      delay : 1000
    }, options);
    var pid = setInterval(function() {
      if ($target.length > 0) {
        clearInterval(pid);
        $target.html(config.onLoadSetValue ? config.onLoadSetValue() : '');
      }
    }, config.delay);
  }
})(jQuery);

// File: banners.js
var banners = [
  { html : '<h1>Hello World #1</h1>' },
  { html : '<h1>Hello World #2</h1>' },
  { html : '<h1>Hello World #3</h1>' },
  { html : '<h1>Hello World #4</h1>' },
  { html : '<h1>Hello World #5</h1>' }
]; // Returned from AJAX call.

// Loop over all possible banners.
for (var i = 0; i < banners.length; i++) {
  $('#banner-' + (i + 1)).scriptListener((function(id) {
    return {
      onLoadSetValue : function() {
        return banners[id].html;
      },
      delay : 10
    }
  })(i));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="banner-1"></div>
<div id="banner-2"></div>
<div id="banner-3"></div>
<div id="banner-4"></div>
<div id="banner-5"></div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2017-11-16
    • 2018-11-01
    相关资源
    最近更新 更多