進(jìn)階12-ajax

1.ajax 是什么?有什么作用副砍?
Ajax是Asynchronous JavaScript and XML的縮寫衔肢,這一技術(shù)能夠向服務(wù)器請求額外的數(shù)據(jù)而無需卸載整個(gè)頁面,會帶來良好的用戶體驗(yàn)豁翎。傳統(tǒng)的HTTP請求流程大概是這樣的:

  • 瀏覽器向服務(wù)器發(fā)送請求
  • 服務(wù)器根據(jù)瀏覽器傳來數(shù)據(jù)生成response
  • 服務(wù)器把response返回給瀏覽器
  • 瀏覽器刷新整個(gè)頁面顯示最新數(shù)據(jù)
  • 這個(gè)過程是同步的角骤,順序執(zhí)行

異步數(shù)據(jù)傳輸(HTTP 請求)從服務(wù)器獲取數(shù)據(jù)
無需重新加載頁面
通過DOM操作網(wǎng)頁部分更新
網(wǎng)頁沒有緩存
有安全問題

2.

  • 前后端開發(fā)聯(lián)調(diào)需要注意哪些事情?
1:get/post;    //請求類型
2./loadMore;    //接口位置
3.{
index: 3,    //請求的數(shù)組的序號和長度
length: 5
};    
4.['new1', 'news2'...'news5'];    //需要的數(shù)據(jù)心剥,JSON格式的數(shù)組
  • 后端接口完成前如何 mock 數(shù)據(jù)邦尊?
    1.自己模擬數(shù)據(jù)來進(jìn)行MOCK;
    2.使用server-mock或mock.js搭建模擬服務(wù)器优烧,進(jìn)行模擬測試蝉揍;
    3.使用XAMPP等工具,編寫PHP文件來進(jìn)行測試畦娄。
xhr.open('get', '/loadmore?index='+pageIndex+'&length=5', true)    
                      /*生成請求
                       *將接口和數(shù)據(jù)的要求
                       *通過字符串拼接出來
                       */
xhr.send()            /*發(fā)送

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

                           /* 
var isDataArrive = true     * 添加一個(gè)變量來記錄數(shù)據(jù)到來狀態(tài)
                            * 初始狀態(tài)為true
                            */
btn.addEventListener('click', function(){
  if(!isDataArrive){
  return;
  }
  xhr.onreadystatechange = function(){
  ...
    if(xhr.readyState === 4){
    ...                       /* 
   isDateArrive = true         * 在onreadystatechange事件變?yōu)?之后  
   }                           * 表示請求的數(shù)據(jù)正常生成
 }                             */
                          
  xhr.open()
  xhr.send()              /* 
                           * 到達(dá)這里表示數(shù)據(jù)已正常到來
  isDateArrive = false     * 狀態(tài)改變--->false
                           * 之后重復(fù)點(diǎn)擊不會再生成請求發(fā)送
                           */
 
})

4.封裝一個(gè) ajax 函數(shù)熙卡,能通過如下方式調(diào)用杖刷。后端在本地使用server-mock來 mock 數(shù)據(jù)

//ajax封裝
function ajax(opts){
            opts.success = opts.success || function(){};    //該項(xiàng)內(nèi)容用戶沒有輸入則設(shè)置默認(rèn)
            opts.error = opts.error || function(){};                                             
            opts.dataType = opts.dataType || 'json';
            opts.data = opts.data || {};
            var dataStr = '';
            for (var key in opts.data){
                dataStr += key + '=' + opts.data[key] + '&'
            }                               
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function(){
                if (xmlhttp.readyState == 4) {
                    if(xmlhttp.status == 200 || xmlhttp.status ==304) {
                        if(opts.dataType === 'text'){
                            opts.success(xmlhttp.responseText);
                        }
                        if(opts.dataType === 'json'){
                            var json = JSON.parse(xmlhttp.responseText);
                            opts.success(json)
                        }
                    }else{
                        opts.error()
                    }
                }
            }
            dataStr = dataStr.substr(0,dataStr.length-1);

            if (opts.type.toLowerCase() === 'post') {
                xmlhttp.open(opts.type, opts.url,true);
                xmlhttp.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
                xmlhttp.send();
            }
        }
    document.querySelector('#btn').addEventListener('click', function(){
        ajax({
            url: '/login',   //接口地址
            type: 'get',               // 類型get
            data: {
                username: 'xiaoming',
                password: 'abcd1234'
            },
            success: function(ret){
                console.log(ret);       // {status: 0}
            },
            error: function(){
               console.log('出錯了')
            }
        })
    });

5.
加載更多

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
    <style type="text/css">
        ul,li{
            margin: 0;
            padding: 0;
        }
        li:hover{
            background-color: #6ff;
            color: #fff;
        }
        .btn{
            display:block;
            margin: 10px auto;
            text-decoration: none;
            color: #fff;
            background: #6ea;
            width: 100px;
            padding: 10px;
            line-height: 30px;
            font-size: 18px;
            text-align: center;
        }
        #ct>li{
            padding: 10px;
            margin: 10px 0;
            border: 1px solid #ccc;
        }
    </style>
<body>
    <ul id="ct">
        <li>內(nèi)容1</li>
        <li>內(nèi)容2</li>
        
    </ul>
    <a href="#" id="load-more" class="btn">加載更多</a>
    <script type="text/javascript">
        var btn = document.querySelector(".btn")
        var ct = document.querySelector("#ct")
        var pageIndex = 3
        var isDataArrive = true

        btn.addEventListener('click',function(e){
            e.preventDefault()
            if(!isDataArrive){
                return;
            }
            var xhr = new XMLHttpRequest()
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status === 200 || xhr.status === 304){
                        var results = JSON.parse(xhr.responseText)
                        console.log(results)
                        var fragment = document.createDocumentFragment()
                        for (var i = 0;i<results.length;i++){
                            var node = document.createElement('li')
                            node.innerText = results[i]
                            fragment.appendChild(node)
                        }
                        ct.appendChild(fragment)
                        pageIndex = pageIndex + 5
                    }else{
                        console.log('出錯了')
                    }
                    isDataArrive = true
                }
            }
            xhr.open('get','/loadMore?index='+pageIndex+'&length=5',true)
            xhr.send()
            isDataArrive = false
        })

    </script>
