js__Ajax__實(shí)踐

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

  • Ajax是Asynchronous JavaScript and XML的縮寫,這一技術(shù)能夠向服務(wù)器請(qǐng)求額外的數(shù)據(jù)而無需卸載整個(gè)頁面.

  • AJAX 在瀏覽器與 Web 服務(wù)器之間使用異步數(shù)據(jù)傳輸(HTTP 請(qǐng)求)從服務(wù)器獲取數(shù)據(jù),這里的異步是指脫離當(dāng)前瀏覽器頁面的請(qǐng)求、加載等單獨(dú)執(zhí)行,這意味著可以在不重新加載整個(gè)網(wǎng)頁的情況下,通過JavaScript接受服務(wù)器傳來的數(shù)據(jù),然后操作DOM將新數(shù)據(jù)對(duì)網(wǎng)頁的某部分進(jìn)行更新,

  • Ajax是一種瀏覽器和服務(wù)器的通訊技術(shù),Ajax不是瀏覽器自帶功能

  • open()方法的第三個(gè)參數(shù)表示請(qǐng)求采用異步還是同步方式,默認(rèn)值為true–異步方式

  • 作用
    使用Ajax最直觀的感受是向服務(wù)器獲取新數(shù)據(jù)不需要刷新頁面等待了,良好的用戶體驗(yàn)

2: 前后端開發(fā)聯(lián)調(diào)需要注意哪些事情?后端接口完成前如何 mock 數(shù)據(jù)?

  • 注意點(diǎn):
  • 約定數(shù)據(jù):需要傳輸?shù)臄?shù)據(jù)以及數(shù)據(jù)類型;
  • 約定接口:接口名稱,請(qǐng)求和響應(yīng)的格式,請(qǐng)求的參數(shù)名稱,響應(yīng)的數(shù)據(jù)格式;
  • 約定方式 :是get還是post,后端用同樣的方式接收發(fā)送過來的數(shù)據(jù)
  • 前后端獨(dú)立開發(fā),前端向Mock Server發(fā)送請(qǐng)求,獲取模擬的數(shù)據(jù)進(jìn)行開發(fā)和測(cè)試
  • 如果接口修改了,Mock Server要同步修改
  • 如何 mock ?
    方法一:本地Mock Server做法:前端把Mock Server克隆到本地,開發(fā)的時(shí)候,開啟前端工程服務(wù)器和Mock Server,所有的請(qǐng)求都發(fā)向本地服務(wù)器,獲取到Mock數(shù)據(jù).
    方法二: 使用nodejs的express框架

3:點(diǎn)擊按鈕,使用 ajax 獲取數(shù)據(jù),如何在數(shù)據(jù)到來之前防止重復(fù)點(diǎn)擊?

  • 1.在請(qǐng)求數(shù)據(jù)方法前引入布爾變量如var isDataArrive = true,
    2.在綁定按鈕點(diǎn)擊請(qǐng)求數(shù)據(jù)事件的方法里的開頭做次判斷,如果發(fā)請(qǐng)求前有值(即isDataArrive = ture ),就return,不請(qǐng)求,因?yàn)樵?br> 3.在xhr.onreadystatechange方法里的判斷xhr.readystate的值===4的方法里引入布爾變量isDataArrive = true,
    4.在發(fā)送請(qǐng)求的方法xhr.send()后引入布爾變量isDataArrive = false.
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:封裝一個(gè) ajax 函數(shù),能通過如下方式調(diào)用。后端在本地使用server-mock來 mock 數(shù)據(jù)

<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)//配置參數(shù),這里 opts.url+query = '/login?username=xiaoming&password=abcd1234'
  xhr.send()//發(fā)生請(qǐng)求
}

//點(diǎn)擊事件
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,成功請(qǐng)求到的內(nèi)容             
        },
        error: function () {
            console.log('出錯(cuò)了')
        }
    })
});

</script>




5:實(shí)現(xiàn)加載更多的功能,效果范例,后端在本地使用server-mock來模擬數(shù)據(jù)

  • 效果
使用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  //當(dāng)前要加載的數(shù)據(jù)的序號(hào)
  var len = 5   // 每次加載多少個(gè)數(shù)據(jù)
  var isLoading = false  //狀態(tài)鎖,用于判斷是否在加載數(shù)據(jù)


  //點(diǎn)擊事件
  btn.addEventListener('click', function (e) {
    e.preventDefault();  //防止點(diǎn)擊 a 鏈接頁面跳到頂部

    if (isLoading) {
      return   //如果正在請(qǐng)求數(shù)據(jù),那這次點(diǎn)擊什么都不做
    }

    //執(zhí)行到這里說明 沒有正在發(fā)出的請(qǐng)求,那后面就可以發(fā)請(qǐng)求
    ajax('/loadMore', {
      idx: curIndex,
      len: len
    }, function (data) {
      appendData(data)
      isLoading = false   //數(shù)據(jù)到來之后 解
      curIndex = curIndex + len  //修改序號(hào),下次要數(shù)據(jù)就從新序號(hào)開始要
      console.log(curIndex)
    })
    isLoading = true   //發(fā)請(qǐng)求之前做個(gè)標(biāo)記加鎖

  })


  //封裝的函數(shù)
  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請(qǐng)求成功,就會(huì)觸發(fā)xhr.onreadystatechange和xhr.onload兩個(gè)事件。 那么我們到底要將成功回調(diào)注冊(cè)在哪個(gè)事件中呢?我傾向于 xhr.onload事件,因?yàn)閤hr.onreadystatechange是每次xhr.readyState變化時(shí)都會(huì)觸發(fā),而不是xhr.readyState=4時(shí)才觸發(fā)
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
        onSuccess(JSON.parse(this.response))//this = xhr對(duì)象   this.response 是 responseText
      } else {
        onError && onError()
      }
    }
  }



  //封裝函數(shù),data 為 JSON.parse(this.response)即響應(yīng)內(nèi)容
  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('出錯(cuò)了')
  }

</script>

后端部分:router.js

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

    var curIdx = req.query.idx//通過query去拿,這里的idx對(duì)應(yīng)前端js發(fā)生請(qǐng)求的參數(shù)idx
    var len = req.query.len
    var data = []

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

    res.send(data);
});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ajax 是什么?有什么作用? AJAX的全稱是Asynchronous JavaScript and XML...
    hahahahaqwert閱讀 302評(píng)論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評(píng)論 19 139
  • AJAX 原生js操作ajax 1.創(chuàng)建XMLHttpRequest對(duì)象 var xhr = new XMLHtt...
    碧玉含香閱讀 3,569評(píng)論 0 7
  • 大家好,我是IT修真院深圳分院第3期的學(xué)員,一枚正直純潔善良的前端程序員,今天給大家分享一下,修真院官網(wǎng)前端工程師...
    大大頭大閱讀 8,090評(píng)論 1 72
  • 今天起了個(gè)大早,6點(diǎn)就出發(fā)去某市婦幼。寶媽老是說這兩天感覺不到寶寶胎動(dòng),嚇得我還是趕緊去醫(yī)院看看。 話說這市婦幼,...
    拉格朗日閱讀 199評(píng)論 0 0

友情鏈接更多精彩內(nèi)容