私は無限スクロールを使用しています。問題のCodePenの例を作成しました。私はフィードを始めました...それ自体で、それは完璧に機能します。ただし、2つのボタンがあり、1つはフィード1を要求し、もう1つはフィード2を要求します。
ページを読み込んでまったくスクロールせずにフィード2をリクエストして(フィード2もスクロールしないでください)、フィード1に戻ってスクロールすると、一部のページをスクロールできる場合がありますが、やめます。2ページで停止する場合もあれば、4ページで停止する場合もあります。次のページに移動する場合(一番下にいる場合)、上にスクロールして次のページに移動する必要があります。ボタンは一方のフィードを非表示にし、もう一方を表示します。
この動作が発生するのはなぜですか?どうすれば修正できますか?
$(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>
コメントで述べたように、要素が表示/非表示(要素はまだレイアウトされており、表示されなくてもスペースを占有します)とブロック/なしの表示には違いがあります。可視性に基づいてセレクターを使用することが基本的な問題であることを示唆しているわけではありませんが、2つのコンテナーに一意のIDを指定し、どちらか一方を常に非表示にする方がクリーンです。だから、私がやったことである修正されたコードで。
私が信じているのは、コードに関する2つの問題であることがわかりました。ただし、中心的ではない最初のものは、注意する必要があるものです。InfiniteScrollはgetEndpoint
、"load.infiniteScroll"
イベントをまだ生成していなくても、エンドポイントのメソッドを連続して呼び出す可能性があり、実際にはそうします。"load.infiniteScroll"
次のページ取得のためにページ番号をインクリメントするコードが存続するのはイベントハンドラーであるため、誤って同じページを複数回取得することになります。このページ番号は、ページが要求されたらすぐにインクリメントする必要があります。1つの解決策は、Endpoint
クラス自体に現在のページ番号を維持させるgetEndpoint
ことです。これは、メソッドによって実装されます。したがって、次のコードでは、ページ1が何度も何度も読み込まれます。ある時点で、2ページを何度もロードしていたと思います。
もう1つの問題は、"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/[email protected]/dist/infinite-scroll.pkgd.js"></script>
<div class="wrapper">
<div id="c1" class="container"></div>
</div>
更新
私は上記のコメントを対処する必要のある問題として支持していますが、この問題は現在、複数の無限スクロールを使用することとは何の関係もないと思います。上記のスニペットを1つの無限スクロールを使用するように更新し、ページ数をインクリメントするコードを復元しました。デバッガーを使用してコードをステップ実行しました。コードは明らかEndpoints.getEndPoint
にpage = 1、page = 2、page = 3(長さゼロのデータ配列を持つ)のメソッドを呼び出していますが、実際のページフェッチは3番目の空のページ用に作成されているため、データは表示されません。これは、デバッガーを使用しなくても、コンソールログに表示できます。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
この特定のリクエストには、無限スクロールの問題を引き起こしている何かがあり、キャッシュに関連する1つ以上のヘッダータグに関連していると思います。次のスニペットでは、ページ番号2のみをロードするようにコードが変更されており、コンソールログを見るgetEndPoint
と、実際の「ロード時」ハンドラーイベントがトリガーされるのは3回目の呼び出しの後であることがわかります。Infinite Scrollの独自のデバッグ出力ではgetEndPoint
、次のページをフェッチするために呼び出されるURLのメソッドに対して3回の呼び出しが行われているにもかかわらず、ページ2に対して行われている要求は1つだけであることに注意してください。
$(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/[email protected]/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です。
$(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/[email protected]/dist/infinite-scroll.pkgd.js"></script>
<div class="wrapper">
<div id="c1" class="container"></div>
</div>
次のスニペットでは、返される実際のデータは無視され、ページ番号だけが100回繰り返されます。コードは、2ページ以降にページがないことを示すように設定されています。なぜgetEndpoint
1ページで3回、2ページで2回呼び出されるのかは、まだ謎です。もう1つ問題があります。ページの80番目のエントリがスクロールされて表示されるのは、次のページの呼び出しがトリガーされたときのようです。後getEndpoint
のビューに99 -メソッドは複数のページが存在しない意味なしURLを返さない、コンテンツがライン96をスクロールすることはありません。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/[email protected]/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>
Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。
メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.
ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。
ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.
Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?
The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!
トム・ペニントン/ゲッティイメージズ新しい関係で起こることの1つは、誰が何のクレジットを取得するかについて混乱し始めることです。私は私の元と一緒にこの良いサルサダンサーでしたか?私はいつもエビとグリッツが好きでしたか、それとも新しいペはおばあちゃんよりも上手に調理しましたか?現実の世界では、あなたを知っている友達は記録を更新します:あなたは決して良いサルサダンサーではありませんでしたまだそうではありません。
長い間、世界は、死のゆっくりとした避けられない進行についてのビデオゲームであるDestinyで演じるピーターディンクレイジの声を笑っていました。まもなく、その声の演技は変わるでしょう。
ロシアのフィギュアスケーター、カミラ・バリエバが関与したドーピング事件が整理されているため、チームは2022年北京冬季オリンピックで獲得したメダルを待っています。
何千人ものAmazonの買い物客がMulberry Silk Pillowcaseを推奨しており、現在販売中. シルクの枕カバーにはいくつかの色があり、髪を柔らかく肌を透明に保ちます。Amazonで最大46%オフになっている間にシルクの枕カバーを購入してください
ラファイエット警察署は、「不審な男性が女性に近づいた」という複数の苦情を受けて、12 月にパデュー大学の教授の捜査を開始しました。
私たちの周りの世界と同じように、言語は常に変化しています。以前の時代では、言語の変化は数年または数十年にわたって発生していましたが、現在では数日または数時間で変化する可能性があります。
認知症を患っている 91 歳のアジア人女性が最近、47 番街のアウター サンセット地区でロメオ ロレンゾ パーハムに襲われました。伝えられるところによると、被害者はサンフランシスコの通りを歩いていたところ、容疑者に近づき、攻撃を受け、暴行を受けました。
“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.
人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。