iT邦幫忙

2025 iThome 鐵人賽

0
自我挑戰組

給愛追劇的你:30天互動網站挑戰系列 第 13

Day 13:心得牆美化 +「載入更多」

  • 分享至 

  • xImage
  •  

目標
review.html 的心得列表做成對話框風格、加陰影與分隔;長列表用「載入更多」。

改哪裡style.cssjs/reviews.js

1. CSS(貼到 style.css 末尾)

/* Day 13:心得對話框風格 + 分隔 */
.review-item{
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 14px 16px;
  box-shadow: var(--shadow-sm);
}
.review-item::before{
  content: "";
  position: absolute;
  left: 20px; top: -8px;
  border: 8px solid transparent;
  border-bottom-color: var(--border);
}
.review-item::after{
  content: "";
  position: absolute;
  left: 20px; top: -7px;
  border: 7px solid transparent;
  border-bottom-color: var(--surface);
}
.reviews.separated > .review-item + .review-item{ margin-top: 10px; }
.loadmore-wrap{ display:flex; justify-content:center; margin-top: 10px; }
#btnLoadMore{ padding:10px 14px; border-radius:10px; border:1px solid var(--border); background:var(--surface); cursor:pointer; }
#btnLoadMore:hover{ border-color: var(--text); }

2. JS(覆蓋 js/reviews.js 的 render 相關部分即可)

在 Day12 版中,加入「分頁顯示」,保留 LocalStorage:

// 只貼需新增/替換的片段 —— 放在 Day12 版 reviews.js 內

// 額外狀態:每次顯示幾筆
let PAGE_SIZE = 5;
let visibleCount = PAGE_SIZE;

function mountLoadMore(){
  const total = REVIEWS.length;
  const $wrap = $('.loadmore-wrap');
  if ($wrap.length === 0){
    $('#reviewList').after('<div class="loadmore-wrap"><button id="btnLoadMore" type="button">載入更多</button></div>');
  }
  if (visibleCount >= total) {
    $('#btnLoadMore').prop('disabled', true).text('沒有更多了');
  } else {
    $('#btnLoadMore').prop('disabled', false).text('載入更多');
  }
}

function render(){
  if (!REVIEWS.length){
    $('#reviewList').html(`<div class="empty">目前還沒有心得,快成為第一個分享的人吧!</div>`);
    $('.loadmore-wrap').remove();
    return;
  }
  const sorted = REVIEWS.slice().sort((a,b) => (b.createdAt || '').localeCompare(a.createdAt || ''));
  const cut = sorted.slice(0, visibleCount);
  const html = cut.map(item => {
    const tags = (item.genres || []).map(g => LABELS[g] || g).join(' / ');
    const dateStr = (item.createdAt || '').slice(0,10);
    return `
      <article class="review-item" data-id="${item.id}">
        <div class="review-head">
          <h3 class="review-title">${esc(item.title)}</h3>
          <span class="review-meta">⭐ ${item.rating} · ${esc(item.name || '匿名')}${tags?` · ${tags}`:''}${dateStr?` · ${dateStr}`:''}</span>
        </div>
        <p class="review-content">${esc(item.content)}</p>
        <div class="review-actions">
          <button class="btn-del" type="button">刪除</button>
        </div>
      </article>
    `;
  }).join('');
  $('#reviewList').toggleClass('separated', true).html(html);
  mountLoadMore();
}

$(document).on('click', '#btnLoadMore', function(){
  visibleCount += PAGE_SIZE;
  render();
});

// 初始化時確保第一頁
$(function(){
  visibleCount = PAGE_SIZE;
  render();
});

驗收

  • 頁面每次顯示 5 筆,按「載入更多」再顯示 5 筆。
  • 卡片有對話框三角形、陰影與圓角。

上一篇
Day 12:心得牆永久保存
下一篇
Day 14:第二週小結(文件化 + README)
系列文
給愛追劇的你:30天互動網站挑戰30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言