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

页面刷新后点赞/点踩计数器不显示问题求助

修复留言板刷新后点赞/点踩计数器消失的问题

问题根源

  1. 页面刷新恢复按钮状态时,直接替换按钮的innerHTML,删除了原本的计数器<span>元素,导致后续无法更新计数器显示
  2. 点赞/点踩操作成功后,未将最新的计数器数值存入localStorage,刷新后无法读取更新后的数据
  3. 恢复按钮图标时使用的图片路径与激活态不一致,且未保留计数器显示

修复后的完整脚本代码

function setReplyTo(messageId) {
    document.getElementById('reply_to').value = messageId;
}

function likeMessage(messageId) {
    // 检查是否已点赞/点踩
    if (localStorage.getItem(`liked_${messageId}`) === '1') {
        console.log('该消息已被点赞');
        return;
    }
    if (localStorage.getItem(`disliked_${messageId}`) === '1') {
        console.log('该消息已被点踩');
        return;
    }

    // 发送AJAX请求更新数据库
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'update_likes.php', true);
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    xhr.onload = function () {
        if (xhr.status === 200) {
            const response = JSON.parse(xhr.responseText);
            if (response.success) {
                const likeBtn = document.getElementById(`likeBtn${messageId}`);
                // 找到按钮内的img和span元素,只修改src和文本,不替换整个HTML
                const img = likeBtn.querySelector('.thumbs-up-image');
                const countSpan = likeBtn.querySelector(`#likeCount${messageId}`);
                if (img) img.src = 'https://i.ibb.co/wpmSdDC/thumbsup-green.png';
                if (countSpan) countSpan.textContent = response.likeCount;
                
                likeBtn.disabled = true;

                // 存储状态和最新计数器值
                localStorage.setItem(`liked_${messageId}`, '1');
                localStorage.setItem(`likeCount_${messageId}`, response.likeCount);
                localStorage.removeItem(`disliked_${messageId}`);
                localStorage.removeItem(`dislikeCount_${messageId}`);
            } else {
                console.error(response.message);
            }
        }
    };
    xhr.send(`messageId=${messageId}&action=like`);
}

function dislikeMessage(messageId) {
    // 检查是否已点赞/点踩
    if (localStorage.getItem(`liked_${messageId}`) === '1') {
        console.log('该消息已被点赞');
        return;
    }
    if (localStorage.getItem(`disliked_${messageId}`) === '1') {
        console.log('该消息已被点踩');
        return;
    }

    // 发送AJAX请求更新数据库
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'update_likes.php', true);
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    xhr.onload = function () {
        if (xhr.status === 200) {
            const response = JSON.parse(xhr.responseText);
            if (response.success) {
                const dislikeBtn = document.getElementById(`dislikeBtn${messageId}`);
                // 找到按钮内的img和span元素,只修改src和文本
                const img = dislikeBtn.querySelector('.thumbs-down-image');
                const countSpan = dislikeBtn.querySelector(`#dislikeCount${messageId}`);
                if (img) img.src = 'https://i.ibb.co/YLjV9ZW/thumbsdown-red.png';
                if (countSpan) countSpan.textContent = response.dislikeCount;
                
                dislikeBtn.disabled = true;

                // 存储状态和最新计数器值
                localStorage.setItem(`disliked_${messageId}`, '1');
                localStorage.setItem(`dislikeCount_${messageId}`, response.dislikeCount);
                localStorage.removeItem(`liked_${messageId}`);
                localStorage.removeItem(`likeCount_${messageId}`);
            } else {
                console.error(response.message);
            }
        }
    };
    xhr.send(`messageId=${messageId}&action=dislike`);
}

// 页面加载时恢复按钮状态和计数器
window.addEventListener('DOMContentLoaded', function () {
    // 恢复点赞状态
    const likedMessages = Object.keys(localStorage).filter(key => key.startsWith('liked_'));
    likedMessages.forEach(key => {
        const messageId = key.replace('liked_', '');
        const likeBtn = document.getElementById(`likeBtn${messageId}`);
        if (likeBtn) {
            const img = likeBtn.querySelector('.thumbs-up-image');
            const countSpan = likeBtn.querySelector(`#likeCount${messageId}`);
            // 设置激活态图标
            if (img) img.src = 'https://i.ibb.co/wpmSdDC/thumbsup-green.png';
            // 设置计数器数值
            const storedCount = localStorage.getItem(`likeCount_${messageId}`);
            if (countSpan) countSpan.textContent = storedCount || countSpan.dataset.count;
            
            likeBtn.disabled = true;
        }
    });

    // 恢复点踩状态
    const dislikedMessages = Object.keys(localStorage).filter(key => key.startsWith('disliked_'));
    dislikedMessages.forEach(key => {
        const messageId = key.replace('disliked_', '');
        const dislikeBtn = document.getElementById(`dislikeBtn${messageId}`);
        if (dislikeBtn) {
            const img = dislikeBtn.querySelector('.thumbs-down-image');
            const countSpan = dislikeBtn.querySelector(`#dislikeCount${messageId}`);
            // 设置激活态图标
            if (img) img.src = 'https://i.ibb.co/YLjV9ZW/thumbsdown-red.png';
            // 设置计数器数值
            const storedCount = localStorage.getItem(`dislikeCount_${messageId}`);
            if (countSpan) countSpan.textContent = storedCount || countSpan.dataset.count;
            
            dislikeBtn.disabled = true;
        }
    });

    // 未操作过的消息,确保计数器显示初始值
    const likeCountSpans = document.querySelectorAll('[id^="likeCount"]');
    likeCountSpans.forEach(span => {
        const messageId = span.id.replace('likeCount', '');
        if (!localStorage.getItem(`liked_${messageId}`) && !localStorage.getItem(`disliked_${messageId}`)) {
            span.textContent = span.dataset.count;
        }
    });

    const dislikeCountSpans = document.querySelectorAll('[id^="dislikeCount"]');
    dislikeCountSpans.forEach(span => {
        const messageId = span.id.replace('dislikeCount', '');
        if (!localStorage.getItem(`liked_${messageId}`) && !localStorage.getItem(`disliked_${messageId}`)) {
            span.textContent = span.dataset.count;
        }
    });
});

关键修改点

  1. 保留计数器元素:不再通过innerHTML重写按钮内容,而是通过querySelector找到按钮内的图片和计数器元素,单独修改属性,避免删除计数器<span>
  2. 存储最新计数器值:在点赞/点踩成功后,将接口返回的最新likeCount/dislikeCount存入localStorage
  3. 统一激活态图标:恢复状态时使用与操作时一致的激活态图标,保持视觉统一
  4. 完善计数器恢复逻辑:加载页面时,优先读取localStorage中的最新数值,没有则使用PHP渲染的初始值,确保所有情况下计数器都能正确显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:09:50