【分功能一】实时加载用户选择的头像文件

发布时间 2023-07-21 15:47:26作者: Chimengmeng

【一】代码实现

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

       <!--  CDN 链接 引入方法  -->
    <!--  Bootstrap 的 CSS 样式文件  -->
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
    <!--  Bootstrap 的 JS 文件 (动画效果需要jQuery)  -->
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js">// bootstrap </script>
    <!--  jQuery 文件  -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"> // jquery</script>
    <!--  以下为 css样式书写区  -->
    <style>


    </style>

</head>
<body>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">注册功能</h1>
            {#   不用form表单提交数据     #}
            <form id="myform">
                {% csrf_token %}
                {% for form in form_obj %}
                    <div class="form-group">
                        <label for="">{{ form.label }}</label>
                        {{ form }}
                        <span style="color: red">{{ form.errors.0 }}</span>
                    </div>
                {% endfor %}
                <div class="form-group text-center">
                    <label for="myfile">
                        选择头像<img src="{% static 'avatar/default.png' %}" id="myimg" alt=""
                                     style="height: 200px;width: 200px;margin-left: 20px">
                    </label>
                    <input type="file" id="myfile" name="avatar" style="display: none">
                </div>

                 <input type="button" class="btn btn-primary pull-right" value="注册" id="btn_commit">

            </form>

        </div>
    </div>
</div>

<script>
    {#  文本域变化事件  #}
    $("#myfile").change(function () {
        // 文件阅读器对象
        // (1)先生成一个文本阅读器对象
        let myFileReaderObj = new FileReader();
        // (2)获取用户上传的头像文件
        let fileObj = $(this)[0].files[0];
        // (3)将文件对象交给阅读器对象读取
        myFileReaderObj.readAsDataURL(fileObj) // 异步操作 + IO操作
        // (4)利用文件阅读器将文件展示到前端页面  修改src属性
        // 等待 文件阅读器加载完毕之后再执行
        myFileReaderObj.onload = function () {
            $("#myimg").attr('src', myFileReaderObj.result) // 直接写有bug,需要放在 onload 里面
        }
    })
</script>

</body>
</html>

【二】静态展示头像代码分析

<div class="form-group text-center">
                    <label for="myfile">
                        选择头像<img src="{% static 'avatar/default.png' %}" id="myimg" alt=""
                                     style="height: 200px;width: 200px;margin-left: 20px">
                    </label>
                    <input type="file" id="myfile" name="avatar" style="display: none">
                </div>

<label>标签通常用于表单中的输入字段
	如<input>、<select>或<textarea>等。
它可以通过两种方式与对应的表单元素建立关联:
	一种是将表单元素的id属性值与<label>的for属性值相匹配
	另一种是将表单元素直接包含在<label>标签内。

使用<label>标签
	当用户点击标签文本时,相关的表单元素就会被激活,这样用户就可以通过点击文本来聚焦到相应的输入字段上。
	这提升了表单的可用性和易用性,并且对于使用辅助技术的用户(如屏幕阅读器)也更加友好。
只要是label里面的内容点击都会跳转到 for 指定的标签上
  • 在上述代码中

    • 定义了一个div标签包裹住了,头像标签部分(划定分区)
  • 通过动态加载本地文件加载默认的头像文件

    • src="{% static 'avatar/default.png' %}"
  • 同时给img标签加了一个id方便下面的ajax调用该标签

    • id="myimg"
  • 为了限制头像的大小,给头像强制加了样式,限制大小

    • style="height: 200px;width: 200px;margin-left: 20px"
  • 定义了一个 input 框用来让用户上传头像文件,同时属性设置为隐藏

    • id="myfile"
    • type="file"
    • style="display: none"

【三】动态更新头像代码分析

<script>
    {#  文本域变化事件  #}
    $("#myfile").change(function () {
        // 文件阅读器对象
        // (1)先生成一个文本阅读器对象
        let myFileReaderObj = new FileReader();
        // (2)获取用户上传的头像文件
        let fileObj = $(this)[0].files[0];
        // (3)将文件对象交给阅读器对象读取
        myFileReaderObj.readAsDataURL(fileObj) // 异步操作 + IO操作
        // (4)利用文件阅读器将文件展示到前端页面  修改src属性
        // 等待 文件阅读器加载完毕之后再执行
        myFileReaderObj.onload = function () {
            $("#myimg").attr('src', myFileReaderObj.result) // 直接写有bug,需要放在 onload 里面
        }

    })
</script>
  • 在Ajax请求过程中,可以监听文本域的多种事件,例如:

    • onkeydown:当用户按下键盘上的任意键时触发。

    • onkeypress:当用户按下键盘上的字符键时触发。

    • onkeyup:当用户释放键盘上的键时触发。

    • onchange:当文本域的值发生改变时触发。

    • oninput:当用户输入或粘贴内容到文本域时触发(包括通过键盘输入、鼠标操作或者通过其他方式)。

    • onselect:当用户选择文本域中的一部分或全部内容时触发。

  • 通过监听这些事件

    • 可以实现对文本域内容的实时监控、自动保存或自动完成等功能。
  • 一般情况下

    • 可以在文本域的HTML标签中添加对应的事件处理函数
    • 也可以使用JavaScript动态绑定事件处理函数。
  • 在上面的逻辑中引入了 ajax的文本域事件中的change方法

    • 即动态监控某一块区域的变化同时给出相应的响应
  • 首先通过定义的id值找到需要监控变化发生的标签

    • $("#myfile")
  • 然后加上文本域变化监控方法

    • $("#myfile").change(function () {}
  • 在方法内书写当变化发生时,产生的逻辑方法

    • 先生成文本阅读器对象 - 掌事者/

      • let myFileReaderObj = new FileReader();
    • 然后拿到用户上传的头像文件

      • let fileObj = $(this)[0].files[0];

        • $(this):表示当前上下文中的jQuery对象。
        • [0]:获取jQuery对象中的第一个元素。
        • .files[0]:获取文件选择器中选中的文件对象数组中的第一个文件对象。
        • 综合起来
          • $(this)[0].files[0] 的意思是从当前上下文中的文件选择器中获取选中的第一个文件对象。
          • 这个文件对象可以是用户选择的文件
          • 例如通过 <input type="file"> 元素实现的文件选择器。
        • 获取到的文件对象可以用于进行进一步的处理
          • 例如读取文件的内容、上传文件到服务器等操作。
    • 将这个文件对象交给我们的掌事者即文本阅读器对象

      • myFileReaderObj.readAsDataURL(fileObj)

        • myFileReaderObj 是一个 FileReader 对象
          • 用于读取文件的内容。
          • 通过调用该对象的 readAsDataURL() 方法来实现读取文件。
        • readAsDataURL(fileObj) 是一个异步操作
          • 它会以异步的方式读取 fileObj 所代表的文件的内容
          • 并将其转换为 Data URL。Data URL 是一种将文件内容直接嵌入到 URL 中的方式
          • 可以用于在浏览器中展示或传输文件的内容。
        • 这行代码中的 fileObj 是之前获取的文件对象
          • 会作为参数传递给 readAsDataURL() 方法
          • 告诉它要读取哪个文件的内容。
        • 需要注意的是
          • readAsDataURL() 是一个涉及 IO 操作的异步操作
          • 所以需要在其完成后才能获取到读取到的结果。
          • 通常会监听 FileReader 对象的 onload 事件
            • 当该事件触发时,表示文件的内容已经读取完成
            • 可以通过 FileReader 对象的 result 属性获取读取到的 Data URL 数据。
    • 因为上述操作是一个异步IO操作,所以我们需要监听FileReader 对象的 onload 事件,通过触发该事件,达到实时替换头像的效果

      • myFileReaderObj.onload
    • 定义触发该事件后,进行的功能

      • $("#myimg").attr('src', myFileReaderObj.result)

        • 这行代码是将读取到的 Data URL 数据设置为指定元素(ID 为 "myimg")的 src 属性值。

        • 具体解释如下:

          • $("#myimg") 是一个 jQuery 选择器
            • 用于选择具有特定 ID 的元素。
            • 在这里,通过选择器 #myimg 来选取 ID 为 "myimg" 的元素。
          • attr('src', myFileReaderObj.result) 是调用了 attr() 方法来设置选中元素的 src 属性值。
            • 其中第一个参数是属性名 'src'
            • 第二个参数是要设置的属性值 myFileReaderObj.result
            • 在这里,myFileReaderObj.result 是之前通过 FileReader 对象读取得到的 Data URL 数据。
          • 所以
            • 这行代码的作用是将 Data URL 数据设置为 ID 为 "myimg" 的元素的 src 属性值。
            • 这样做之后,该元素就会显示 Data URL 所代表的图片或者其他支持的媒体类型。
  • 通过以上方法达到实时展示用户更换头像的效果

【四】主要逻辑代码总结

  • 展示头像部分
<div class="form-group text-center">
                    <label for="myfile">
                        选择头像<img src="{% static 'avatar/default.png' %}" id="myimg" alt=""
                                     style="height: 200px;width: 200px;margin-left: 20px">
                    </label>
                    <input type="file" id="myfile" name="avatar" style="display: none">
                </div>

  • 动态监听事件
<script>
    {#  文本域变化事件  #}
    $("#myfile").change(function () {
        // 文件阅读器对象
        // (1)先生成一个文本阅读器对象
        let myFileReaderObj = new FileReader();
        // (2)获取用户上传的头像文件
        let fileObj = $(this)[0].files[0];
        // (3)将文件对象交给阅读器对象读取
        myFileReaderObj.readAsDataURL(fileObj) // 异步操作 + IO操作
        // (4)利用文件阅读器将文件展示到前端页面  修改src属性
        // 等待 文件阅读器加载完毕之后再执行
        myFileReaderObj.onload = function () {
            $("#myimg").attr('src', myFileReaderObj.result) // 直接写有bug,需要放在 onload 里面
        }

    })
</script>