最近在优化网站的页面,在用Bootstrap框架渲染用户上传头像的页面时候,遇到了一个问题
如果不用任何渲染,单纯用原生HTML的input标签上传文件,在你选择完文件以后,文件的文件名是可以显示在input框边上的。
但是你如果用了bootstrap渲染后,已选择的文件名无法显示了(虽然实际上他已经被选中了)
1: 功能实现
然后查阅了资料以后,决定在html页面写一段script,功能得以实现
<div class="container">
<div class="custom-file">
<form action="{% url 'users:edit_profile' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="{{profile.avatar.name}}" id={{profile.avatar.id_for_label}} class="custom-file-input" >
<label class="custom-file-label upload_avatar_label" for={{profile.avatar.id_for_label}}>选择文件</label>
<div id="showfilename"></div>
<button id="submit_avatar" class="btn btn-warning" type="submit">提交修改</button>
</form>
</div>
</div>
<script type="text/javascript">
var input = document.getElementById('{{profile.avatar.id_for_label | safe}}');
var infoarea = document.getElementById('showfilename');
input.addEventListener('change',showFileName);
function showFileName(event){
var input = event.srcElement;
var fileName = input.files[0].name;
infoarea.textContent = 'Filename'+fileName;
}

2:但是这已经算一个非常简单的功能实现了,还是在HTML页面写了一大坨
所以我想把script移步到外联的js文件中去
<script src="{% static 'custom_js/edit_profile.js' %}"></script>
但是在把代码搬到外部JS的过程中,发现了一个问题,Django的模板变量无法在js中被应用,传过去以后相当于只是普通字符串,这个导致了一个严重的问题,getElementById取不到值了,如下图,我在代码里加入了alert进行测试

3: 最简单但不是很完美的解决方案
在网上搜索了半天之后,没有发现很好的解决办法,有些方法建议通过views函数来做,太懒了没试。
最后找了个看似比较简单的方法,他的原理是在html页面引入外部脚本的上方,先把变量进行定义,这样外联JS中就可以取到值了,来试一下。
<script type="text/javascript">
var input = document.getElementById('{{profile.avatar.id_for_label}}');
var infoarea = document.getElementById('showfilename');
</script>
<script src="{% static 'custom_js/edit_profile.js' %}"></script>
来看一下效果

总结:
看了下其他文章,应该还有更加好的方法,回头再研究了,先实现功能再说
网友评论