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

Django文章点赞后跳转至页面顶部问题求助:需保留当前页面滚动位置

解决Django点赞后页面跳回顶部的问题

这个问题我之前帮朋友排查过——用表单同步提交的话,页面必然会刷新重载,自然就回到顶部了。咱们换成异步AJAX请求就能完美解决,既不用刷新页面,还能稳稳保持当前滚动位置,同时实时更新点赞状态和数量。

步骤1:修改视图函数(views.py)

把原来的重定向逻辑改成返回JSON数据,告诉前端点赞操作的结果:

from django.http import JsonResponse

def like_post(request, category_slug, post_slug):
    if request.method == 'POST':
        post = get_object_or_404(Post, id=request.POST.get('like_btn'))
        liked = False
        if post.likes.filter(id=request.user.id).exists():
            post.likes.remove(request.user)
            liked = False
        else:
            post.likes.add(request.user)
            liked = True
        # 返回点赞状态和最新点赞数给前端
        return JsonResponse({
            'liked': liked,
            'total_likes': post.total_likes()
        })
    # 非POST请求直接返回错误
    return JsonResponse({'error': 'Invalid request'}, status=400)

步骤2:修改前端模板(post_detail页面)

给表单加个ID方便JS定位,然后用原生JS阻止默认提交行为,发送异步请求:

<form id="like-form" action="{% url 'like_post' single_post.category.slug single_post.slug %}" method="POST">
 {% csrf_token %}
 <button type="submit" name="like_btn" value={{single_post.id}} class="ui red button like_btn" >
 <i class="heart icon {% if request.user in single_post.likes.all %}red{% endif %}"></i> 
 {% if request.user in single_post.likes.all %}Liked{% else %}Like{% endif %} ({{single_post.total_likes}})
 </button>
</form>

<script>
document.getElementById('like-form').addEventListener('submit', function(e) {
    e.preventDefault(); // 阻止表单默认刷新行为
    const form = this;
    const url = form.action;
    const formData = new FormData(form);
    
    fetch(url, {
        method: 'POST',
        headers: {
            'X-CSRFToken': form.querySelector('[name=csrfmiddlewaretoken]').value,
        },
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        // 实时更新按钮的文本、图标和点赞数
        const button = form.querySelector('.like_btn');
        const icon = button.querySelector('.heart.icon');
        if (data.liked) {
            button.innerHTML = `<i class="heart icon red"></i> Liked (${data.total_likes})`;
        } else {
            button.innerHTML = `<i class="heart icon"></i> Like (${data.total_likes})`;
        }
    })
    .catch(error => console.error('点赞出错啦:', error));
});
</script>

为什么这套方案可行?

  • 用AJAX异步请求,页面完全不刷新,滚动位置自然纹丝不动
  • 实时更新按钮状态和点赞数,用户体验比刷新页面流畅太多
  • 不用重载整个文章页面,服务器压力也更小

如果你习惯用jQuery,把JS部分换成jQuery的$.ajax写法也可以,逻辑是一样的。现在测试一下,点击点赞按钮后,页面不会跳回顶部,点赞状态和数字也会立刻更新~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 17:54:08