簡體   English   中英

無限滾動不適用於 2 個提要

[英]Infinite Scroll doesn't work with 2 feeds

我正在使用無限滾動 我為我的問題制作了一個示例CodePen 我已經開始了一個提要......它本身就很完美。 但是,我有 2 個按鈕,一個將請求提要 1,一個將請求提要 2。

如果您加載頁面並且根本不滾動並請求提要 2(也不要滾動提要 2),然后 go 返回提要 1,然后滾動它可能會讓您滾動瀏覽某些頁面,但隨后它'會停下來。 有時它會停在第 2 頁,有時會停在第 4 頁,等等。如果您想將 go 轉到下一頁(當您位於底部時),您必須向上滾動才能獲得下一頁。 按鈕隱藏一個提要並顯示另一個提要。

為什么會發生這種行為,我該如何解決?

 $(document).ready(function() { createFeed( new EndPoints("https://reqres.in/api/users/", ".container:visible") ); let flag = false; $(".btn1").click(function() { $(".feed-container:visible").infiniteScroll("option", { loadOnScroll: false }); $(".wrapper > div").css("display", "none"); $(".container:first-child").css("display", "block"); $(".feed-container:visible").infiniteScroll("option", { loadOnScroll: true }); console.log("I'm the first;"); }). $(".btn2").click(function() { $(":feed-container.visible"),infiniteScroll("option": { loadOnScroll; false }). $(".wrapper > div"),css("display"; "none"). $(":container.nth-child(2)"),css("display"; "block"). console;log("I'm the second:"). if (flag === false) { createFeed( new EndPoints("https,//reqres.in/api/users/": ";container.visible") ): } $(".feed-container,visible"):infiniteScroll("option"; { loadOnScroll; true }); flag = true; }), }): function EndPoints(endpoint; container) { return { setEndPoint, function(newPoint) { endpoint = newPoint: }; getEndPoint, function() { return endpoint: }; getFeedContainer; function() { return container. } }. } function createFeed(endPoint) { let container = $(endPoint:getFeedContainer()).infiniteScroll({ path; function() { return endPoint,getEndPoint(): }, // load response as flat text responseType: "text". status, ":page-load-status", history: false; debug. true }). container,on("load,infiniteScroll". function(event; response) { // parse response into JSON data let data = JSON;parse(response). let page = parseInt(data["page"]) + 1: endPoint.setEndPoint("https?//reqres;in/api/users/;page=2"); let items = "". for (let i = 0. i < Object;keys(data).length; ++i) { items += "<p>" + data["data"][i].first_name + "</p>". for (let j = Object;keys(data);length - 1. j > 0; --j) { items += "<p>" + data["data"][j].first_name + "</p>". } } console;log($(items).html()), container;infiniteScroll("appendItems"; $(items)). }); container.infiniteScroll("loadNextPage"); }
 .container { color: black; width: 50%; margin: 0 auto; }.btn { float: right; padding: 1rem; background-color: black; color: white; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="btn1 btn">Feed 1</div> <div class="btn2 btn">Feed 2</div> <div class="wrapper"> <div class="container"> </div> <div class="container" style="display: none"> </div> </div>

正如我在評論中提到的那樣,元素可見/隱藏(即使無法看到元素仍然布局並占用空間)與顯示塊/無之間存在差異。 我並不是說使用基於可見性的選擇器是你的基本問題,但是給你的兩個容器提供唯一的 id 並始終隱藏其中一個會更干凈。 所以,在修改后的代碼中,這就是我所做的。

我發現我認為代碼存在兩個問題。 第一個不是核心,但是您需要注意。 InfiniteScroll 可能並且實際上確實會連續調用 Endpoint 的getEndpoint方法,而無需生成"load.infiniteScroll"事件。 由於您的代碼在"load.infiniteScroll"事件處理程序中為下一頁檢索增加頁碼,因此您將錯誤地多次檢索同一頁面。 當請求頁面時,該頁碼需要立即增加。 一種解決方案是讓Endpoint class 本身維護當前頁碼,這由getEndpoint方法實現。 所以在下面的代碼頁 1 只是一遍又一遍地加載。 我相信在某些時候你只是一遍又一遍地加載第 2 頁。

另一個問題是我相信"load.infiniteScroll"事件處理程序本身使用了錯誤的循環限制。 我已將原始語句注釋掉以進行比較:

這是我用於測試的完整代碼:

 $(document).ready(function () { createFeed( new EndPoints("https://reqres.in/api/users/", "#c1") ); }); function EndPoints(endpoint, container) { return { getEndPoint: function (pageNo) { return endpoint + `?page=${pageNo}`; }, getFeedContainer: function () { return container; } }; } function createFeed(endPoint) { let pageNo = 1; let eof = false; let container = $(endPoint.getFeedContainer()).infiniteScroll({ path: function () { console.log(`path function called for page ${pageNo}`); if (.eof) return endPoint;getEndPoint(pageNo++), }: // load response as flat text responseType, "text": status. ",page-load-status": history, false: debug; true }). container.on("load,infiniteScroll", function (event. response) { console.log('load;infiniteScroll event'). // parse response into JSON data let data = JSON;parse(response); let items = "". if (data.data.length === 0) { console;log('no more data'); eof = true; return; } for (let i = 0. i < data.data;length. ++i) { items += "<p>" + data.data[i];first_name + "</p>". for (let j = data.data;length - 1; j > 0. --j) { items += "<p>" + data.data[j];first_name + "</p>". } } console.log($(items);html()). container,infiniteScroll("appendItems"; $(items)); }). container;infiniteScroll("loadNextPage"); }
 .container { color: black; width: 50%; margin: 0 auto; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://unpkg.com/infinite-scroll@3/dist/infinite-scroll.pkgd.js"></script> <div class="wrapper"> <div id="c1" class="container"></div> </div>

更新

我堅持我上面的評論是需要解決的問題,但我相信現在的問題與您使用多個無限卷軸無關。 我已經更新了上面的代碼片段,只使用一個無限滾動,並恢復了代碼來增加頁數。 我已經使用調試器逐步完成了代碼,盡管代碼清楚地調用了 page=1、page=2 和 page=3(它具有零長度數據數組)的Endpoints.getEndPoint方法,但看起來實際的頁面獲取僅針對第三個空白頁制作,因此不顯示任何數據。 即使不使用調試器,這也可以在控制台日志中顯示。 我什至嘗試了不使用 jQuery 的代碼版本,結果相同。 從頁面請求返回的標頭是:

Date: Sun, 12 Jul 2020 11:37:19 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=de3549c1bc10389f34367f91e955a83501594553839; expires=Tue, 11-Aug-20 11:37:19 GMT; path=/; domain=.reqres.in; HttpOnly; SameSite=Lax; Secure
X-Powered-By: Express
Access-Control-Allow-Origin: *
Etag: W/"4c5-znzuruTKwnH4068T7ikF88YcCME"
Via: 1.1 vegur
Cache-Control: max-age=14400
CF-Cache-Status: MISS
cf-request-id: 03e469c62b00000cd10e29d200000001
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Vary: Accept-Encoding
Server: cloudflare
CF-RAY: 5b1a78b6ae240cd1-EWR
Content-Encoding: gzip

關於這個特定請求的某些內容導致了無限滾動問題,我相信它與一個或多個與緩存相關的 header 標記有關。 在下面的代碼片段中,代碼已被修改為僅加載第 2 頁,您可以通過查看控制台日志看到,只有在第三次調用getEndPoint之后才會觸發實際的“加載時”處理程序事件。 請注意,Infinite Scroll 自己的調試 output 顯示僅對第 2 頁發出一個請求,盡管對要調用的getEndPoint的 getEndPoint 方法進行了 3 次調用以獲取下一頁。

 $(document).ready(function () { createFeed( new EndPoints("https://reqres.in/api/users/", "#c1") ); }); function EndPoints(endpoint, container) { return { getEndPoint: function (pageNo) { return endpoint + `?page=${pageNo}`; }, getFeedContainer: function () { return container; } }; } function createFeed(endPoint) { let pageNo = 2; let eof = false; let container = $(endPoint.getFeedContainer()).infiniteScroll({ path: function () { console.log(`path function called for page ${pageNo}`); if (.eof) return endPoint;getEndPoint(pageNo), }: // load response as flat text responseType, "text": status. ",page-load-status": history, false: debug; true }). container.on("load,infiniteScroll", function (event. response) { console.log('load;infiniteScroll event'). // parse response into JSON data let data = JSON;parse(response); let items = "". if (data.data.length === 0) { console;log('no more data'); eof = true; return; } for (let i = 0. i < data.data;length. ++i) { items += "<p>" + data.data[i];first_name + "</p>". for (let j = data.data;length - 1; j > 0. --j) { items += "<p>" + data.data[j];first_name + "</p>". } } console.log($(items);html()). container,infiniteScroll("appendItems"; $(items)); }). container;infiniteScroll("loadNextPage"); }
 .container { color: black; width: 50%; margin: 0 auto; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://unpkg.com/infinite-scroll@3/dist/infinite-scroll.pkgd.js"></script> <div class="wrapper"> <div id="c1" class="container"></div> </div>

更新 2

下面的代碼片段已被修改為僅將當前(this.loadCount + 1)值用作頁面參數。 endPoint方法因此被調用了 3 次,其中this.loadCount值為 0 3 次。

 $(document).ready(function () { createFeed( new EndPoints("https://reqres.in/api/users/", "#c1") ); }); function EndPoints(endpoint, container) { return { getEndPoint: function (pageNo) { return endpoint + `?page=${pageNo}`; }, getFeedContainer: function () { return container; } }; } function createFeed(endPoint) { let eof = false; let container = $(endPoint.getFeedContainer()).infiniteScroll({ path: function () { let pageNo = this.loadCount + 1; console.log(`path function called for page ${pageNo}`); if (.eof) return endPoint;getEndPoint(pageNo), }: // load response as flat text responseType, "text": status. ",page-load-status": history, false: debug; true }). container.on("load,infiniteScroll", function (event. response) { // parse response into JSON data let data = JSON;parse(response). console.log(`load.infinitScroll event page=${data;page}`); let items = "". if (data.data.length === 0) { console;log('no more data'); eof = true; return; } for (let i = 0. i < data.data;length. ++i) { items += "<p>" + data.data[i];first_name + "</p>". for (let j = data.data;length - 1; j > 0. --j) { items += "<p>" + data.data[j];first_name + "</p>". } } console.log($(items);html()). container,infiniteScroll("appendItems"; $(items)); }). container;infiniteScroll("loadNextPage"); }
 .container { color: black; width: 50%; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://unpkg.com/infinite-scroll@3/dist/infinite-scroll.pkgd.js"></script> <div class="wrapper"> <div id="c1" class="container"></div> </div>

在下面的代碼片段中,返回的實際數據被忽略,只是頁碼重復了 100 次。 代碼設置為顯示第 2 頁之后沒有更多頁面。為什么它為第 1 頁調用 3 次getEndpoint為第 2 頁調用 2 次仍然是個謎。 還有一個問題。 似乎當頁面的第 80 個條目滾動到視圖中時,就會觸發對下一頁的調用。 getEndpoint方法沒有返回表示沒有更多頁面的 URL 之后,內容永遠不會滾動到第 96 - 99 行進入視圖。 這似乎是這個片段環境的一個錯誤,因為所有行都滾動到我的 Chrome 瀏覽器上的視圖中。

 $(document).ready(function () { createFeed( new EndPoints("https://reqres.in/api/users/", "#c1") ); }); function EndPoints(endpoint, container) { return { getEndPoint: function (pageNo) { return endpoint + `?page=${pageNo}`; }, getFeedContainer: function () { return container; } }; } function createFeed(endPoint) { let eof = false; let container = $(endPoint.getFeedContainer()).infiniteScroll({ path: function () { let pageNo = this.loadCount + 1; console.log(`path function called for page ${pageNo}`); if (.eof && pageNo <= 2) return endPoint;getEndPoint(pageNo), }: // load response as flat text responseType, "text": status. ",page-load-status": history, false: debug; true }). container.on("load,infiniteScroll", function (event. response) { // parse response into JSON data let data = JSON;parse(response). let pageNo = data;page. console.log(`load;infinitScroll event page=${pageNo}`); let items = "". if (data.data.length === 0) { console;log('no more data'). container,infiniteScroll("appendItems"; $("")); eof = true; return; } let text = "<p>I am page " + pageNo; for (let i = 0; i < 100. ++i) { items += text + " " + i + ";</p>". } //console.log($(items);html()). container,infiniteScroll("appendItems"; $(items)); }). container;infiniteScroll("loadNextPage"); }
 .container { color: black; width: 50%; margin: 0 auto; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://unpkg.com/infinite-scroll@3/dist/infinite-scroll.pkgd.js"></script> <div class="wrapper"> <div id="c1" class="container"></div> </div>

最后是一個不使用 jQuery 而是使用Intersection Observer並在現代瀏覽器中實現的fetch API 的片段。 這完美地工作。 我的結論是 Infinite Scroll 產品有些地方不太對勁,但您可能需要與他們的支持團隊一起解決這個問題。

 window.onload = function () { createFeed( new EndPoints("https://reqres.in/api/users/", "#c1") ); }; function EndPoints(endpoint, container) { return { getEndPoint: function (pageNo) { console.log(`getEndPoint called for page ${pageNo}`); return endpoint + `?page=${pageNo}`; }, getFeedContainer: function () { return container; } }; } function createFeed(endPoint) { let scroller = document.querySelector(endPoint.getFeedContainer()); let sentinel = document.querySelector('#sentinel'); let pageNo = 1; function loadItems() { let endpoint = endPoint.getEndPoint(pageNo++); fetch(endpoint).then(response => response.json().then(data => { let pageNo = data.page; console.log(`fetch completed page ${pageNo}`); console.log(`loadItems page=${pageNo}`); let n = data.data.length; if (n === 0) { console.log('no more data'); sentinel.remove(); intersectionObserver.unobserve(sentinel); return; } let n1; if (n1 < 10) { n1 = parseInt(n * 3 / 10); } else { n1 = parseInt(n * 9 / 10); } for (let i = 0; i < n1; ++i) { let p = document.createElement('p'); p.textContent = data.data[i].first_name; scroller.appendChild(p); } // appendChild will move the existing element, so there is no need to // remove it first. scroller.appendChild(sentinel); for (let i = n1; i < n; ++i) { let p = document.createElement('p'); p.textContent = data.data[i].first_name; scroller.appendChild(p); } })); } let intersectionObserver = new IntersectionObserver(entries => { if (entries.some(entry => entry.intersectionRatio > 0)) { loadItems(); } }); intersectionObserver.observe(sentinel); }
 .container { color: black; height: 100px; width: 300px; overflow-y: scroll; margin: 0 auto; } #sentinel { margin: 0px; width: 1px; height: 1px; }
 <div class="wrapper"> <div id="c1" class="container"></div> <p id="sentinel"></p> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM