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

编辑帖子按钮onclick函数仅运行一次的问题求助

问题:帖子编辑按钮首次点击正常,再次点击无响应

点击帖子的编辑按钮,第一次可正常触发编辑流程并更新内容,但再次点击该按钮时,onclick函数完全不执行。

HTML代码

<div class="post">
    <b><a href="{% url 'profile' post.author.id %}">{{post.author}}</a></b>
    <input type="hidden" name="postid" value={{post.id}}>
    <!-- <br><br> -->
    <p>{{post.content}}</p>
    {% csrf_token %}
    <textarea name="edit_content" id="edit_content" cols="50" rows="5"></textarea>
    {% if user.is_authenticated %}
        {% if post.author == user %}
            <button class="edit" onclick="edit(this)">Edit</button>
        {% endif %}                
    {% endif %}
    <p><small class="text-muted">{{post.created_on}}</small></p>
</div>

注:textarea默认设置display: none

JavaScript代码(原代码)

function edit(ele){
var parent = ele.parentNode;
console.log(ele.parentNode);
var post = parent.querySelector('p');
var textarea = parent.querySelector('textarea');
var id = parent.querySelector('input');

post.style.display = 'none';
textarea.style.display = 'block';
ele.innerHTML = "Save"; 
ele.id = "save";
ele.disabled = true;
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;

textarea.onkeyup = () => {
    if( textarea.value.length > 0){
        ele.disabled = false;
    }
    else{
        ele.disabled = true;
    }
}

var save = document.getElementById('save');
save.onclick = () => {
    fetch("http://127.0.0.1:8000/edit", {
        method : "PUT",
        headers: {'X-CSRFToken': csrftoken},
        body : JSON.stringify({
            "postdata" : textarea.value,
            "id" : id.value
            })
    }).then(() => {
        post.innerHTML = textarea.value;
        // textarea.value = '';
        post.style.display = "block";
        textarea.style.display = "none";
        ele.innerHTML = "Edit";
        save.removeAttribute('id');
    });
}

问题根源

第一次点击编辑按钮时,代码给按钮绑定了新的onclick保存逻辑,这会直接覆盖按钮原本的edit()点击事件。保存完成后,仅将按钮文本改回"Edit",但未恢复原本的onclick="edit(this)"绑定,导致后续点击无任何函数触发。

此外,原代码中通过getElementById('save')获取按钮存在隐患:若页面有多个帖子,重复设置相同ID会导致DOM元素冲突。

修复方案

放弃通过覆盖onclick切换逻辑的方式,改为在同一个edit函数内根据按钮当前状态(编辑/保存)执行对应操作,同时优化潜在问题:

function edit(ele){
    const parent = ele.parentNode;
    const post = parent.querySelector('p');
    const textarea = parent.querySelector('textarea');
    const id = parent.querySelector('input[name="postid"]');
    // 从当前帖子节点获取CSRF Token,避免多帖子场景下取错
    const csrftoken = parent.querySelector('[name=csrfmiddlewaretoken]').value;

    // 根据按钮文本判断当前状态
    if(ele.textContent.trim() === "Edit"){
        // 切换到编辑模式
        post.style.display = 'none';
        textarea.style.display = 'block';
        // 把当前帖子内容同步到textarea(原代码缺失此步骤)
        textarea.value = post.textContent.trim();
        ele.textContent = "Save";
        // 初始根据内容长度设置按钮禁用状态
        ele.disabled = textarea.value.length === 0;
    } else {
        // 执行保存操作
        fetch("http://127.0.0.1:8000/edit", {
            method : "PUT",
            headers: {
                'X-CSRFToken': csrftoken,
                'Content-Type': 'application/json'
            },
            body : JSON.stringify({
                "postdata" : textarea.value,
                "id" : id.value
            })
        }).then(() => {
            post.innerHTML = textarea.value;
            post.style.display = "block";
            textarea.style.display = "none";
            ele.textContent = "Edit";
        });
    }

    // 实时监听输入,控制保存按钮禁用状态
    textarea.onkeyup = () => {
        // 仅在保存状态时触发
        if(ele.textContent.trim() === "Save"){
            ele.disabled = textarea.value.length === 0;
        }
    }
}

关键修改点

  • 移除动态ID操作,通过按钮文本判断状态,避免DOM ID冲突
  • 进入编辑模式时自动同步帖子内容到textarea,提升用户体验
  • 从当前帖子节点获取CSRF Token,适配多帖子场景
  • 同一个函数处理编辑/保存逻辑,避免事件绑定被覆盖
  • 优化按钮禁用状态的初始设置与实时监听逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:41:57