使用JavaScript实现HTML页面评论回复功能,点击按钮动态添加元素
修正后完整可运行代码
HTML部分
<section><button onclick="comment()">发表评论</button></section> <div id="comments"></div> <div id="comments_and_replies"></div>
JS部分
// 渲染评论输入框 function comment() { const commentContainer = document.getElementById('comments'); // 避免重复生成输入框 if (commentContainer.querySelector('#user_comment')) return; commentContainer.innerHTML = `<textarea id='user_comment'></textarea> <button onclick='addNewItem()'>发布评论</button>`; } // 提交新的主评论 function addNewItem() { const commentsWrap = document.getElementById("comments_and_replies"); const userCommentInput = document.getElementById('user_comment'); const commentContent = userCommentInput.value.trim(); // 空内容不提交 if (!commentContent) return; // 单条主评论节点 const commentItem = document.createElement("li"); commentItem.className = "comment-item"; // 主评论内容 const commentSpan = document.createElement("span"); commentSpan.textContent = commentContent; // 回复按钮 const replyButton = document.createElement("button"); replyButton.innerText = "回复"; replyButton.className = "reply-btn"; // 存储当前评论下所有回复的子列表 const replyList = document.createElement("ul"); replyList.className = "reply-list"; // 回复按钮点击事件 replyButton.addEventListener("click", function() { // 避免重复生成回复输入框 if (commentItem.querySelector('.reply-input-wrap')) return; // 回复输入区容器 const replyInputWrap = document.createElement("div"); replyInputWrap.className = "reply-input-wrap"; // 回复输入框 const replyInput = document.createElement("textarea"); replyInput.className = "reply-input"; replyInput.placeholder = "请输入回复内容"; // 提交回复按钮 const submitReplyBtn = document.createElement("button"); submitReplyBtn.innerText = "发布回复"; // 提交回复逻辑 submitReplyBtn.addEventListener("click", function() { const replyContent = replyInput.value.trim(); if (!replyContent) return; const replyItem = document.createElement("li"); replyItem.textContent = replyContent; replyList.appendChild(replyItem); // 提交完成后移除输入区 replyInputWrap.remove(); }) // 组装回复输入区并插入到当前评论节点内 replyInputWrap.appendChild(replyInput); replyInputWrap.appendChild(submitReplyBtn); commentItem.insertBefore(replyInputWrap, replyList); }) // 组装单条主评论所有元素 commentItem.appendChild(commentSpan); commentItem.appendChild(replyButton); commentItem.appendChild(replyList); // 通过DocumentFragment插入减少页面重绘 const fragment = document.createDocumentFragment(); fragment.appendChild(commentItem); commentsWrap.appendChild(fragment); // 提交后清空主评论输入框 userCommentInput.value = ''; }
实现说明
- 每条主评论为独立
li节点,内部自带专属回复列表容器,回复内容会直接追加到对应评论的子列表中,不会串到其他评论下 - 新增了重复渲染校验,点击回复按钮只会生成一个输入框,不会重复出现多个输入区
- 新增了空内容校验,不会提交空白的评论和回复
- 保留了DocumentFragment优化插入性能的逻辑
内容的提问来源于stack exchange,提问作者Mayank Sharma
相关产品推荐
相关产品推荐

