Front-end and mobile development-Ajax programming-JSON string, XHR2.0 new features, throttling function

Ajax programming

review

  1. The XMLHttpRequest constructor used natively at the bottom of Ajax, which is an attribute of the window (an interface of the browser)

  2. GET is behind the url? Splicing parameters are passed to the background

  3. The POST method is sent to the background in the body

  4. If you send a file, you need to ensure that the content type sent is not a string but multipart/form-data

  5. Collect the values ​​in the form

    serialize

    • Cannot collect documents with
    • Disabled tags cannot be collected
    • When collecting, key is the value of the name attribute, and value is the value of the form

8. JSON

8.0 JSON string writing

The carrier (representation) of the background data can be a JSON string

Lightweight data exchange format

JSON string and JS data conversion

// 为什么要有JSON出现呢?
// 因为JS的数组/对象 转成字符串, 没办法使用了
var obj = {
    
    name: "小明"};
console.log(obj.toString()); // 字符串类型 [object Object]

// 所以引入JSON数据格式字符串使用
var obj = {
    
    name: "小明"};
console.log(JSON.stringify(obj)); // 字符串类型 {"name":"小明"}

// 后台返回数组/对象数据时, 传递的数据是JSON格式字符串

8.1 Introduction to JSON file

  • No comments allowed
  • Cannot have functions
  • Property name, string type value, must be enclosed in double quotes
  • A complete JSON string, the brackets before and after must correspond

No undefined, no function, no comment

{
    
    
    "name": "hello",
    "age": 18,
    "marry": false
}

9. XHR2.0 new features

XHR2.0-Introduction

XMLHttpRequest is an API provided by a browser. After the concept of HTML 5 was formed, W3C in February 2008, the new version of XMLHttpRequest, proposed many useful new features

  • XHR1.0
    • Only supports the transmission of text data, cannot upload files
    • There is no progress information when transmitting and receiving data
    • Properties and methods
      • readyState
      • responseText
      • onreadystatechange
      • open
      • send
      • status
      • setRequestHeader
  • XHR2.0
    • The time limit for HTTP requests can be set
    • You can use the FormData object to manage form data with files, and you can upload files
    • Can get the progress information of data transfer
    • Properties and methods
      • response
      • responseType
      • A series of new events such as onload (onprogress, onloadstart, onloadend)
      • timeout-timeout (set a few seconds to timeout)
      • ontimeout-timeout event
      • upload-upload action

9.0 Set HTTP request time limit

  • timeout-timeout in milliseconds
  • ontimeout-request timeout event
var btn = document.getElementById("btn");
btn.onclick = function () {
    
    
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function () {
    
    
        if (ajax.readystate == 4 && ajax.status == 200) {
    
    
            console.log(ajax.responseText);
        }
    }
    ajax.open("GET", "URL/api/st");
    ajax.send();

    // 超时时间, 单位是毫秒
    ajax.timeout = 2000;
    // 超时事件
    ajax.ontimeout = function () {
    
    
        alert('请求超时,请刷新重试');
    }
    // 超时后自动关闭本次ajax请求
}

9.1 Use onload new event

  • xhr.onload
    • 成功Triggered after request response
    • And it is triggered when xhr.readyState===4
    • You can use it instead of onreadystatechange event
// XHR2.0 新出onload方法
var btn = document.getElementById("btn");
btn.onclick = function () {
    
    
    var ajax = new XMLHttpRequest();
    // 1. 状态为4(收集完后台返回结果) - http状态200
    // 触发onload(替代onreadystatechange和判断)
    ajax.onload = function () {
    
    
        console.log(JSON.parse(ajax.responseText));
        console.log(ajax.response);
    }

    ajax.open("GET", "URL/api/getbooks");
    ajax.send();
}

9.2 Use of FormData

Content carrier for sending data from web front end to back end

Which one to choose GET/POST, the content type of POST depends on what the backend wants, what the frontend gives... Just match

