You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript实现动态创建评论的精准编辑功能

问题描述

我正在开发一个社交媒体评论区,用户可通过底部评论框添加自定义评论。我希望给每条评论添加一个Edit按钮,点击后仅对该条评论进行编辑。之前尝试添加点击函数生成输入框时,会在所有带Edit按钮的评论上都生成输入框,请问如何让Edit按钮精准作用于被点击的目标评论?

相关代码

HTML代码

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <link href='style.css' type='text/css' rel='stylesheet' />
</head>
<body>
<div id='wholeForm'>
<div id="question">
    <p id="nameOfPerson">WhySoSerious45</p>
    <p id="commentOfPerson">Trying to decide a career path? Programming is the move. Change my mind.</p>
</div>
<div class='form2'>
    <div class='eachComment'>
    <div class="comments">
    <img class="imgClass" src="userImage.jpg">
    <p class="nameVal">Jonny R</p>
    <p class="commentVal">I wish I knew how to program! Maybe ill start learning?</p>
    <input type="button" class="edit" value="Edit">
    <input type="button" class="delete" value="Delete">
    </div>
    </div>
</div>
<div class='form1'>
    <div class='formInput'>
    <input type="text" id="name" placeholder="Display Name"/>
    <input type='text' id="bodyText" placeholder="Comment">
    </div>
    <input type="button" id="addComment" value="Submit">
</div>

</div>

<script src="https://code.jquery.com/jquery-3.5.0.slim.min.js" integrity="sha256-MlusDLJIP1GRgLrOflUQtshyP0TwT/RHXsI1wWGnQhs=" crossorigin="anonymous"></script>
<script src="app.js"></script>
</body>
</html>

(注:已将原HTML中edit/delete按钮的id改为class,修复ID重复问题)

CSS代码

body{
    background-color: #E5E5E5
}

#wholeForm{
    margin: 0 auto;
    width: 800px;
    height: 400px;
    position: relative;
    background-color: #D3D3D3;
    font-family: helvetica;
}

#question{
    padding: 0px;
    margin: 0px;
    width: 780px;
    height: 75px;
    background-color: white;
    padding:10px;
}

#nameOfPerson{
  font-size:13px;
  margin: 0;
  padding: 0;
}

#commentOfPerson{
  font-size:25px;
  font-weight: bold;
  margin: 0;
  padding: 0;
}

.form2{
    width: 800px;
    height: 458px;
}

.comments{
    background-color: white;
    width: 780px;
    height: 75px;
    position: relative;
    margin: 10px;
}

.form1{
    padding:20px;
    margin-bottom: 10px;
    width: 758px;
    position: absolute;
    bottom: -10px;
    background-color: white;
}

#addComment{
    display: inline-block;
    margin-left: 35px;
}

#name{
    width: 125px;
}
#bodyText{
    width: 500px;
}

.formInput{
    display: inline-block;
}

.nameVal{
    display: inline-block;
    font-size: 12px;
    position: absolute;
}
.commentVal{
    display: inline-block;
    position: absolute;
    font-weight: bold;
    font-size: 18px;
    bottom: 5px;
}

.imgClass{
 display: inline-block;
 height: 65px;
 width: 65px;
 margin: 5px;
}

.edit{
    position: absolute;
    right:55px;
    border: none;
    text-decoration: underline;
    color:#30D5C8;
    background-color:white;
    margin:5px;
}

.delete{
    position: absolute;
    right:0px;
    border: none;
    text-decoration: underline;
    color:#30D5C8;
    background-color:white;
    margin:5px;
}

.edit:hover{
    color:#DDA0DD
}

.delete:hover{
    color:#DDA0DD
}

