前提・実現したいこと
Railsでインスタグラム風のアプリを作っています。
無限スクロール(InfiniteScroll)を使って
記事が10記事ずつ読み込まれるようにしています。
その時に、新しい記事が読み込まれるたびに
記事(article)についているハートの表示を
切り替える処理をjavascriptで行いたいのですが、
現在のコードだと下記の処理が数1000回実行されてしまって
エラーが発生したり処理が重くなってしまいます。
これを解決するためには
article.jsにどのようなコードを書けばいいでしょうか?
(ちなみに document.addEventListener('DOMContentLoaded', () => {})
で囲まれた処理は最初に読み込まれる10記事にしか実行されません。)
javascript
1$(function(){ 2 $(window).on('scroll', function (){ 3 var scroll = $(window).scrollTop(); 4 if (scroll % 30 < 1){ 5 6 // ロード時にいいねされていないハートを配列で取得 7 $('.inactive-heart').each(function (index, element) { 8 const likeData = $(element).data() 9 const articleId = likeData.articleId 10 axios.get(`/articles/${articleId}/like`) 11 .then((response) => { 12 const inActiveStatus = response.data.hasLiked 13 if ( inActiveStatus === false ) { 14 $(element).removeClass('hidden') 15 } 16 }) 17 }) 18 19 // ロード時にいいねされているハートを配列で取得 20 $('.active-heart').each(function (index, element) { 21 const likeData = $(element).data() 22 const articleId = likeData.articleId 23 axios.get(`/articles/${articleId}/like`) 24 .then((response) => { 25 const activeStatus = response.data.hasLiked 26 if ( activeStatus === true) { 27 $(element).removeClass('hidden') 28 } 29 }) 30 }) 31 } 32 }); 33});
発生している問題・エラーメッセージ
Failed to load resource: net::ERR_INSUFFICIENT_RESOURCES
該当のソースコード
articles/index.html.haml
haml
1.new-post-btn 2 = link_to new_article_path do 3 = icon("fas", "camera") 4.infinite-container 5 - @articles.each do |article| 6 .article.infinite-post 7 .article-poster-info 8 = link_to account_path(id: article.user_id) do 9 .avatar-style 10 - if article.user.profile&.avatar&.attached? 11 = image_tag article.user&.profile&.avatar 12 - else 13 = image_tag 'avatar1.png' 14 .article-poster-info-text 15 .article-username 16 = article.user.username 17 .article-post-date 18 = I18n.l(article.created_at, format: :long) 19 .slider 20 - if article.images.attached? 21 - article.images.each do |image| 22 .article-image 23 = link_to article_path(article) do 24 = image_tag image 25 .article-nav-icon 26 .article_heart.hidden.active-heart{id: "active-heart#{article.id}", data: {article_id: article.id}} 27 = icon("fas", "heart") 28 .article_heart.hidden.inactive-heart{id: "inactive-heart#{article.id}", data: {article_id: article.id}} 29 = icon("far", "heart") 30 = link_to article_path(article) do 31 .article-comment-icon 32 = icon("far", "comment-dots") 33 =link_to "http://twitter.com/share?url=#{ url_for(action: :show,id: article.id,only_path: false) } &text=さらに向こうへPLUS ULTRA!! &hashtags=もうすぐ春ですね",{class:"logo-profile"},target: "_blank" do 34 .article-share-icon 35 = icon("fas", "share-alt") 36 .article-content 37 .article-username 38 = article.user.username 39 .article-content-text 40 = article.content 41 = javascript_pack_tag 'article' 42 43 = paginate @articles 44.page-load-status.has-text-centered 45 %p.infinite-scroll-request Loading... 46 47= javascript_pack_tag 'scroll' 48 49.bottom-image 50 = image_tag 'logo.jpg'
article.js
javascript
1import $ from 'jquery' 2import axios from 'modules/axios' 3 4 5 6document.addEventListener('DOMContentLoaded', () => { 7 8// ロード時にいいねされていないハートを配列で取得 9 $('.inactive-heart').each(function (index, element) { 10 const likeData = $(element).data() 11 const articleId = likeData.articleId 12 axios.get(`/articles/${articleId}/like`) 13 .then((response) => { 14 const inActiveStatus = response.data.hasLiked 15 if ( inActiveStatus === false ) { 16 $(element).removeClass('hidden') 17 } 18 }) 19 }) 20 21 // ロード時にいいねされているハートを配列で取得 22 $('.active-heart').each(function (index, element) { 23 const likeData = $(element).data() 24 const articleId = likeData.articleId 25 axios.get(`/articles/${articleId}/like`) 26 .then((response) => { 27 const activeStatus = response.data.hasLiked 28 if ( activeStatus === true) { 29 $(element).removeClass('hidden') 30 } 31 }) 32 }) 33 34 // #create いいねをつけたいときの処理 35 $('.inactive-heart').on('click', (e) => { 36 e.preventDefault(); 37 const dataset = $(e.currentTarget).data() 38 const articleId = dataset.articleId 39 axios.post(`/articles/${articleId}/like`) 40 .then((response) => { 41 if (response.data.status === 'ok') { 42 $(`#inactive-heart${articleId}`).addClass('hidden'); 43 $(`#active-heart${articleId}`).removeClass('hidden'); 44 } 45 }) 46 .catch((e) => { 47 window.alert('Error') 48 console.log(e) 49 }) 50 51 }) 52 53 // #destroy いいねを外したいときの処理 54 $('.active-heart').on('click', (e) => { 55 e.preventDefault(); 56 const dataset = $(e.currentTarget).data() 57 const articleId = dataset.articleId 58 axios.delete(`/articles/${articleId}/like`) 59 .then((response) => { 60 if (response.data.status === 'ok') { 61 $(`#active-heart${articleId}`).addClass('hidden'); 62 $(`#inactive-heart${articleId}`).removeClass('hidden'); 63 } 64 }) 65 .catch((e) => { 66 window.alert('Error') 67 console.log(e) 68 }) 69 }) 70}) 71 72 73$(function(){ 74 $(window).on('scroll', function (){ 75 var scroll = $(window).scrollTop(); 76 if (scroll % 30 < 1){ 77 78 $('.inactive-heart').each(function (index, element) { 79 const likeData = $(element).data() 80 const articleId = likeData.articleId 81 axios.get(`/articles/${articleId}/like`) 82 .then((response) => { 83 const inActiveStatus = response.data.hasLiked 84 if ( inActiveStatus === false ) { 85 $(element).removeClass('hidden') 86 } 87 }) 88 }) 89 90 // ロード時にいいねされているハートを配列で取得 91 $('.active-heart').each(function (index, element) { 92 const likeData = $(element).data() 93 const articleId = likeData.articleId 94 axios.get(`/articles/${articleId}/like`) 95 .then((response) => { 96 const activeStatus = response.data.hasLiked 97 if ( activeStatus === true) { 98 $(element).removeClass('hidden') 99 } 100 }) 101 }) 102 } 103 }); 104});
articles_controller.rb
ruby
1class ArticlesController < ApplicationController 2 before_action :authenticate_user!, only: [:show, :new, :create, :destroy] 3 4 5 6 def index 7 @articles = Article.all.order(created_at: :desc).page(params[:page]).per(10) 8 end 9 10 def show 11 @article = Article.find(params[:id]) 12 end 13 14 def new 15 @article = current_user.articles.build 16 end 17 18 def create 19 @article = current_user.articles.build(article_params) 20 if @article.save 21 redirect_to root_path, notice: '投稿しました' 22 else 23 flash.now[:error] = '投稿できませんでした' 24 render :new 25 end 26 end 27 28 def destroy 29 article = Article.find(params[:id]) 30 article.destroy! 31 redirect_to root_path, notice: '削除に成功しました' 32 end 33 34 private 35 36 def article_params 37 params.require(:article).permit(:content, images: []) 38 end 39 40end
試したこと
setIntervalで一定時間置きに処理するようにしてみましたが
同じように「Failed to load resource: net::ERR_INSUFFICIENT_RESOURCES」
が出てしまいました。
また、ハートが両方ともhiddenだったら処理が行われるように
以下のようにコードを書きましたが
新しく記事が読み込まれても反応せず。
$(function(){ $(window).on('scroll', function (){ $(".article").each(function () { if ($('.article').find('.active-heart').css('display') == 'none' && $('.article').find('.inactive-heart').css('display') == 'none') {
途方にくれております。
回答1件
あなたの回答
tips
プレビュー