// 好处: 可以一键收集表单的信息
var theBtn = document.getElementById("btn");
var theForm = document.getElementById("myForm");
theBtn.onclick = function(ev){
    
    
    ev.preventDefault();
    var formData = new FormData(theForm); // 把form穿进去, 参数名和值会自动收集起来

    // 还可以自己往formData上拼接
    formData.append("a", 100);
    // 更多的方法可以看这里(一般用不上)https://developer.mozilla.org/zh-CN/docs/Web/API/FormData

    // 打印查看formData里的东西
    formData.forEach(function(value, key){
    
    
        console.log(value, key);
    })

    var ajax = new XMLHttpRequest();
    ajax.onload = function () {
    
    
        console.log(JSON.parse(ajax.responseText));
        console.log(ajax.response);
    }

    ajax.open("POST", "URL/api/upload/avatar"); // 表单提交一般用POST方式
    ajax.send(formData);

}

// 总结:
// jQ的方法 $("form标签").serialize() 原地返回结果 key=value&key=value的字符串(注意key指的每个表单标签name属性的值)
// 原生的 new FormData(原生form标签)  原地返回结果 是一个FormData对象(带有分割符的键值对格式)

Use attention

  • Instantiate the FormData object and pass in the DOM object of the form. The result will contain the data of the form
  • FormData also gets the value according to the name attribute of the form
  • Can collect file type information, serialize can only collect non-file name and value
  • For the drop-down box, the name is set to the select tag, and the value is set to the option tag;
  • For ajax submission, just submit the fd object directly, without converting it into query character form. ( xhr.send(fd))
  • No need to set the request header yourself; the XHR object will automatically set the Content-Type request header

The difference between POST content

  • application/x-www-form-urlencode (default)

Insert picture description here

  • below form/data
    Insert picture description here

Insert picture description here

Click on view source to see what the parameters really look like

Insert picture description here

9.3 Upload file-with progress bar (native)

Implementation process:

  1. Implement Ajax to submit FormData data
  2. Register the xhr.upload.onprogress event to monitor progress

Note that the upload progress uses the xhr.upload.onprogress event; the download progress uses the xhr.onprogress event;

<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传文件的按钮 -->
<button id="btnUpload">上传文件</button>

<!-- bootstrap 中的进度条 -->
<div class="progress" style="width: 500px; margin: 15px 10px;">
    <div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
        0%
    </div>
</div>

<br />
<!-- 3. img 标签,来显示上传成功以后的图片 -->
<img src="" alt="" id="img" width="800" />

<script>
    // 1. 上传按钮
    var btnUpload = document.querySelector('#btnUpload')
    // 2. 上传按钮 - 点击事件
    btnUpload.addEventListener('click', function () {
      // 3. 用户选择的文件列表
      var files = document.querySelector('#file1').files
      if (files.length <= 0) {
        return alert('请选择要上传的文件!')
      }

      // 4. 准备FormData对象 - 装载表单数据
      var fd = new FormData()
      fd.append('avatar', files[0])

      // 5. Ajax - 监听文件上传的进度 (upload上传, onprogress进度, 只要上传的进度改变就触发此事件)
      var xhr = new XMLHttpRequest()

      xhr.upload.onprogress = function (e) {
        if (e.lengthComputable) { // 是否具有可以计算的长度

          // 6. 计算出上传的进度 (e.loaded已上传字节数, e.total共要上传的字节数)
          var procentComplete = Math.ceil((e.loaded / e.total) * 100)
          console.log(procentComplete)
          // 动态设置进度条
          $('#percent').attr('style', 'width: ' + procentComplete + '%;').html(procentComplete + '%')
        }
      }

      xhr.open('POST', 'http://123.57.109.30:3006/api/upload/avatar')
      xhr.send(fd)

      xhr.onload = function () {
          var data = JSON.parse(xhr.responseText)
          if (data.status === 200) { // 后台返回的代码逻辑的状态码(而非http状态码)
            // 上传成功
            $('#percent').removeClass().addClass('progress-bar progress-bar-success');
            document.querySelector('#img').src = data.url
          } else {
            // 上传失败
            console.log('图片上传失败!' + data.message)
          }
      }
    })

9.4 Upload file-with loader (jQ)

