惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
J
Java Code Geeks
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
腾讯CDC
博客园 - 司徒正美
B
Blog RSS Feed
博客园 - 三生石上(FineUI控件)
I
InfoQ
N
Netflix TechBlog - Medium
L
LangChain Blog
博客园_首页
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Tailwind CSS Blog
MyScale Blog
MyScale Blog
美团技术团队
The Cloudflare Blog
爱范儿
爱范儿
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
H
Help Net Security
Martin Fowler
Martin Fowler
V
Visual Studio Blog

Nic Lin's Blog

謝明真 - 高效領導力的課後筆記 NFT 開發實戰!基礎智能合約入門 (3) NFT 開發實戰!基礎智能合約入門 (2) NFT 開發實戰!基礎智能合約入門 (1) 如何自我檢測 log4j CVE 漏洞 Rails 如何在資料寫入時記錄來源 IP 位置 如何經營工程師 Youtube 頻道 - Part 8 營收篇 如何經營工程師 Youtube 頻道 - Part 7 酸民文化篇 如何經營工程師 Youtube 頻道 - Part 5 設備器材篇 如何經營工程師 Youtube 頻道 - Part 4 後製剪輯篇 如何經營工程師 Youtube 頻道 - Part 3 文案企劃篇 如何經營工程師 Youtube 頻道 - Part 2 設備器材篇 如何經營工程師 Youtube 頻道 - Part 1 制訂頻道方向篇 如何經營工程師 Youtube 頻道 - Part 0 Rails 中避免 race condition 的最佳實踐(二) Rails 中避免 race condition 的最佳實踐(一) 10 分鐘整合 google sheet 做自動化開發功能週報 經營 Side Project 300 天所帶來的收穫及挑戰 我的 Youtube 影片製作流程 API 設計時必須注意的 HTTP header 底線問題 如何提升你的程式可讀性之實務技巧(三) 如何提升你的程式可讀性之實務技巧(二) 如何提升你的程式可讀性之實務技巧(一) Ruby 中使用 freeze 優化效能的時機 避免 React 中的 useEffect 無限 render 在 Rails 內輕量使用 Vue Component 的最佳實踐 如何在區域網路用 Docker 架設有 SSL 的 Gitlab 從被問到問人,那些我常問的面試問題 [Rails] 如何漂亮寫出可維護的 query (Maintainable Rails Query) 在已知長度情況下優化 slice 的性能
用 ajax + paginate 讓留言功能更出色
Nic Lin · 2017-08-24 · via Nic Lin's Blog

Implement background animation colors for comments(like stack over flow share answer link)

Rails version 5.1.3 Ruby version 2.3.2

原本如果實作一個 Post has_many Comments 的 CRUD

最陽春的版本就是在留言之後,跳出一個 flash 顯示

「你已留言成功」

不過因為是用 http post,所以在 controller action 就會 redirect_to 一個 path 回來,

在這裡我們可以用

  • Rails 4 redirect_to :back
  • Rails 5 redirect_back(fallback_location: root_path)

來做到留言後返回同一頁。

不過看似沒有導去任何的頁面,但是頁面卻彈到最頂部了。

因為這其實是在重新 load 當前頁面。

所以當留言越來越長,我們每次留言完就會又彈回頂部。這樣實在太糟糕了

秉持著現代流行的 SPA 精神,我們用 ajax 來完成吧

目標讓留言系統有

  • Load more 按鈕載入更多留言
  • ajax 留言
  • 留言後下拉至留言處,並對留言區塊產生顏色漸層

對於漸層從亮色到底色這種標記區塊的方法,是從 StackOverFlow 分享 answer 裡面看到的,所以就思考了一下並實作,你可以點看看這個在 stackoverflow 經典的答案分享體驗一下。

Gem install

gem 'jquery-rails'
gem 'will_paginate', '~> 3.1'
//= require rails-ujs
//= require jquery

Load more 按鈕載入更多留言

CRUD 這邊就略過不贅述了 XD

在 post#show 顯示留言,直接先分頁


def show
    @comments = @post.comments.paginate(page: params[:page], per_page: 5).order('created_at DESC')

    respond_to do |format|
      format.html
      format.js
    end
end

先寫 helper

  def render_ajax_more_comments_link(post, comments)
    link_to("SHOW MORE", post_path(post, page: comments.next_page), remote: true, class: 'btn coin-comment__load-more-btn', id: "js-load-more-comments" )
  end

再 show 頁面使用這個 load more 按鈕,並且在 form 的地方補上 remote: true

// 留言表單獨立出來做 partial
<%= render "comment_form"%>

// Load more 按鈕
<% if @comments.next_page %>
  <div class="coin-comment__load-more">
     <%= render_ajax_more_comments_link(@post, @comments) %>
  </div>
<% end %>

comment form 的 partial

<%= simple_form_for [@post, Comment.new], remote: true, html: { id: 'js-comment-form' } do |f| %>

    <%= f.input :message %>

    <%= f.submit "COMMENT", class: "btn btn-sm", data: { disable_with: "COMMENT..." } %>
<% end %>

設定 js.erb

$('#js-comments-list').append("<%= j render @comments %>");

<% if @comments.next_page %>
  $('#js-load-more-comments').replaceWith('<%= j render_ajax_more_comments_link(@post, @comments) %>');
<% else %>
  $(window).off('scroll');
  $('#js-load-more-comments').remove();
<% end %>

Load more button 示範

ajax 留言

controller 在 create 留言時會紀錄哪位使用者留言的

  def create
    @post = Post.friendly.find(params[:post_id])
    @comment = @post.comments.build(comment_params)
    @comment.user = current_user

    respond_to do |format|
      if @comment.save
        format.html { redirect_to(post_path(@post)) }
        format.js
      else
        format.html { redirect_back(fallback_location: root_path) }
        format.js
      end
    end
  end

因為 create 行為沒有 html.erb ,不過要有 js 行為,所以

$('#js-comments-list').append("<%= j render @comment %>");

// clear form input 留言後能夠把 form 上面的 input 欄位清掉
$('#js-comment-form')[0].reset();

// scroll to bottom 依照當前網頁高度,去計算拉到底部的高度,這邊採用 jquery 裡面的 animate 實作
height = $('#js-comments-list').offset().top;
$('html, body').animate({scrollTop : height+ $('#js-comments-list').height()},500);

// comment moment height light 先給予顏色,之後再用 animate 將顏色動畫漸變回底色
$('#js-comments-<%= @comment.id %>').css("backgroundColor", "rgba(255, 210, 46, 0.39)");
$('#js-comments-<%= @comment.id %>').animate({backgroundColor: "#fff"}, 800);

由於原本的 jquery 是沒有加入 backgroundColor 的功能,這是額外的擴充,所以請在 layout 裡面加入

一定要在 javascript 載入之後再載入 jquery.color-animation ,因為他是依賴在 jquery 之下

    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    <script src="//cdn.jsdelivr.net/jquery.color-animation/1/mainfile"></script>

記得做一塊 partial ,裡面是每一個 comment

<div id="js-comments-<%= comment.id %>">
  <%= comment.user.name %>
  <%= comment.message %>
</div>

這邊的 js-comments-<%= comment.id %> 用意是為了能夠辨別每一個唯一的 comment 加上的標籤,這樣一來,我們就可以做到留言後自動標記了

到這邊,應該可以實現如下圖的功能了