交互流程
- 列表渲染留言,每條留言帶「回復」鏈接/按鈕。
- 點擊「回復」→ 動態在該留言下插入回復輸入框(textarea + 提交按鈕)。
- 用戶輸入內容點擊提交 → AJAX 發送至後端 → 成功後刷新該留言的回復列表或追加新回復節點。
- 再次點擊「回復」或點擊空白處 → 移除輸入框。
關鍵技術點
// 1. 事件委託(列表動態增減)
$('#messageList').on('click', '.reply-btn', function(e) {
e.preventDefault();
const $msg = $(this).closest('.message');
if ($msg.find('.reply-form').length) return; // 防重複
// 2. 動態構建表單
const formHtml = `
<div class="reply-form">
<textarea placeholder="寫回復..."></textarea>
<button class="submit-reply" data-msg-id="${$msg.data('id')}">提交</button>
<button class="cancel-reply">取消</button>
</div>`;
$msg.append(formHtml);
});
// 3. 提交處理
$('#messageList').on('click', '.submit-reply', function() {
const msgId = $(this).data('msg-id');
const content = $(this).siblings('textarea').val().trim();
if (!content) return;
$.post('/api/reply', { msgId, content }, res => {
if (res.success) {
// 追加回復節點或局部刷新
$(this).closest('.reply-form').remove();
$msg.find('.replies').append(renderReply(res.data));
}
});
});
// 4. 取消/點擊外部關閉
$(document).on('click', (e) => {
if (!$(e.target).closest('.reply-form, .reply-btn').length)
$('.reply-form').remove();
});
後端接口建議
POST /api/reply:{ msgId, content, parentReplyId? } → 返回新回復對象(含 id、用戶、時間、內容)。
- 分頁加載回復:
GET /api/replies?msgId=xxx&page=1&size=10。
無障礙與體驗細節
- 輸入框自動聚焦:
$('textarea').focus()。
- 提交中禁用按鈕防重複提交。
- 長文本自動增高:
textarea { resize: vertical; } 或 JS 監聽 input 調整高度。