質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1705閲覧

無限スクロールで稀に2回データが取得されてしまう

maskmelon

総合スコア63

スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2020/09/11 07:24

編集2020/09/11 07:27

コメント欄に無限スクロール機能を実装しています。YouTubeのコメント欄のような感じで、スクロールバーが最下部に達すると、新しくコメントを取得して描画するような処理を行なっています。

JavaScript

1 let scrollLock = false; 2  3 // 取得したコメントを描画する関数 4 const loadCommentsIntoSection = (postedComments) => { 5 let html = ''; 6 postedComments.forEach((comment) => { 7 const { time, content, createdBy } = comment; 8 const displayTime = calculateTimeDiffer(time); 9 html += '<div class="comment-box">' 10 html += `<div id="picture-parent"><img src="${createdBy.picture}" id="user-picture"></div>`; 11 html += `<div id="comment-body"><p>${createdBy.displayName} ${displayTime}</p><p>${content}</p></div>`; 12 html += '</div><hr>'; 13 }); 14 createLoadingElm(); 15 setTimeout(() => { 16 commentContainer.insertAdjacentHTML('beforeend', html); 17 destroyLoadingElm(); 18 scrollLock = false; // コメントを取得して描画した後にスクロールロックを解除する 19 }, 2000); 20 }; 21  22 // コメントを取得して描画する関数(offset=0で最初の10件, offset=10で次の10件...) 23 const getComments = (offset) => { 24 if (!offset) offset = 0; 25 26 fetch(`/questions/${questionId}/comments.json?limit=10&offset=${offset}`).then((response) => { 27 response.json().then((result) => { 28 const { Comments } = result; 29 console.log(Comments); 30 loadCommentsIntoSection(Comments); 31 }); 32 }); 33 }; 34 35 window.onscroll = () => { 36 console.log(scrollLock); 37  // スクロールがロックされているときはデータの取得を中断する 38 if (scrollLock) return; 39  // スクロールバーが画面最下部に移動した時 40 if (this.innerHeight + this.pageYOffset >= document.body.scrollHeight) { 41 fetch(`/questions/${questionId}/comments.json`).then((response) => response.json().then((result) => { 42 const { Comments } = result; 43 const numOfComments = Comments.length; //すべてのコメントの数 44 const commentsLength = document.querySelectorAll('.comment-box').length; // 取得したコメントの数 45 if (numOfComments === commentsLength) return; // 取得したコメント数がすべてのコメント数に達したらデータの取得を中断する 46 scrollLock = true; //コメントを取得している最中はスクロールをロックする 47 getComments(commentsLength); 48 })); 49 } 50 };

基本的にはうまく動作するのですが、たまに同じ範囲のコメントが重複して取得されてしまうので、その原因を特定したいと思っています。

スクロール時にスクロールロックを、コメント取得時に取得したコメントを出力したところ、下画像のように本来falseとtrueの間に10件読み込まれるべきコメントが20件読み込まれています。

怪しいとすればスクロール位置の指定かと思うのですが、自力で原因を把握できなかったため質問させていただきました。

分かる方いらっしゃいましたらご教授いただけると幸いです。
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

scrollLock = true をリクエスト(一定時間かかる)の後に行っているため、リクエストの最中はロックされていないかと思いました。

window.onscroll = () => { console.log(scrollLock); if (scrollLock) return; if (this.innerHeight + this.pageYOffset >= document.body.scrollHeight) { // リクエストする前にロック scrollLock = true; fetch(`/questions/${questionId}/comments.json`).then((response) => response.json().then((result) => { // このブロックはリクエスト ( 100ms なり 1000ms なり HTTPにかかった時間)後に実行される const { Comments } = result; const numOfComments = Comments.length; const commentsLength = document.querySelectorAll('.comment-box').length; if (numOfComments === commentsLength) return; // scrollLock = true; getComments(commentsLength); }));

投稿2020/09/12 02:38

編集2020/09/12 02:39
unhappychoice

総合スコア1531

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maskmelon

2020/09/12 06:32

ご指摘の通り、リクエスト前にスクロールをロックすると正しく動作するようになりました。 的確な回答をくださりありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問