</body>
</html>


//router.js
app.get('/loadMore', function(req, res){
    var curIdx = req.query.index
    var len = req.query.length
    var data = []
    for(var i =0; i<len; i++){
        data.push('內(nèi)容' + (parseInt(curIdx) + i) )
    }
    setTimeout(function(){
        res.send(data);
    },5000)
    // res.send(data);
});
//完整的ajax封裝
<script>
var btn = document.querySelector(".btn")
var ct = document.querySelector("#ct")
var pageIndex = 3
var isDataArrive = true  //上鎖

btn.addEventListener('click',function(e){
    e.preventDefault()
    if(!isDataArrive) return;
    
    load(function(e){
        renderPage(e)
        pageIndex = pageIndex + 5
        isDataArrive = true  //解鎖
    })
    isDataArrive = false  //加鎖
})
function load(callback){
     ajax({
        url:'/loadMore',
        type: 'get',
        dataType: 'json',
        data: {
            index: pageIndex,
            length: 5
        },
        success: callback,  //callback 是一個(gè)函數(shù),得到的參數(shù)傳給e
        error: function(){
            console.log('error');
        }
    })
}
function renderPage(text){
    var fragment = document.createDocumentFragment()
        for (var i = 0;i<text.length;i++){
            var node = document.createElement('li')
            node.innerText = text[i]
            fragment.appendChild(node)
        }
        ct.appendChild(fragment)
}


function ajax(opts){
        opts.success = opts.success || function(){};    //該項(xiàng)內(nèi)容用戶沒有輸入則設(shè)置默認(rèn)的匿名函數(shù)
        opts.error = opts.error || function(){};                                              
        opts.dataType = opts.dataType || 'json';
        opts.data = opts.data || {};
        var dataStr = '';
        for (var key in opts.data){
            dataStr += key + '=' + opts.data[key] + '&'
        }                                
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function(){
            if (xmlhttp.readyState == 4) {
                if(xmlhttp.status == 200 || xmlhttp.status ==304) {
                    if(opts.dataType === 'text'){
                        opts.success(xmlhttp.responseText);
                    }
                    if(opts.dataType === 'json'){
                        var json = JSON.parse(xmlhttp.responseText);
                        opts.success(json)
                    }
                }else{
                    opts.error()
                }
            }
        }
        dataStr = dataStr.substr(0,dataStr.length-1);

        if (opts.type.toLowerCase() === 'post') {
            xmlhttp.open(opts.type, opts.url,true);
            xmlhttp.setRequestHeader('contengt-type', 'application/x-www-form-urlencoded')
            xmlhttp.send(dataStr);  //post的傳遞請求方式
        }
        if (opts.type.toLowerCase() === 'get') {
            xmlhttp.open(opts.type, opts.url+'?'+dataStr,true);
            xmlhttp.send();
        }
    }


        </script>
gif001.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驳癌,一起剝皮案震驚了整個(gè)濱河市挺勿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喂柒,老刑警劉巖不瓶,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異灾杰,居然都是意外死亡蚊丐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門艳吠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麦备,“玉大人,你說我怎么就攤上這事×莞荩” “怎么了黍匾?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長呛梆。 經(jīng)常有香客問我锐涯,道長,這世上最難降的妖魔是什么填物? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任纹腌,我火速辦了婚禮,結(jié)果婚禮上滞磺,老公的妹妹穿的比我還像新娘升薯。我一直安慰自己,他們只是感情好击困,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布涎劈。 她就那樣靜靜地躺著,像睡著了一般阅茶。 火紅的嫁衣襯著肌膚如雪责语。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天目派,我揣著相機(jī)與錄音,去河邊找鬼胁赢。 笑死企蹭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的智末。 我是一名探鬼主播谅摄,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼系馆!你這毒婦竟也來了送漠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤由蘑,失蹤者是張志新(化名)和其女友劉穎闽寡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尼酿,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爷狈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了裳擎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涎永。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出羡微,到底是詐尸還是另有隱情谷饿,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布妈倔,位于F島的核電站博投,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏启涯。R本人自食惡果不足惜贬堵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望结洼。 院中可真熱鬧黎做,春花似錦、人聲如沸松忍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸣峭。三九已至宏所,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摊溶,已是汗流浹背爬骤。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莫换,地道東北人霞玄。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像拉岁,于是被迫代替她去往敵國和親坷剧。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容