如何配置 jQuery.Lazy() 插件仅在加载第一个元素后才加载第二个元素

Posted

技术标签:

【中文标题】如何配置 jQuery.Lazy() 插件仅在加载第一个元素后才加载第二个元素【英文标题】:How to configure jQuery.Lazy() Plugin to load second element ONLY after first is loaded 【发布时间】:2021-11-24 13:30:26 【问题描述】:

我正在使用带有 ASP.NET Core Razor 页面和 Bootstrap 4 应用程序的 jQuery.Lazy() 插件通过 AJAX 从数据库中检索 2 个列表(见图)。一切都很好,除了一件事:在移动设备上,我不知道如何延迟Content Data 2 List 的检索/显示,直到用户在浏览器中向下滚动到足够远以使Title 2/content 在他们的视图中港口。桌面上不存在此问题(因为列表并排显示并且都需要检索),但在移动设备上,如果用户从不向下滚动,我不想检索Content Data 2 List足以看到它。

当页面首次加载时,两个标题都将与一个带有微调器的小数据区域一起显示。使用 AJAX,我检索数据,隐藏微调器,然后在其位置显示检索到的数据。我过度简化的 html 是:

<div class="col-sm-12 col-lg-6 lazy" data-loader="lazyAJAX1">
    <div class="col">
        <label class="">Title 1</label>
    </div>

    <div class="col">
        <div class="">
            <div class="lp-spinner mt-4 mb-4">
            </div>
        </div>
        <div id="Content1List" class="col-12">
        </div>
    </div>
</div>

<div class="col-sm-12 col-lg-6 lazy" data-loader="lazyAJAX2">
    <div class="col">
        <label class="">Title 2</label>
    </div>

    <div class="col">
        <div class="">
            <div class="lp-spinner mt-4 mb-4">
            </div>
        </div>
        <div id="Content2List" class="col-12">
        </div>
    </div>
</div>

而相关的JQuery是:

$(".lazy").Lazy(
    scrollDirection: 'vertical',
    effect: 'fadeIn',
    visibleOnly: true,
    bind: 'event',
    threshold: 0,
    lazyAJAX1: function () 
        loadAJAX1Partial();
    ,
    lazyAJAX2: function () 
        loadAJAX2Partial();
    
);

玩了一段时间后,我相信问题出在数据加载器上。具体来说,data-loader="lazyAJAX2" 因为它最初在页面加载时显示在用户的视口中,因此会自动检索Content Data 2 List。我想要的是 Lazy() 首先检索 Content Data 1 List (这会将 Title 2 内容向下推送并移出用户的视口),然后为 Content Data 2 List 启用/激活 Lazy() 以便当用户滚动时向下到达Title 2Content Data 2 List 将被检索。我希望这是有道理的。

我正在考虑使用 addClass() 来尝试解决这个问题,但也许有更多 .Lazy() 经验的人对如何做到这一点有更好的想法。

提前感谢您的任何建议/帮助... :)

【问题讨论】:

【参考方案1】:

我认为,问题在于,在您的方法中,将同时请求两个表,因为它们最初没有内容,因此非常小。当用户向下滚动时,他很可能会触发两次加载,因为只有标题。

如果您只想在加载第一个表之后再加载第二个表,一个简单的方法是使用Lazy 的两个实例。如下图所示。它未经测试,但我想你明白了。

$("#table1").Lazy(
  tableLoader: function() 
    if (loadAJAX1Partial()) 
      $("#table2").Lazy(
        tableLoader: function() 
          loadAJAX2Partial()
        
      );
    
  
);
<div id="table1" class="col-sm-12 col-lg-6" data-loader="tableLoader">
  <div class="col">
    <label class="">Title 1</label>
  </div>
  <div class="col">
    <div>
      <div class="lp-spinner mt-4 mb-4"></div>
    </div>
    <div id="Content1List" class="col-12"></div>
  </div>
</div>

<div id="table2" class="col-sm-12 col-lg-6" data-loader="tableLoader">
  <div class="col">
    <label class="">Title 2</label>
  </div>
  <div>
    <div>
      <div class="lp-spinner mt-4 mb-4"></div>
    </div>
    <div id="Content2List" class="col-12"></div>
  </div>
</div>

【讨论】:

谢谢@eisbehr。事实上,解决方案非常符合这些思路。在下面的答案中查看我的完整解释。【参考方案2】:

经过反复试验,我找到了解决困境的方法。基于 @eisbehr 的建议,秘密在于 DOM 刷新。

问题是:当通过 loadAJAX1Partial() 检索第一个 Content Data 1 List 时,Content Data 2 List 也通过 loadAJAX2Partial() 异步调用/检索。根据数据(从服务器返回的大小和时间),这两个列表中的任何一个都可以按任何顺序返回。使用@eisbehr 建议的内容并不能保证顺序,也不能将调用包装在 async/await 中(至少我不能不断地让它工作)。

那么答案是什么?使用 setTimeout() 或 requestAnimationFrame() 并按照@eisbehr 的建议对检索进行排序。

有一篇关于 DOM 以及它如何刷新浏览器中的内容的非常好的文章(请参阅 When DOM Updates Appear to Be Asynchronous),但本质上您需要给浏览器时间来更新/刷新屏幕上的 Content Data 1 List,以便 Lazy可以做到这一点。

所以在我的第一个 AJAX 调用 (loadAJAX1Partial()) 中,成功时:(在检索到列表后),我只需调用:setTimeout(loadAssetLists, 500) 到 loadAssetLists() 但给它 500 毫秒(1/2 秒)允许在初始化'Lazy'之前刷新浏览器屏幕:

function loadAssetLists() 
    $(".lazy").Lazy(
        scrollDirection: 'vertical',
        effect: 'fadeIn',
        visibleOnly: true,
        bind: 'event',
        threshold: 0,
        lazyAJAX2: function () 
            loadAJAX2Partial();
        ,
        lazyAJAX3: function () 
            loadAJAX3Partial();
        
        // Chain additional AJAX calls here, if needed
    );
;

loadAJAX1Partial();

Lazy 初始化之前允许屏幕刷新会显示Content Data 1 List,从而将Content Data 2 List 视口向下推。这似乎一直有效。

还请注意,一旦视口向下移动,您可以轻松地链接多个加载(即 loadAJAX2Partial()、loadAJAX3Partial() 等),并且一切都按预期工作。

最棒的是:当用户完全显示页面时(通过部分向下滚动以检索所有 AJAX 数据),单击新页面,然后单击“返回”按钮,所有 'Lazy' 功能都可以正常工作正如预期的那样。

我希望这个解决方案和解释对其他人有所帮助,因为我不能是唯一一个遇到这个问题的人...... :)

【讨论】:

以上是关于如何配置 jQuery.Lazy() 插件仅在加载第一个元素后才加载第二个元素的主要内容,如果未能解决你的问题,请参考以下文章

如何确保Magento 2中的RequireJS在加载其他脚本之前加载jQuery?我发现嵌套需要解决这个问题

jQuery Lazy Load 图片延迟加载

jQuery Lazy Load图片懒加载

jQuery 插件 (DataTables) 仅在页面刷新时正确加载

Wordpress插件开发 - 仅在需要的地方加载排队的文件

javascript插件仅在鼠标进入视口时起作用