$(function () {
    
    
    // 1. 监听到整个文档 - 有Ajax请求被发起了
    $(document).ajaxStart(function () {
    
    
        $('#loading').show()
    })

    // 2. 监听到整个文档 - 有Ajax完成的事件
    $(document).ajaxStop(function () {
    
    
        $('#loading').hide()
    })

    // 3. 点击发起 Ajax
    $('#btnUpload').on('click', function () {
    
    
        var files = $('#file1')[0].files
        if (files.length <= 0) {
    
    
            return alert('请选择文件后再上传!')
        }

        // 4. 准备表单容器
        var fd = new FormData()
        fd.append('avatar', files[0])

        // 发起 jQuery 的 Ajax 请求,上传文件
        $.ajax({
    
    
            method: 'POST',
            url: 'http://123.57.109.30:3006/api/upload/avatar',
            data: fd,
            processData: false,
            contentType: false,
            success: function (res) {
    
    
                console.log(res)
            }
        })
    })
})

10. Case-News List

  • The case diagram is as follows
    • Call the background interface to get news list data
    • Pull to the bottom to load more, if there is no more data (the background will return whether there is more), give a prompt (close the pull-down to load more methods)

Insert picture description here

10.0 Case-News List-Get Data

// 2. 格式化日期
Date.formatTime = function (date) {
    
    
    function padZero(n) {
    
    
        if (n < 10) {
    
    
            return '0' + n
        } else {
    
    
            return n
        }
    }
    // 把字符串格式的日期转换为日期对象
    var d = new Date(date)
    var year = padZero(d.getFullYear())
    var month = padZero(d.getMonth() + 1)
    var day = padZero(d.getDate())
    var hour = padZero(d.getHours())
    var minute = padZero(d.getMinutes())
    var second = padZero(d.getSeconds())
    return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
}

// 1. Ajax请求数据 - 铺设第一页数据
var nowPage = 1;
function loadNewsList() {
    
    
    $.ajax({
    
    
        url: "http://123.57.109.30:3006/api/news",
        data: {
    
     page: nowPage },
        type: "GET",
        success(res) {
    
    
            var arr = res.data;
            arr.forEach(function (obj, index) {
    
    
                var tagsArr = obj.tags.split(",");
                $("#news-list").append(`<div class="news-item">
<img class="thumb" src="http://123.57.109.30:3006${
      
      obj.img}" alt="">
<div class="right-box">
<h1 class="title">${
      
      obj.title}</h1>
<div class="tags">
<span>${
      
      tagsArr[0]}</span>
<span>${
      
      tagsArr[1]}</span>
<span>${
      
      tagsArr[2]}</span>
</div>
<div class="footer">
<div>
<span>${
      
      obj.source}</span>&nbsp;&nbsp;
<span>${
      
      Date.formatTime(obj.time)}</span>
</div>
<span>评论数:${
      
      obj.cmtcount}</span>
</div>
</div>
</div>`)
            })
        }
    })
}
loadNewsList();

10.1 Case-News List-Pull down to load more

// 3. 监测网页是否滚动到底部
$(document).on("scroll", function(){
    
    
    if ($(document).scrollTop() >= document.documentElement.scrollHeight - document.documentElement.clientHeight) {
    
    
        nowPage++;
        loadNewsList();
    }
})

10.2 Case-News List-Throttle Valve

// 3. 监测网页是否滚动到底部
var timer = null; // 保存定时器
$(document).on("scroll", function () {
    
    
    if (timer) return; // 如果有定时器再触发函数就回去不继续执行下面的

    timer = setTimeout(function () {
    
    
        if ($(document).scrollTop() >= document.documentElement.scrollHeight - document.documentElement.clientHeight) {
    
    
            nowPage++;
            loadNewsList();
        }

        timer = null;
    }, 300);
})

10.3 Throttle function

// 3. 监测网页是否滚动到底部
$(document).on("scroll", throttle(function () {
    
    
    if ($(document).scrollTop() >= document.documentElement.scrollHeight - document.documentElement.clientHeight) {
    
    
        nowPage++;
        loadNewsList();
    }
}, 300))

// 4. 定义节流函数
function throttle(fn, theTime) {
    
    
    return function () {
    
    
        if (fn.timer) return;
        fn.timer = setTimeout(() => {
    
    
            fn.call(this, ...arguments);
            fn.timer = null;
        }, theTime);
    }
}

If there are any shortcomings, please advise, to
be continued, continue to update!
Make progress together!

Guess you like

Origin blog.csdn.net/qq_40440961/article/details/111596553