js__Ajax__实践

2017-05-09  本文已影响31人  好奇而已

1: ajax 是什么?有什么作用?

2: 前后端开发联调需要注意哪些事情?后端接口完成前如何 mock 数据?

3:点击按钮,使用 ajax 获取数据,如何在数据到来之前防止重复点击?

var check = true;
btn.addEventListener("click",function(){
    if(!check){
      return;
    }
    var xhr=new XMLHttpRequest()
    xhr.onreadystatechange=function(){
      if(xhr.readyState==4&&(xhr.status==200||xhr.status==304)){
          console.log(xhr.response);
          check = true;
      }   
    }
    xhr.open(method,url,true);
    xhr.send();
    check=false
})

4:封装一个 ajax 函数,能通过如下方式调用。后端在本地使用server-mock来 mock 数据

<script>
//封装的方法
function ajax(opts){
  var xhr = new XMLHttpRequest()
  xhr.onreadystatechange = function(){
      if(xhr.readyState === 4){
          if(xhr.status === 200 || xhr.status === 304){
              var results = JSON.parse(xhr.responseText)
              opts.success('results')
          }else{
              opts.error()
          }
      }
  }
  var query = '?'
  for (key in opts.data){
      query += key + '=' + opts.data[key] + '&'
      //query = query + key + '=' + opts.data[key] + '&'
      //?username=xiaoming& 遍历第一次
      //?username=xiaoming&password=abcd1234& 第二次
  }

  query = query.substr(0, query.length-1)//去除最后一位的&--->?username=xiaoming&password=abcd1234
  xhr.open(opts.type, opts.url+query, true)//配置参数,这里 opts.url+query = '/login?username=xiaoming&password=abcd1234'
  xhr.send()//发生请求
}

//点击事件
document.querySelector('#btn').addEventListener('click', function () {
    ajax({
        url: '/login',//接口地址 
        type: 'get', // 类型, post 或者 get, 
        data: {
            username: 'xiaoming',
            password: 'abcd1234'
        },
        success: function (ret) {
            console.log(ret); //ret为xhr.responseText,成功请求到的内容             
        },
        error: function () {
            console.log('出错了')
        }
    })
});

</script>




5:实现加载更多的功能,效果范例,后端在本地使用server-mock来模拟数据

使用Ajax加载更多

HTML__CSS部分

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>
    加载更多
  </title>
  <style>
    ul,
    li {
      margin: 0;
      padding: 0
    }

    #ct li {
      list-style: none;
      border: 1px solid #ccc;
      padding: 10px;
      margin-top: 10px;
      cursor: pointer;
    }

    #load-more {
      display: block;
      margin: 10px auto;
      text-align: center;
      cursor: pointer;
    }

    .btn {
      display: inline-block;
      height: 40px;
      line-height: 40px;
      width: 80px;
      border: 1px solid #E27272;
      border-radius: 3px;
      text-align: center;
      text-decoration: none;
      color: #E27272;
    }

    .btn:hover {
      background: green;
      color: #fff;
    }

    #ct>li:hover {
      background-color: pink;
    }
  </style>
</head>

<body>
  <ul id="ct">
  </ul>
  <a id="load-more" class="btn" href="#">
      加载更多
    </a>
</body>
</html>

js部分

<script>
  var ct = document.querySelector('#ct')
  var btn = document.querySelector('#load-more')

  var curIndex = 0  //当前要加载的数据的序号
  var len = 5   // 每次加载多少个数据
  var isLoading = false  //状态锁,用于判断是否在加载数据


  //点击事件
  btn.addEventListener('click', function (e) {
    e.preventDefault();  //防止点击 a 链接页面跳到顶部

    if (isLoading) {
      return   //如果正在请求数据,那这次点击什么都不做
    }

    //执行到这里说明 没有正在发出的请求,那后面就可以发请求
    ajax('/loadMore', {
      idx: curIndex,
      len: len
    }, function (data) {
      appendData(data)
      isLoading = false   //数据到来之后 解
      curIndex = curIndex + len  //修改序号,下次要数据就从新序号开始要
      console.log(curIndex)
    })
    isLoading = true   //发请求之前做个标记加锁

  })


  //封装的函数
  function ajax(url, json, onSuccess, onError) {
    var xhr = new XMLHttpRequest()
    var arr = []
    for (key in json) {
      arr.push(key + '=' + json[key])
    }
    url += '?' + arr.join('&')
    xhr.open('get', url)
    xhr.send()

    xhr.onload = function () {//若xhr请求成功,就会触发xhr.onreadystatechange和xhr.onload两个事件。 那么我们到底要将成功回调注册在哪个事件中呢?我倾向于 xhr.onload事件,因为xhr.onreadystatechange是每次xhr.readyState变化时都会触发,而不是xhr.readyState=4时才触发
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
        onSuccess(JSON.parse(this.response))//this = xhr对象   this.response 是 responseText
      } else {
        onError && onError()
      }
    }
  }



  //封装函数,data 为 JSON.parse(this.response)即响应内容
  function appendData(data) {
    for (var i = 0; i < data.length; i++) {
      var child = document.createElement('li')
      child.innerText = data[i]
      ct.appendChild(child)
    }
  }

  function onError() {
    console.log('出错了')
  }

</script>

后端部分:router.js

app.get('/loadMore', function (req, res) {

    var curIdx = req.query.idx//通过query去拿,这里的idx对应前端js发生请求的参数idx
    var len = req.query.len
    var data = []

    for (var i = 0; i < len; i++) {
        data.push('头条' + (parseInt(curIdx) + i))
    }

    res.send(data);
});

上一篇下一篇

猜你喜欢

热点阅读