(注:已将原CSS中针对#edit/#delete的选择器改为.edit/.delete,匹配修改后的class)

JavaScript代码(原代码)

$(document).ready(function(){
    let value;
    let storeValues = []
    let storeValueName;
    let storeValueComment;
    $('#addComment').click(function(){
    storeValueName = getName(); 
    storeValueComment = getComment();
    storeValues.push(storeValueName);
    storeValues.push(storeValueComment);
    value = getName() + getComment();
    function getName(){
        let grabName;
        $('#name').val(function(i, v){
            grabName = v;
        })
        return grabName;
    }

    function getComment(){
        let grabComment;
        $('#bodyText').val(function(i, v){
            grabComment = v;
        })
        return grabComment
    }
    console.log(storeValues);
    
    $('.eachComment').prepend('<div class="comments">' +'<img class="imgClass" src="userImage.jpg">'+'<p class="nameVal">'
    + storeValueName +'</p>' + '<p class="commentVal">'+ storeValueComment +'</p>'+
    '<input type="button" class="edit" value="Edit" />'+ '<input type="button" class="delete" value="Delete" />' + '</div>');
    
        $('.edit').click(function(){

        })
    
    })
    
})

(注:已将新增评论中edit/delete按钮的id改为class)


解决方案

核心思路

  1. 修复ID重复问题:HTML中ID必须唯一,原代码中所有评论的Edit/Delete按钮都用了相同ID,导致事件绑定混乱,改为class即可。
  2. 使用事件委托处理动态元素:新增的评论是动态生成的,直接绑定click事件无效,需要通过父元素委托事件。
  3. 精准定位目标评论:通过$(this).closest('.comments')找到当前点击按钮所在的评论容器,再操作该容器内的元素,避免影响其他评论。

修改后的完整JavaScript代码

$(document).ready(function(){
    let storeValues = [];

    // 添加评论
    $('#addComment').click(function(){
        const storeValueName = $('#name').val().trim();
        const storeValueComment = $('#bodyText').val().trim();
        
        if(!storeValueName || !storeValueComment) return;
        
        storeValues.push({name: storeValueName, comment: storeValueComment});
        
        $('.eachComment').prepend(`
            <div class="comments">
                <img class="imgClass" src="userImage.jpg">
                <p class="nameVal">${storeValueName}</p>
                <p class="commentVal">${storeValueComment}</p>
                <input type="button" class="edit" value="Edit" />
                <input type="button" class="delete" value="Delete" />
            </div>
        `);
        
        // 清空输入框
        $('#name').val('');
        $('#bodyText').val('');
    });

    // 编辑评论:事件委托给父元素
    $('.eachComment').on('click', '.edit', function(){
        const $commentContainer = $(this).closest('.comments');
        const $commentText = $commentContainer.find('.commentVal');
        const currentText = $commentText.text();

        // 替换评论文本为输入框
        $commentText.replaceWith(`
            <input type="text" class="edit-input" value="${currentText}" />
            <button class="save-btn">Save</button>
            <button class="cancel-btn">Cancel</button>
        `);

        // 隐藏当前Edit按钮
        $(this).hide();
    });

    // 保存编辑:事件委托
    $('.eachComment').on('click', '.save-btn', function(){
        const $commentContainer = $(this).closest('.comments');
        const $input = $commentContainer.find('.edit-input');
        const newText = $input.val().trim();

        if(newText){
            // 替换输入框为新的评论文本
            $input.replaceWith(`<p class="commentVal">${newText}</p>`);
            // 显示Edit按钮
            $commentContainer.find('.edit').show();
            // 移除保存/取消按钮
            $(this).add('.cancel-btn').remove();
        }
    });

    // 取消编辑:事件委托
    $('.eachComment').on('click', '.cancel-btn', function(){
        const $commentContainer = $(this).closest('.comments');
        const originalText = $commentContainer.find('.edit-input').val();
        // 恢复原评论文本
        $commentContainer.find('.edit-input').replaceWith(`<p class="commentVal">${originalText}</p>`);
        // 显示Edit按钮
        $commentContainer.find('.edit').show();
        // 移除保存/取消按钮
        $(this).add('.save-btn').remove();
    });

    // 删除评论:事件委托
    $('.eachComment').on('click', '.delete', function(){
        $(this).closest('.comments').remove();
    });
});

说明

  • 事件委托绑定在.eachComment父元素上,不管是静态还是动态生成的评论按钮,都能触发事件。
  • 通过closest('.comments')精准获取当前点击按钮所在的评论容器,确保操作只针对目标评论。
  • 编辑流程:点击Edit按钮→隐藏按钮,显示输入框+保存/取消按钮→点击Save替换为新评论,点击Cancel恢复原评论。

内容的提问来源于stack exchange,提问作者Brad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:00:54