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

How to configure jQuery.Lazy() Plugin to load second element ONLY after first is loaded

我正在使用 jQuery.Lazy() 插件与 ASP.NET Core Razor Pages 和 Bootstrap 4 应用程序通过 AJAX 从数据库中检索 2 个列表(见图)。一切都很好,除了一件事:在移动设备上,我无法弄清楚如何延迟 Content Data 2 List 的 retrieval/display 直到用户在浏览器中向下滚动到足够远,以便 Title 2/content 在他们的视口中。问题是在台式机上 non-existent(因为列表显示 side-by-side 并且都需要检索),但在移动设备上我不想检索 Content Data 2 List 如果用户永远不会向下滚动到足以看到它。

当页面首次加载时,两个标题都会与一个带有微调器的小数据区域一起显示。使用 AJAX,我检索数据,隐藏微调器,然后在其位置显示检索到的数据。我的 over-simplified 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-loaders 上。具体来说,data-loader="lazyAJAX2" 因为它最初在页面加载时显示在用户的视口中,因此会自动检索 Content Data 2 List。我想要的是让 Lazy() 首先检索 Content Data 1 List(这会将 Title 2 内容向下推到用户的视口之外),然后 enable/activate Lazy() for Content Data 2 List 这样当用户向下滚动到足以到达 Title 2 时,将检索 Content Data 2 List。我希望这是有道理的。

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

提前感谢任何 suggestions/help...:)

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

如果您只想在第一个 table 加载后加载第二个 table,一个简单的方法是使用 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 的建议,秘密在于 DOM 刷新。

问题是:当通过loadAJAX1Partial()获取第一个Content Data 1 List时,Content Data 2 List也是通过loadAJAX异步获取的called/retrieved 2部分()。根据数据(从服务器到 return 的大小和时间),这两个列表中的任何一个都可以 return 以任何顺序排列。使用@eisbehr 建议的内容并不能保证顺序,也不能将调用包装在 async/await 中(至少我无法持续让它工作)。

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

有一篇关于 DOM 以及它如何刷新浏览器中的内容的非常好的文章(参见 When DOM Updates Appear to Be Asynchronous),但本质上你需要给浏览器时间 update/refresh Content Data 1 List 在屏幕上,以便 Lazy 可以施展魔法。

所以在我的第一个 AJAX 调用 (loadAJAX1Partial()) 中,成功时:(在检索列表之后),我简单地调用:setTimeout(loadAssetLists, 500) 来加载资产列表() 但是给它 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 视口向下推。这似乎一直有效。

另请注意,一旦视口向下移动,您就可以轻松地链接多个加载(即加载AJAX2Partial()、加载AJAX3Partial() 等)并且一切正常预期。

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

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