简体   繁体   English

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

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

I am using jQuery.Lazy() Plugin with ASP.NET Core Razor Pages and Bootstrap 4 app to retrieve 2 lists from the DB via AJAX (see photo).我正在使用带有 ASP.NET Core Razor Pages 和 Bootstrap 4 应用程序的jQuery.Lazy()插件通过 AJAX 从数据库中检索 2 个列表(见图)。 Everything is working great except for one thing: on a mobile device, I can't figure out how to delay the retrieval/display of Content Data 2 List until the user scrolls down far enough in the browser so that Title 2/content is in their view port.一切都很好,除了一件事:在移动设备上,我不知道如何延迟Content Data 2 List的检索/显示,直到用户在浏览器中向下滚动到足够远的位置,以便Title 2/content在他们的视口。 The problem is non-existent on desktops (since the lists are displayed side-by-side and both need to be retrieved), but on a mobile device I don't want to retrieve the Content Data 2 List if the user never scrolls down far enough to see it.该问题在台式机上不存在(因为列表并排显示并且都需要检索),但在移动设备上,如果用户从不向下滚动,我不想检索Content Data 2 List远到足以看到它。

在此处输入图片说明

When the page first loads, both of the titles are displayed along with a small data area with a spinner.当页面第一次加载时,两个标题都与一个带有微调器的小数据区域一起显示。 Using AJAX, I retrieve the data, hide the spinner, and then display the retrieved data in it's place.使用 AJAX,我检索数据,隐藏微调器,然后在它的位置显示检索到的数据。 My over-simplified HTML is:我过度简化的 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>

And the related JQuery is:相关的 JQuery 是:

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

After playing with it for a while, I believe the problem is with the data-loaders.玩了一段时间后,我相信问题出在数据加载器上。 Specifically, data-loader="lazyAJAX2" because it is initially displayed in the user's view port on page load, and therefore automatically retrieves the Content Data 2 List .具体来说, data-loader="lazyAJAX2"因为它最初在页面加载时显示在用户的视data-loader="lazyAJAX2" ,因此会自动检索Content Data 2 List What I want is for Lazy() to retrieve Content Data 1 List first (which will push the Title 2 content down and out of user's view port), and then enable/activate Lazy() for Content Data 2 List so that when the user scrolls down far enough to reach Title 2 , the Content Data 2 List will be retrieved.我想要的是 Lazy() 首先检索Content Data 1 List (这会将Title 2内容向下推送并移出用户的视口),然后为Content Data 2 List启用/激活 Lazy(),以便当用户向下滚动到Title 2Content Data 2 List将被检索。 I hope that makes sense.我希望这是有道理的。

I was contemplating using addClass() to try and get around this, but maybe someone with more .Lazy() experience has a better idea on how to do this.我正在考虑使用 addClass() 来尝试解决这个问题,但也许有更多 .Lazy() 经验的人对如何做到这一点有更好的想法。

Thanks for any suggestions/help in advance... :)感谢您提前提供任何建议/帮助... :)

I would think, the problem is, that on your approach, both tables will be requested at the same time, because they initially have no content and therefore are very small.我认为,问题是,在您的方法中,将同时请求两个表,因为它们最初没有内容,因此非常小。 When the user scrolls down he will trigger both loads with a high probability, because there are only headlines.当用户向下滚动时,他将很有可能触发这两个加载,因为只有标题。

If you want to only load the second table after first has been loaded, a easy way would be to use two instances of Lazy .如果您只想在加载第一个表后加载第二个表,一个简单的方法是使用两个Lazy实例。 Like shown below.如下图所示。 It's untested but I think you get the idea.它未经测试,但我认为你明白了。

 $("#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>

After some trial and error, I found a solution to my dilemma.经过一些试验和错误,我找到了解决我的困境的方法。 Building on what @eisbehr suggested, the secret lies within the DOM refresh.基于@eisbehr 的建议,秘密就在 DOM 刷新中。

The problem is: when the first Content Data 1 List is retrieved via loadAJAX1Partial(), Content Data 2 List is also called/retrieved asynchronously via loadAJAX2Partial().问题是:当第一个Content Data 1 List通过 loadAJAX1Partial() 检索时, Content Data 2 List也通过 loadAJAX2Partial() 异步调用/检索。 Depending on the data (size and time taken to return from the server), either of these 2 lists could return in any order.根据数据(从服务器返回所需的大小和时间),这两个列表中的任何一个都可以以任何顺序返回。 Using what @eisbehr suggested doesn't guarantee the sequence, nor does wrapping the calls in async/await (at least I was not able to constantly get it to work).使用@eisbehr 建议的内容并不能保证顺序,也不能将调用包装在 async/await 中(至少我不能经常让它工作)。

So what is the answer?所以答案是什么? Using setTimeout() or requestAnimationFrame() and sequencing the retrieval as @eisbehr suggested.使用 setTimeout() 或 requestAnimationFrame() 并按照@eisbehr 的建议对检索进行排序。

There is a really good article about DOM and how it refreshes the contents in the browser (see When DOM Updates Appear to Be Asynchronous ), but essentially you need to give the browser time to update/refresh Content Data 1 List on screen so that Lazy can do it's magic.有一篇关于 DOM 以及它如何刷新浏览器中的内容的非常好的文章(请参阅When DOM Updates Appear to Be Asynchronous ),但本质上您需要给浏览器时间来更新/刷新屏幕上的Content Data 1 List ,以便Lazy可以做它的魔法。

So in my first AJAX call (loadAJAX1Partial()), on success: (after the list is retrieved), I simply call: setTimeout(loadAssetLists, 500) to loadAssetLists() BUT give it 500ms (1/2 second) to allow for the browser screen to refresh before initializing '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();

Allowing the screen to refresh BEFORE Lazy is initialized displays the Content Data 1 List , thereby pushing the Content Data 2 List viewport down.允许屏幕在Lazy初始化之前刷新显示Content Data 1 List ,从而将Content Data 2 List视口向下推。 And that seems to work consistently.这似乎一直有效。

Notice also that once the viewport is moved down, you can easily chain multiple loads (ie loadAJAX2Partial(), loadAJAX3Partial(), etc.) and everything works as expected.另请注意,一旦视口向下移动,您就可以轻松链接多个加载(即 loadAJAX2Partial()、loadAJAX3Partial() 等),一切都按预期进行。

And the great thing is: when the user fully displays the page (by scrolling partially down to retrieve all the AJAX data), clicks to a new page, and then clicks the 'Back button, all the 'Lazy' functionality works as expected.伟大的事情是:当用户完全显示页面(通过部分向下滚动以检索所有 AJAX 数据),单击新页面,然后单击“返回”按钮时,所有'Lazy'功能都按预期工作。

I hope this solution and explanation is helpful to others, because I cannot be the only one who has faced this issue... :)我希望这个解决方案和解释对其他人有帮助,因为我不可能是唯一遇到这个问题的人...... :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM