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

如何为Django HTML网页实现滚动锁定 避免表单提交后返回顶部

解决方案

问题本质是传统表单提交会触发全页面重定向/刷新,浏览器默认会重置滚动位置到顶部,以下提供两种可直接落地的方案:

方案1:AJAX异步提交(推荐,无刷新体验最优)

无需页面跳转,提交后原地更新状态,完全不会改变滚动位置,最适合快速录入数据的场景。

步骤1:修改HTML模板

给每个表单添加标识,新增JS提交逻辑拦截默认提交行为:

<!-- 给form新增类、数据属性和唯一ID -->
<form class="form-group mt-4 avonlea-form" method="post" 
      data-unit="{{unit_number.data.value}}"
      id="unit-{{unit_number.data.value}}"
      {% if unit_number.data.value in created_nums %}  style="background-color: rgb(231, 224, 224);  " {% endif %} >
<!-- 原有表单内容保持不变 -->
</form>

<!-- 页面底部新增JS逻辑 -->
<script>
document.querySelectorAll('.avonlea-form').forEach(form => {
  form.addEventListener('submit', async (e) => {
    e.preventDefault();
    const formData = new FormData(form);
    const submitBtn = form.querySelector('button[type="submit"]');

    try {
      const res = await fetch(window.location.href, {
        method: 'POST',
        body: formData,
        headers: {
          'X-CSRFToken': form.querySelector('[name=csrfmiddlewaretoken]').value
        }
      });
      const result = await res.json();
      if(result.status === 'success') {
        // 提交成功后把表单置灰、按钮禁用,和已提交样式保持一致
        form.style.backgroundColor = 'rgb(231, 224, 224)';
        submitBtn.disabled = true;
      } else {
        alert('提交失败:' + result.msg);
      }
    } catch(err) {
      alert('请求异常,请重试');
    }
  })
})
</script>

步骤2:修改Views.py的post逻辑

兼容AJAX请求,返回JSON响应:

from django.http import JsonResponse
from django.urls import reverse

def post(self,request):
    created_nums= AvonleaClass.objects.all().values_list('unitNumber', flat=True)
    # 注意要加request.FILES,否则表单的图片上传功能会失效
    form = AvonleaForm(request.POST, request.FILES)
    if form.is_valid():
        form.save()
        messages.success(request , '创建成功')
        # 判断是否为AJAX请求,是则返回JSON
        if request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' or request.accepts('application/json'):
            return JsonResponse({'status':'success', 'msg':'保存成功'})
        return redirect('Avonlea')
    else:
        if request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' or request.accepts('application/json'):
            return JsonResponse({'status':'error', 'msg':form.errors.as_text()})
        # 原代码传递created_nums时漏了参数名引号,已修正
        return render(request, 'meter_readings/avonlea.html', {'form': form ,  'created_nums':created_nums })

注意:原代码中messages.success写在redirect之后,属于不可达代码,以上代码已经调整了执行顺序。

方案2:锚点跳转(改造成本最低,无需JS)

提交后页面仍会刷新,但会自动定位到刚刚提交的表单位置,适合不想改动前端逻辑的场景。

步骤1:给表单添加锚点ID

给每个form标签添加唯一ID作为锚点:

<form id="unit-{{unit_number.data.value}}" class="form-group mt-4" method="post"  {% if unit_number.data.value in created_nums %}  style="background-color: rgb(231, 224, 224);  " {% endif %} >

步骤2:修改重定向逻辑,携带锚点

def post(self,request):
    created_nums= AvonleaClass.objects.all().values_list('unitNumber', flat=True)
    form = AvonleaForm(request.POST, request.FILES)
    if form.is_valid():
        saved_obj = form.save()
        messages.success(request , '创建成功')
        # 重定向时带上提交成功的表单锚点
        return redirect(f'{reverse("Avonlea")}#unit-{saved_obj.unitNumber}')
    else:
        return render(request, 'meter_readings/avonlea.html', {'form': form ,  'created_nums':created_nums })

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:45:05