在Django模板中通过range输入框调整图片大小功能失效如何解决?
问题原因与修复方案
核心问题清单
- 脚本执行时机早于DOM渲染:
<script>标签放在了imageRange、range等目标元素之前,浏览器执行JS时元素还未加载,因此getElementById返回null - 无限递归逻辑错误:
updateTextInput函数末尾主动调用自身,形成死循环触发栈溢出,阻塞所有JS执行 - CSS高度缺少单位:直接给
style.height赋值纯数字不符合CSS规范,必须拼接px单位才会生效 - 按钮默认提交冲突:尺寸按钮的
type="submit",点击后会直接提交表单刷新页面,效果还未展现就被重置 - 滑块步长设置无效:
range的step="0"是非法值,会导致滑块无法正常拖动
修复后代码
{% extends "base.html" %} {% load i18n %} {% load static %} {% load crispy_forms_tags %} {% block conteudo %} <!-- 先渲染DOM元素,再放JS --> <form enctype="multipart/form-data" action="submit" method="POST">{% csrf_token %} <input type="number" class="form-control" name="pet-id" value="{{ pet.id }}" hidden> <div class="container"> <div class="form-group"> <label><b>{% trans "Porte" %}</b>:</label><br> <!-- 把按钮type改成button,阻止默认提交行为 --> <button class="btn btn-primary" style="color:black; font-size:70%" onclick="SetSize('pequeno')" type="button">Pequeno porte</button> <button class="btn btn-primary" style="color:black; font-size:70%" onclick="SetSize('medio')" type="button">Médio porte</button> <button class="btn btn-primary" style="color:black; font-size:70%" onclick="SetSize('grande')" type="button">Grande porte</button><br><br> <table class="fixed"> <tr> <td><img src="https://cdn.pixabay.com/photo/2018/03/30/13/04/silhouette-3275316_960_720.png" height="150" /></td> <td style="vertical-align:bottom"><img id="imageRange" src="https://image.flaticon.com/icons/png/512/91/91544.png" height="80" /></td> </tr> </table> <!-- step改成1,合法步长 --> <input class="form-range" style="width:30%" id="range" type="range" min="40" step="1" max="120" oninput="updateTextInput();" > </div> </div> </form> <script> function updateTextInput() { var value = document.getElementById("range").value; var img = document.getElementById('imageRange'); // 拼接px单位 img.style.height = value + 'px'; // 删掉无限递归的调用 } function SetSize(porte){ var tamanho; switch (porte){ case 'pequeno': tamanho = 40 break; case 'medio': tamanho = 80 break; case 'grande': tamanho = 120 break; } document.getElementById("range").value = tamanho; updateTextInput(); } </script> {% endblock conteudo %}
额外说明
如果你的模板结构必须把JS放在DOM前面,可以给JS逻辑包裹DOM加载完成的监听事件,确保元素加载完成后再执行逻辑:
document.addEventListener('DOMContentLoaded', function() { // 把所有JS逻辑放在这里 });
内容的提问来源于stack exchange,提问作者Jackgba
相关产品推荐
相关产品推荐

