11-Ajax詳解

Ajax的基本概念及使用

同步&異步

  • 同步:必須等待前面的任務(wù)完成,才能繼續(xù)后面的任務(wù);
  • 異步:不受當(dāng)前主要任務(wù)的影響。
  • 舉個(gè)例子:
  • 同步:我們?cè)阢y行排隊(duì)時(shí),只有等到你了,才能夠去處理業(yè)務(wù);
  • 異步:我們?cè)谂抨?duì)的時(shí)候,玩王者農(nóng)藥的先后順序是各不相關(guān)的。

異步更新網(wǎng)站

  • 當(dāng)我們?cè)L問(wèn)一個(gè)普通的網(wǎng)站時(shí),當(dāng)瀏覽器加載完:HTML、CSS、JS以后網(wǎng)站的內(nèi)容就固定了。如果網(wǎng)站內(nèi)容發(fā)生更改必須刷新頁(yè)面才能夠看到更新的內(nèi)容。

  • 網(wǎng)站內(nèi)容更新:常規(guī)的網(wǎng)站內(nèi)容更新,必須通過(guò)刷新才能顯示新內(nèi)容。

  • 異步更新:

  • 我們?cè)谠L問(wèn)新浪微博時(shí),當(dāng)你看到一大半了,會(huì)自動(dòng)幫我們加載更多的微博,同時(shí)之前的頁(yè)面并沒(méi)有刷新。

Ajax概念

  • 在不刷新頁(yè)面的情況下,“偷偷”的發(fā)送數(shù)據(jù)給服務(wù)器,通過(guò)發(fā)出http請(qǐng)求。

  • 在沒(méi)有學(xué)習(xí)Ajax以前,如果想要發(fā)出http請(qǐng)求(發(fā)出請(qǐng)求報(bào)文):

  • 頁(yè)面會(huì)刷新;

  • 后果:如果網(wǎng)速很慢,刷新頁(yè)面勢(shì)必會(huì)重新加載;造成不必要的時(shí)間浪費(fèi);

  • 一些極少量的信息想要提交給服務(wù)器,也沒(méi)有必要刷新整個(gè)頁(yè)面。

  • 寫(xiě)法:是通過(guò)js在瀏覽器端幫我們預(yù)定義的一個(gè)異步對(duì)象來(lái)完成的。

  • 事例:當(dāng)我們正在排隊(duì)的時(shí)候,可以通過(guò)手機(jī)去干一些其他的事情。

  • 在瀏覽器中,我們也能夠不刷新頁(yè)面,通過(guò)ajax的方式去獲取一些新的內(nèi)容,類似網(wǎng)頁(yè)有微博、朋友圈、郵箱等。

  • 單詞解釋:Asynchronous Javascript And XML(異步JavaScript和XML),他并不是憑空出現(xiàn)的新技術(shù),而是對(duì)于現(xiàn)有技術(shù)的結(jié)合:核心是js對(duì)象XMLHttpRequest

XMLHttpRequest

  • ajax使用的依舊是HTTP請(qǐng)求,那么讓我們來(lái)回憶一下一個(gè)完整的HTTP請(qǐng)求需要什么:
  • 請(qǐng)求的網(wǎng)址,方法get/post;
  • 提交請(qǐng)求內(nèi)容數(shù)據(jù)、請(qǐng)求主體等;
  • 接收響應(yīng)回來(lái)的內(nèi)容。
寫(xiě)Ajax的步驟
  • 先寫(xiě)html頁(yè)面,通過(guò)某種條件發(fā)出ajax請(qǐng)求;
  • 寫(xiě)在php頁(yè)面,處理發(fā)過(guò)來(lái)的請(qǐng)求;
  • 再回到瀏覽器異步對(duì)象的onreadystatechange事件中,去處理返回的內(nèi)容。
發(fā)送Ajax請(qǐng)求,使用的是js
五步使用法:
  • 1.創(chuàng)建異步對(duì)象:var ajaxObj = new XMLHttpRequest();
  • 2.使用open方法設(shè)置請(qǐng)求的參數(shù):
    • ajaxObj.open('get','xxx.php');
    • 參數(shù)1為請(qǐng)求的方法,參數(shù)2為請(qǐng)求的url;
  • 3.發(fā)送請(qǐng)求:(發(fā)送請(qǐng)求報(bào)文)
    • ajaxObj.send();
  • 4.注冊(cè)事件:(服務(wù)器返回響應(yīng)報(bào)文)
    • 狀態(tài)改變時(shí)就會(huì)調(diào)用,如果要在數(shù)據(jù)完成請(qǐng)求回來(lái)的時(shí)候才調(diào)用,我們需要手動(dòng)的寫(xiě)一些判斷的邏輯;
ajaxObj.onreadystatechange = function (){
        //為了保證數(shù)據(jù)完整回來(lái),我們一般會(huì)判斷兩個(gè)值
        if (ajaxObj.readyState==4 && ajaxObj.status==200){
            //在注冊(cè)事件中,獲取返回的內(nèi)容,并修改頁(yè)面的顯示
        }
}
  • 5.在注冊(cè)的事件中,獲取返回的內(nèi)容,并修改頁(yè)面的顯示。


    瀏覽器與服務(wù)器的關(guān)系
  • 示例代碼:GET(get的數(shù)據(jù),直接在請(qǐng)求的url中添加即可)
  • html中的代碼:
<body>
    <input type="text" class="user">
    <button>發(fā)送請(qǐng)求</button>
    <script>
        document.querySelector("button").onclick = function () {
            //1.創(chuàng)建異步對(duì)象
            var xhr = new XMLHttpRequest();

            //2.設(shè)置method、url等參數(shù)
            var userName = document.querySelector(".user").value;
            xhr.open("get","03-XMLHttpRequest.php?name="+userName);

            //3.發(fā)送數(shù)據(jù)
            xhr.send();

            //4.綁定事件
            xhr.onreadystatechange = function () {
                if (xhr.readyState==4 && xhr.status==200){
                    //5.在綁定事件中獲取返回的數(shù)據(jù),顯示頁(yè)面
                    console.log(xhr.responseText);
                }
            }
        }
    </script>
</body>
  • php中的代碼:
<?php
        echo $_GET['name'].",歡迎你";
?>
  • 示例代碼:POST
  • 有兩點(diǎn)不同
    1.發(fā)送的數(shù)據(jù)寫(xiě)在send方法中;
    2.必須要在open和send之間添加setRequestHeader("Content-type","application/x-www-form-urlencoded");
  • html中的代碼:
<body>
    <input type="text" class="user">
    <button>發(fā)送請(qǐng)求</button>
    <script>
        document.querySelector("button").onclick = function () {
            //1.創(chuàng)建異步對(duì)象
            var xhr = new XMLHttpRequest();

            //2.設(shè)置method、url等參數(shù)
            xhr.open("POST","03-XMLHttpRequest.php");

            //如果使用post發(fā)送數(shù)據(jù),必須要添加如下內(nèi)容,修改發(fā)送給服務(wù)器的請(qǐng)求報(bào)文的內(nèi)容。form表單使用post發(fā)送數(shù)據(jù)不需要設(shè)置,因?yàn)閒orm表單默認(rèn)會(huì)進(jìn)行轉(zhuǎn)換
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");

            //3.發(fā)送請(qǐng)求,發(fā)送請(qǐng)求的數(shù)據(jù)寫(xiě)在send方法中
            //格式 name=jiang & age=18
            var userName = document.querySelector(".user").value;
            xhr.send("name="+userName);

            //4.綁定事件
            xhr.onreadystatechange = function () {
                //5.在綁定事件里獲取數(shù)據(jù),展示頁(yè)面
                if (xhr.readyState==4 && xhr.status==200){
                    console.log(xhr.responseText);
                }
            }
        }
    </script>
</body>
  • php中的代碼:
<?php
        echo $_POST["name"].",你好";
?>
  • 實(shí)際開(kāi)發(fā)中,get和post的選取:
    由后臺(tái)程序員以文檔或者口頭形式告知;
    如果不考慮提交文件,那么get/post的作用基本一致,只是寫(xiě)法不同;
    自己寫(xiě)demo的時(shí)候,隨便選取哪一個(gè)使用。
練習(xí):異步切換明星頭像

XMLHttpRequest_API講解

創(chuàng)建XMLHttpRequest對(duì)象(兼容性寫(xiě)法):

  • 新版本瀏覽器:
var xml=new XMLHttpRequest();
  • IE5和IE6:
var xml=new ActiveXObject("Microsoft.XMLHTTP");
  • 考慮兼容性創(chuàng)建Ajax對(duì)象
var request ;
if(XMLHttpRequest){
        // 新式瀏覽器寫(xiě)法
        request = new XMLHttpRequest();
}else{
        //IE5,IE6寫(xiě)法
        request = new ActiveXObject("Microsoft.XMLHTTP");
}

發(fā)送請(qǐng)求:

方法 描述
open(method,url,async) 規(guī)定請(qǐng)求的類型、URL 以及是否異步處理請(qǐng)求。<ul><li>method:請(qǐng)求的類型;GET 或 POST;</li><li>url:文件在服務(wù)器上的位置;</li><li>async:true(異步)或 false(同步)</li></ul>
send(string) 將請(qǐng)求發(fā)送到服務(wù)器。string:僅用于 POST 請(qǐng)求

POST請(qǐng)求注意點(diǎn):

  • 如果想要像form表單提交數(shù)據(jù)那樣使用POST請(qǐng)求,需要使用XMLHttpRequest對(duì)象setRequestHeader()方法來(lái)添加HTTP頭。然后在send()方法中添加想要發(fā)送的數(shù)據(jù):
xmlhttp.open("POST","ajax_test.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Bill&lname=Gates");

onreadystatechange事件

  • 當(dāng)服務(wù)器給予我們反饋時(shí),我們需要實(shí)現(xiàn)一些邏輯
屬性 描述
onreadystatechange 存儲(chǔ)函數(shù)(或函數(shù)名),每當(dāng) readyState 屬性改變時(shí),就會(huì)調(diào)用該函數(shù)。
readyState 存有 XMLHttpRequest 的狀態(tài)。從 0 到 4 發(fā)生變化:<ul><li>0:請(qǐng)求未初始化;</li><li>1:服務(wù)器連接已建立;</li><li>2:請(qǐng)求已接收;</li><li>3:請(qǐng)求處理中;</li><li>4:請(qǐng)求已完成,且響應(yīng)已就緒。</li></ul>
status 200: "OK";404: 未找到頁(yè)面

服務(wù)器響應(yīng)內(nèi)容

  • 如果響應(yīng)的是普通字符串,使用responseText,如果響應(yīng)的是XML,使用responseXML
屬性 描述
responseText 獲得字符串形式的響應(yīng)數(shù)據(jù)。
responseXML 獲得 XML 形式的響應(yīng)數(shù)據(jù)。
服務(wù)器
  • Apache;
  • web服務(wù)端開(kāi)發(fā)的語(yǔ)言;
  • 設(shè)置訪問(wèn)的網(wǎng)站:
  • 設(shè)置網(wǎng)站根目錄;
  • 往網(wǎng)站的目錄中拷貝文件即可:
    • .html:如果存在該頁(yè)面,會(huì)原封不動(dòng)的返回給用戶;
    • .php:會(huì)將php中的代碼執(zhí)行完,將結(jié)果返回給瀏覽器。

php如何讀取文本數(shù)據(jù)

  • 目的:實(shí)現(xiàn)數(shù)據(jù)和邏輯代碼分離;
  • PHP之所以被稱為“最好的編程語(yǔ)言”:使用十分方便,基本上我們能夠想到的功能,都幫我們封裝成了方法:
file_get_contents(文件路徑);

Ajax數(shù)據(jù)傳輸XML

XML簡(jiǎn)介

  • XML:指可擴(kuò)展標(biāo)記語(yǔ)言EXtensible Markup Language,他設(shè)計(jì)的時(shí)候是用來(lái)傳遞數(shù)據(jù)的,雖然格式跟HTML類似.。
  • xml示例:下面是一個(gè)XML示例
<?xml version="1.0" encoding="UTF-8"?>
<singer>
<name>周杰倫</name>
<age>18</age>
<skill>途牛</skill>
</singer>
  • XML是純文本,這點(diǎn)跟HTML很像,所以我們可以用任何的文本編輯軟件去打開(kāi)編輯它。

XML語(yǔ)法

  • 雖然看起來(lái)跟HTML類似,但是XML的語(yǔ)法有些需要注意的,更為詳細(xì)的可以查閱:http://www.w3school.com.cn/xml/index.asp
  • XML聲明:第一行是XML的聲明,指定XML版本(1.0)以及使用的編碼(UTF-8萬(wàn)國(guó)碼):
<?xml version="1.0" encoding="UTF-8"?>
  • 自定義標(biāo)簽,XML中沒(méi)有默認(rèn)的標(biāo)簽,所有的標(biāo)簽都是我們自定義的;
  • 注:不要使用數(shù)字開(kāi)頭,不要使用中文。
<!-- 下列標(biāo)簽都是被允許的 -->
<fox></fox>
<name></name>
  • 雙標(biāo)簽XML中沒(méi)有單標(biāo)簽,都是雙標(biāo)簽
<haha>標(biāo)簽內(nèi)</haha>
  • 根節(jié)點(diǎn):XML中必須有一個(gè)根節(jié)點(diǎn),所有的子節(jié)點(diǎn)都放置在根節(jié)點(diǎn)下
<root>
  <name></name>
</root>
  • XML屬性:跟HTML一樣,XML的標(biāo)簽里面也能夠添加屬性type = 'text',但是不建議這樣用,而是使用標(biāo)簽的方式來(lái)表述內(nèi)容(下半部分代碼)
<!-- 使用屬性配合標(biāo)簽表述信息 -->
<person sex="female">
  <firstname>Anna</firstname>
  <lastname>Smith</lastname>
</person>
<!-- 使用標(biāo)簽來(lái)表述信息 -->
<person>
  <sex>female</sex>
  <firstname>Anna</firstname>
  <lastname>Smith</lastname>
</person>

XML解析

  • 因?yàn)閄ML就是標(biāo)簽,所以直接用解析Dom元素的方法解析即可;
  • html代碼:
<!DOCTYPE html>
<html lang="en">
<head>
      <meta charset="UTF-8">
      <title>Document</title>
</head>
<body>
      <person id='personXML'>
          <name>fox</name>
          <age>18</age>
          <skill>小花花</skill>
      </person>
</body>
</html>
  • 獲取方法:
<script type="text/javascript">
    var xmlObj = document.getElementById("personXML");
    var name = xmlObj.getElementsByTagName('name')[0].innerHTML;
    console.log(name);
</script>

PHP中設(shè)置Header

  • 在php中如果要使用xml傳輸數(shù)據(jù),需要使用header()設(shè)置返回的內(nèi)容為xml:
header('content-type:text/xml;charset=utf-8');
  • 從php中獲取xml內(nèi)容,html中的代碼如下:
<script type="text/javascript">
    document.querySelector('#getXML').onclick = function () {
        var ajax = new XMLHttpRequest();

        ajax.open('get','get_XMl.php');

        ajax.send();

        ajax.onreadystatechange = function () {
            if (ajax.readyState == 4 && ajax.status==200) {
                // 如果 返回的是 xml文件
                console.log(ajax.responseText);

                // 異步 對(duì)象中 有另外一個(gè)屬性 用來(lái)專門(mén)獲取 xml
                // xml對(duì)象 在瀏覽器端 就是一個(gè) document對(duì)象
                // 解析時(shí) 可以直接使用 querySelector 或者 getElementById等 document對(duì)象 有的語(yǔ)法
                console.log(ajax.responseXML);
                console.log(ajax.responseXML.querySelector('name').innerHTML);
                // 下面這個(gè) 頁(yè)面文檔對(duì)象,和ajax.responseXML一模一樣, 如果要獲取某個(gè)標(biāo)簽,使用同樣的方法
                console.log(window.document);
            }
        }
    }
</script>
  • php:
<?php
        header('content-type:text/xml;charset=utf-8');
        $text = file_get_contents("01-getFile-xml.xml");
        echo $text;
?>
  • xml:
<?xml version="1.0" encoding="UTF-8" ?>
<yijiang>
        <name>yijiang</name>
        <age>20</age>
        <sex>男</sex>
</yijiang>
Ajax中獲取xml:
  • 瀏覽器:

  • 通過(guò)xhr.responseXML獲取返回的xml值;

  • (如果通過(guò)xhr.responseText獲取,返回的是字符串)。

  • 服務(wù)器:

  • 準(zhǔn)備一個(gè)xml文件;

  • php中獲取xml文件內(nèi)容,并返回(注意要設(shè)置header:header('content-type:text/xml;charset=utf-8');

實(shí)際開(kāi)發(fā)中xml用的頻率不是很高,敲兩遍就可以了。
案例:重寫(xiě)明星頭像
  • html中:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>change</title>

    <style>
        table{
            width: 400px;
            margin: 20px auto;
            border: 1px solid #000;
        }
        td{
            border: 1px solid #000;
        }
        img{
            height: 200px;
            width: 200px;
        }
    </style>
</head>
<body>
    <script>
        //1.
        var xhr = new XMLHttpRequest();
        //2.
        xhr.open("get","change-xml.php");
        //3.
        xhr.send();
        //4.
        xhr.onreadystatechange = function () {
            //5.
            if (xhr.readyState==4 && xhr.status==200){
                var responseStars = xhr.responseXML;
                var stars = responseStars.querySelector("stars").children;
                console.log(stars[0].querySelector("name").innerHTML);
                var str = "<table>";
                for(var i=0; i<stars.length; i++){
                    str += "<tr>";
                    str += "<td>"+stars[i].querySelector("name").innerHTML+"</td>";
                    str += "<td>![]("+stars[i].querySelector("pic").innerHTML+")</td>";
                    str += "<td>"+stars[i].querySelector("description").innerHTML+"</td>";
                }
                str += "</table>";

                document.body.innerHTML = str;
            }
        }
    </script>
</body>
</html>
  • php中:
<?php
    header('content-type:text/xml;charset=utf-8');
    echo file_get_contents('change-xml.xml');
?>
  • xml中:
<?xml version="1.0" encoding="UTF-8" ?>
<stars>
    <star>
        <name>Angelababy</name>
        <age>30</age>
        <description>著名女演員</description>
        <pic>images/baby.jpg</pic>
    </star>
    <star>
        <name>mage</name>
        <age>16</age>
        <description>國(guó)際名模</description>
        <pic>images/mage.jpeg</pic>
    </star>
    <star>
        <name>wangge</name>
        <age>18</age>
        <description>大陸著名企業(yè)家</description>
        <pic>images/shuaige.jpeg</pic>
    </star>
</stars>

Ajax傳輸JSON

JSON語(yǔ)法

  • JSON(JavaScript Object Notation)
    一種字符串格式;
    是ECMAScript的子集,作用是進(jìn)行數(shù)據(jù)的交換;
    而且由于語(yǔ)法更為簡(jiǎn)潔,網(wǎng)絡(luò)傳輸以及機(jī)器解析都更為迅速;
    使用的最多,基本上所有的語(yǔ)言都有將JSON字符串轉(zhuǎn)化為該語(yǔ)言對(duì)象的語(yǔ)法。

  • 語(yǔ)法規(guī)則:

  • 數(shù)據(jù)在鍵值對(duì)中;

  • 數(shù)據(jù)由逗號(hào)分隔;

  • 花括號(hào)保存對(duì)象;

  • 方括號(hào)保存數(shù)組;

  • 總結(jié):屬性名必須使用雙引號(hào)包裹,屬性值(數(shù)組除外)必須使用雙引號(hào)包裹。

  • 數(shù)據(jù)類型:

  • 下列內(nèi)容,無(wú)論是鍵還是值 都是用雙引號(hào)包起來(lái):

    • 數(shù)字(整數(shù)或浮點(diǎn)數(shù));
    • 字符串(在雙引號(hào)中);
    • 邏輯值(true 或 false);
    • 數(shù)組(在方括號(hào)中);
    • 對(duì)象(在花括號(hào)中);
    • null。
  • 示例代碼:下部分代碼看起來(lái)類似于定義JavaScript對(duì)象

// 基本對(duì)象
{
      "name":"fox",
      "age":"18",
      "sex":"true",
      "car":null
}
// 數(shù)組
[
      {
          "name":"小小胡",
          "age":"1"
      },
      {
          "name":"小二胡",
          "age":"2"
      }
]

JSON解析

  • 接下來(lái)演示如何使用JavaScriptPHP對(duì)JSON進(jìn)行解析

  • 基本使用步驟:

JSON圖

JavaScript中
  • 使用JSON對(duì)象:
  • JSON.parse()方法:將JSON字符串轉(zhuǎn)化為JavaScript對(duì)象
  • JSON.stringify()方法:將JavaScript對(duì)象轉(zhuǎn)化為JSON字符串
  • 由于老式IE(8以下)瀏覽器中沒(méi)有JSON對(duì)象,通過(guò)導(dǎo)入JSON2.js框架即可解決,框架獲取地址為:JSON2.js_github地址(https://github.com/douglascrockford/JSON-js);
var Obj = {
  name:"fox",
  age:18,
  skill:"撩妹"
};
console.log(Obj);
// 將JavaScript對(duì)象格式化為JSON字符串
var jsonStr = JSON.stringify(Obj);
console.log(jsonStr);
// 將JSON字符串轉(zhuǎn)化為JavaScript對(duì)象
var jsonObj = JSON.parse(jsonStr);
console.log(jsonObj);
  • 使用eval()方法:使用eval()方法需要注意的是,需要將內(nèi)容使用()括號(hào)包裹起來(lái),如示例代碼:
<script type="text/javascript">
var jsonStr ={
  "name":"fox",
  "age":18,
  "skill":"撩妹"
};

var jsonObj = eval('('+jsonStr+')'); console.log(jsonObj);

</script>
PHP中
  • json_decode()方法:

  • json字符串轉(zhuǎn)化為php變量

  • json_encode()方法:

  • php變量轉(zhuǎn)化為json字符串

  • 示例代碼:

<?php
    header("Content-Type:text/html;charset=utf-8");
    // json字符串
    $jsonStr = '{"name":"yijiang","age":"18","skill":"歌神"}';
    // 字符串轉(zhuǎn)化為 php對(duì)象
      print_r(json_decode($jsonStr));

      echo "<br>";
      // php數(shù)組
      $arrayName = array('name' =>'littleFox' ,'age' => 13 );
      // php對(duì)象 轉(zhuǎn)化為 json字符串
      print_r(json_encode($arrayName));
 ?>
  • 輸出結(jié)果為:
stdClass Object ( [name] => yijiang [age] => 18 [skill] => 歌神 )
{"name":"littleFox","age":13}
解析JSON的完整寫(xiě)法:
  • html中:此時(shí)js中獲取返回的數(shù)據(jù)使用xhr.responseText
    <script>
        //1.
        var xhr = new XMLHttpRequest();
        //2.
        xhr.open("post","02-getFile-json.php");
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        //3.
        xhr.send();
        //4.
        xhr.onreadystatechange = function () {
            //5.
            if (xhr.readyState==4 && xhr.status==200){
                var person = JSON.parse(xhr.responseText);
                console.log(person);
                //Object {name: "jiang", age: "16", skill: "撩漢"}
                console.log(person.name);   //jiang
                console.log(person.age);    //16
            }
        }
    </script>
  • php中:
<?php
    echo file_get_contents("02-getFile-json.json");
?>
  • json文件:
{
    "name":"jiang",
    "age":"16",
    "skill":"撩漢"
}

Ajax工具函數(shù)封裝

原生Ajax寫(xiě)法

  • 原生使用Ajax主要分為五步,需要手寫(xiě)較多內(nèi)容,如果每次我們使用Ajax都需要手寫(xiě)一遍,較為浪費(fèi)時(shí)間,所以我們將公共代碼抽取,封裝為工具函數(shù)。

  • 五步使用法:

  • 建立XMLHTTPRequest對(duì)象

  • 使用open方法設(shè)置和服務(wù)器端交互的基本信息:

    • 設(shè)置提交的網(wǎng)址、數(shù)據(jù)以及post提交的一些額外內(nèi)容;
  • 使用send設(shè)置發(fā)送的數(shù)據(jù),開(kāi)始和服務(wù)器端交互:

    • 發(fā)送數(shù)據(jù);
  • 注冊(cè)事件:

    • 當(dāng)服務(wù)器回應(yīng)我們了,我們想要執(zhí)行什么邏輯;
  • 更新界面:

    • 在注冊(cè)的事件中,獲取返回的數(shù)據(jù),更新界面。
  • 示例代碼:GET:

  • get的數(shù)據(jù),直接在請(qǐng)求的url中添加即可;

<script type="text/javascript">
  // 創(chuàng)建XMLHttpRequest 對(duì)象
  var xml = new XMLHttpRequest();
  // 設(shè)置跟服務(wù)端交互的信息
  xml.open('get','01.ajax.php?name=fox');
  //發(fā)送數(shù)據(jù)
  xml.send(null);    // get請(qǐng)求這里寫(xiě)null即可,或者直接空
  // 接收服務(wù)器反饋
  xhr.onreadystatechange = function () {
      // 這步為判斷服務(wù)器是否正確響應(yīng)
      if (xhr.readyState == 4 && xhr.status == 200) {
          // 打印響應(yīng)內(nèi)容
          alert(xml.responseText);
      }
  };
</script>
  • 示例代碼:POST:
<script type="text/javascript">
  // 異步對(duì)象
  var xhr = new XMLHttpRequest();

  // 設(shè)置屬性
  xhr.open('post', '02.post.php' );

  // 如果想要使用post提交數(shù)據(jù),必須添加
  xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");

  // 將數(shù)據(jù)通過(guò)send方法傳遞
  xhr.send('name=fox&age=18');

  // 發(fā)送并接受返回值
  xhr.onreadystatechange = function () {
      // 這步為判斷服務(wù)器是否正確響應(yīng)
      if (xhr.readyState == 4 && xhr.status == 200) {
             alert(xhr.responseText);
      }
  };
</script>

抽取公共部分

  • 重復(fù)步驟分析:

  • 創(chuàng)建異步對(duì)象;

  • 異步對(duì)象open,send方法調(diào)用;

  • post方法需要添加HTTP協(xié)議頭文件;

  • 判斷Ajax響應(yīng)狀態(tài)。

  • 哪些部分是需要使用者自定義的:
    1. 提交方法;
    2. url地址;
    3. 數(shù)據(jù);
    4. Ajax請(qǐng)求成功調(diào)用方法;
    上述內(nèi)容,應(yīng)該是調(diào)用時(shí),由用戶傳入的。

//優(yōu)化,傳入一個(gè)對(duì)象作為參數(shù),對(duì)象中分別包含其它屬性:method,url,data,success
function ajax_tool(params) {
    //1.創(chuàng)建異步對(duì)象
    var xhr = new XMLHttpRequest();
    //2.3.
    if (params.method == "get"){
        if (params.data){
            params.url += "?";
            params.url += params.data;
        }
        //2.設(shè)置方法和url等
        xhr.open(params.method,params.url);
        //3.直接發(fā)送數(shù)據(jù)
        xhr.send();
    }else {
        //2.
        xhr.open(params.method,params.url);
        //設(shè)置請(qǐng)求頭
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        if (params.data){
            //3.如果有數(shù)據(jù),就發(fā)送數(shù)據(jù)
            xhr.send(params.data);
        }else {
            //如果沒(méi)有數(shù)據(jù)直接發(fā)送就好
            xhr.send();
        }
    }
    //4.注冊(cè)事件
    xhr.onreadystatechange = function () {
        //5.在事件中獲取數(shù)據(jù),并修改界面
        if (xhr.readyState==4 && xhr.status==200){
            success(xhr.responseText);
        }
    };
}
案例:聊天機(jī)器人

jQuery中的Ajax

JQuery中Ajax使用

$.get()方法

使用`get`方法取代復(fù)雜 $.ajax 向服務(wù)器獲取數(shù)據(jù);
請(qǐng)求成功時(shí)可調(diào)用回調(diào)函數(shù);
如果需要在出錯(cuò)時(shí)執(zhí)行函數(shù),請(qǐng)使用 $.ajax。
  • 參數(shù)列表
參數(shù) 描述
url 必需。規(guī)定將請(qǐng)求發(fā)送的哪個(gè) URL。
data 可選。待發(fā)送 Key/value 參數(shù)
success(response) 可選。規(guī)定當(dāng)請(qǐng)求成功時(shí)運(yùn)行的函數(shù)。額外的參數(shù):response - 包含來(lái)自請(qǐng)求的結(jié)果數(shù)據(jù)。
dataType 可選。規(guī)定預(yù)計(jì)的服務(wù)器響應(yīng)的數(shù)據(jù)類型。默認(rèn)地,jQuery 將智能判斷。可能的類型:"xml"、"html"、"text"、"script"、"json"、"jsonp"。
  • 關(guān)于dataType的說(shuō)明:預(yù)計(jì)從服務(wù)端獲取的數(shù)據(jù)類型,可以不寫(xiě),如果寫(xiě)了,寫(xiě)成json,jq內(nèi)部會(huì)幫我們進(jìn)行JSON.parse()的轉(zhuǎn)化。注意:

    • 如果寫(xiě)成json,并且服務(wù)端返回的就是json格式字符串,在回調(diào)函數(shù)中獲取的實(shí)參就是轉(zhuǎn)化完成的js對(duì)象,直接按照對(duì)象使用即可;
    • 如果寫(xiě)成json,但是返回的不是json格式的數(shù)據(jù),那么將會(huì)返回null。
  • 使用演示:

  • html代碼:

<script src="jquery.min.js"></script>
<script>
        $.get("01-jq-get.php",{name:"yijiang",des:"大帥比"},function (data) {
            console.log(data);
        });
</script>
  • php代碼:
<?php
        echo $_GET['name']."是一個(gè)".$_GET['des'];
?>
  • 結(jié)果:yijiang是一個(gè)大帥比

$.post方法

使用 post 請(qǐng)求功能以取代復(fù)雜 $.ajax;
請(qǐng)求成功時(shí)可調(diào)用回調(diào)函數(shù);
如果需要在出錯(cuò)時(shí)執(zhí)行函數(shù),請(qǐng)使用 $.ajax。
  • 參數(shù)
參數(shù) 說(shuō)明
url 必選。發(fā)送請(qǐng)求地址
data 可選。待發(fā)送 Key/value 參數(shù)
callback 可選。發(fā)送成功時(shí)回調(diào)函數(shù)
type 可選。返回內(nèi)容格式,xml, html, script, json, text, _default。
  • html代碼:
<script src="jquery.min.js"></script>
<script>
    $.post("02-jq-post.php",{name:"mage",des:"大美妞"},function (data) {
        console.log(data);
    });
</script>
  • php代碼:
<?php
    echo $_POST['name'].'是一個(gè)'.$_POST['des'];
?>
  • 結(jié)果:mage是一個(gè)大美妞

$.getJSON方法

在 jQuery 1.2 中,您可以通過(guò)使用JSONP形式的回調(diào)函數(shù)來(lái)加載其他網(wǎng)域的JSON數(shù)據(jù):
如 "myurl?callback=?"。jQuery 將自動(dòng)替換 ? 為正確的函數(shù)名,以執(zhí)行回調(diào)函數(shù)。
注意:此行以后的代碼將在這個(gè)回調(diào)函數(shù)執(zhí)行前執(zhí)行。
  • 參數(shù):
參數(shù) 說(shuō)明
url 必選,發(fā)送請(qǐng)求地址。
data 待發(fā)送 Key/value 參數(shù)。
callback 載入成功時(shí)回調(diào)函數(shù)。
  • html中代碼:
<script src="jquery.min.js"></script>
<script>
    $.getJSON('02-jq-post.php',function (data) {
        console.log(data);
    })
</script>
  • php中代碼:
<?php
    echo file_get_contents('xxx-json.json');
?>
  • json文件代碼:
{
    "name":"jiang",
    "age":"16",
    "skill":"撩漢"
}
  • 結(jié)果:Object {name: "jiang", age: "16", skill: "撩漢"}

格式化表單$('form').serialize()

我們?cè)谙蚍?wù)器提交數(shù)據(jù)時(shí),如果使用的是Ajax需要手動(dòng)將數(shù)據(jù)格式化,轉(zhuǎn)化成類似name=fox&age=18這樣的格式,jQuery已經(jīng)幫助我封裝好了一個(gè)格式化數(shù)據(jù)的方法。
  • 語(yǔ)法:$(selector).serialize() 直接可以將form中擁有name屬性的表單元素的字,進(jìn)行格式化。

  • 示例代碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>測(cè)試jq_serialize方法</title>
  <script type="text/javascript" src="./files/jquery.min.js"></script>
  <script type="text/javascript">
      $(function(){
          $("#getFormInfo").on("click",function(){
              var info = $("#testForm").serialize()
              console.log(info);
          })
      })
  </script>
</head>
<body>
  <form id="testForm">
      <input type="text" placeholder="您的姓名" name="userName">
      <input type="text" placeholder="您的愛(ài)好" name="userHabbit">
      <input type="text" placeholder="您最喜愛(ài)的食物" name="userHabbit">
  </form>
  <input type="button" value="格式化表單數(shù)據(jù)" id="getFormInfo">
</body>
</html>
  • 演示效果:userName=yijiang&userHabbit=swimming&userHabbit=meat

$.ajax({})方法

$.ajax()方法相比于前面的方法,擁有更為自由的定制性,可以替換$.get(),$.post()方法。
  • 參數(shù):
  • 在w3cSchool_$.ajax_Api(http://www.w3school.com.cn/jquery/ajax_ajax.asp) 中,關(guān)于參數(shù)只有下列一個(gè)。實(shí)際使用中,傳遞的是一個(gè)對(duì)象;
  • 而對(duì)象的屬性在頁(yè)面的下方(如圖可略)
參數(shù) 描述
settings 可選。用于配置 Ajax 請(qǐng)求的鍵值對(duì)集合。可以通過(guò) $.ajaxSetup() 設(shè)置任何選項(xiàng)的默認(rèn)值。
  • 回調(diào)函數(shù)
    如果要處理$.ajax()得到的數(shù)據(jù),則需要使用回調(diào)函數(shù)。beforeSend、error、dataFilter、success、complete。
    beforeSend:在發(fā)送請(qǐng)求之前調(diào)用,并且傳入一個(gè)XMLHttpRequest作為參數(shù)。
    error:在請(qǐng)求出錯(cuò)時(shí)調(diào)用。傳入XMLHttpRequest對(duì)象,描述錯(cuò)誤類型的字符串以及一個(gè)異常對(duì)象(如果有的話)
    dataFilter:在請(qǐng)求成功之后調(diào)用。傳入返回的數(shù)據(jù)以及"dataType"參數(shù)的值。并且必須返回新的數(shù)據(jù)(可能是處理過(guò)的)傳遞給success回調(diào)函數(shù)。
    success:當(dāng)請(qǐng)求之后調(diào)用。傳入返回后的數(shù)據(jù),以及包含成功代碼的字符串。
    complete:當(dāng)請(qǐng)求完成之后調(diào)用這個(gè)函數(shù),無(wú)論成功或失敗。傳入XMLHttpRequest對(duì)象,以及一個(gè)包含成功或錯(cuò)誤代碼的字符串。

  • 示例代碼:

  • 這里演示的是常用的屬性

$.ajax({
        url:'01.php',   //請(qǐng)求地址
        data:'name=fox&age=18',     //發(fā)送的數(shù)據(jù)
        type:'GET',     //請(qǐng)求的方式
        success:function (argument) {},     // 請(qǐng)求成功執(zhí)行的方法
        beforeSend:function (argument) {},  // 在發(fā)送請(qǐng)求之前調(diào)用,可以做一些驗(yàn)證之類的處理
        error:function (argument) {console.log(argument);},   //請(qǐng)求失敗調(diào)用
});
案例:注冊(cè)界面

模板插件

模版引擎簡(jiǎn)介

  • 我們?cè)谑褂?code>ajax請(qǐng)求數(shù)據(jù)時(shí),返回的如果是一個(gè)JSON格式的字符串,我們需要將其包裝到對(duì)應(yīng)的HTML代碼中,再添加到頁(yè)面上,才能看到效果。那么這個(gè)包裝得過(guò)程有沒(méi)有簡(jiǎn)單的方法呢?

  • 假設(shè)有如下數(shù)據(jù)(javascript中)

var obj = {
     name:"fox",
     age:18,
     skill:"賣萌"
};
  • 希望包裝為:
<ul>
  <li>姓名:fox</li>
  <li>年齡:18</li>
  <li>愛(ài)好:賣萌</li>
</ul>
  • 定義模板,替換:
  • 其間需要我們使用對(duì)象替換的位置為<%= 屬性名 %>部分,如果可以:讀取模板->傳入對(duì)象->完成替換->返回html代碼 實(shí)現(xiàn)這樣的步驟,那么就能夠完成我們的模板操作了
<ul>
  <li>姓名:<%= name %></li>
  <li>年齡:<%= age %></li>
  <li>愛(ài)好:<%= skill %></li>
</ul>

模版插件原理

我們定義一段文本作為模板,讀取文本,使用特殊的符號(hào)<%= 屬性名 %>,通過(guò)正則表達(dá)式找到這些特殊的符號(hào)進(jìn)行替換,是不是就實(shí)現(xiàn)了這樣的效果呢?

  • 定義正則表達(dá)式:
  • 想要匹配<%= 屬性名 %>, 我們可以定義如下正則(javascript中):
JS中的RegExp對(duì)象:
        創(chuàng)建:
            創(chuàng)建方法1: var reg = new RegExp("正則")
            創(chuàng)建方法2: var reg = /正則/;    推薦使用這種
        使用:
            reg.exec(string) 可以檢測(cè)并返回字符串
正則含義:
        <%:以 <% 開(kāi)始
        =\s* "="號(hào)之后有0個(gè)或多個(gè)空白字符
        ([^%>]+\S): 匹配除了%>以外的所有字符(至少1個(gè))
        \s*:0個(gè)或多個(gè)空白字符
        %>:以%>結(jié)束
var reg = /<%=\s*([^%>]+\S)\s*%>/;

基本使用

  • 定義好作為模板的文本;
  • 使用正則表達(dá)式進(jìn)行匹配替換即可。
// 定義文本
var str = '大家好,我叫<%= name %>,我今年<%= age %>,我的愛(ài)好為:<%= skill %>';
// 定義數(shù)據(jù)
var data = {
    name: 'jiang',
    age: 10,
    skill:'打籃球'
};

// 快速的創(chuàng)建方法,好處,直接使用 \ 即可 不需要考慮 轉(zhuǎn)義
var reg = /<%=\s*([^%>]+\S)\s*%>/;
// 返回的是一個(gè)對(duì)象(數(shù)組)
var match = null;

// 使用  while循環(huán) 進(jìn)行檢查,知道沒(méi)有匹配的內(nèi)容
while (match = reg.exec(str)){
    // 匹配到的字符串
    var mathString = match[0]
    // 子表達(dá)式匹配到的字符串
    var subString = match[1];
    // 打印文本內(nèi)容
    console.log("循環(huán)中:"+str);
    // 替換字符串的內(nèi)容
    str = str.replace(mathString,data[subString]);
}
console.log("循環(huán)完畢:"+str);
  • 演示結(jié)果為:
    循環(huán)中:大家好,我叫<%= name %>,我今年<%= age %>,我的愛(ài)好為:<%= skill %>
    循環(huán)中:大家好,我叫jiang,我今年<%= age %>,我的愛(ài)好為:<%= skill %>
    循環(huán)中:大家好,我叫jiang,我今年10,我的愛(ài)好為:<%= skill %>
    循環(huán)完畢:大家好,我叫jiang,我今年10,我的愛(ài)好為:打籃球

  • 常見(jiàn)的模板插件:

  • BaiduTemplate(百度開(kāi)發(fā)):http://tangram.baidu.com/BaiduTemplate/

  • ArtTemplate(騰訊開(kāi)發(fā)):https://github.com/aui/artTemplate

  • velocity.js(淘寶開(kāi)發(fā)):https://github.com/shepherdwind/velocity.js/

  • Handlebars:http://handlebarsjs.com/

ArtTemplate基本使用

  • 模板引擎的用法大同小異,ArtTemplate由于性能優(yōu)秀,這里我們演示ArtTemplate的用法:
  • 導(dǎo)入模板引擎:將下載好的ArtTemplate導(dǎo)入到頁(yè)面中:
<script type="text/javascript" src = "./files/template-native.js"></script>
  • 定義模板:
    <% %>:這樣的語(yǔ)法是定義邏輯表達(dá)式;
    <%=內(nèi)容 %>:這樣的語(yǔ)法為輸出表達(dá)式;
    注意:這里的模板type='text'如果寫(xiě)成javascript會(huì)執(zhí)行:
<script type="text" id = "templ01">
        <ul>
            <li><%=name %></li>
            <li><%=age %></li>
            <li><%=skill %></li>
            <li>
                <ul>favouriteFood
                <% for(var i = 0 ;i < favouriteFood.length;i++) {%>
                    <li><%=favouriteFood[i] %></li>
                <% } %>
                </ul>
            </li>
        </ul>
</script>
  • 定義對(duì)象;
  • 調(diào)用模板引擎的方法,傳入對(duì)象,我們可以使用template(模板id,數(shù)據(jù));
// 調(diào)用模板引擎的方法
var backHtml = template("templ01",data);
// 返回值就是填充好的內(nèi)容
  • 總結(jié):
    1.導(dǎo)入模板對(duì)象;
    2.定義模板;一般情況下,模板使用中,type必須寫(xiě),寫(xiě)成非javascript的內(nèi)容,若果留空,會(huì)默認(rèn)解析成為js,會(huì)報(bào)錯(cuò)。
    3.定義對(duì)象;
    4.調(diào)用模板引擎的方法,傳入對(duì)象;
    注意點(diǎn):
    一、如果出現(xiàn)template error錯(cuò)誤,一般模板出錯(cuò),去查找模板:1.for循環(huán)寫(xiě)了開(kāi)頭,沒(méi)有寫(xiě)結(jié)尾;2.for循環(huán)中的分隔符寫(xiě)成了逗號(hào)。
    二、只能接受對(duì)象,不能接受數(shù)組。

  • 示例:

<body>
    <script src="template-native.js"></script>
    <script type="text" id="temp">
        <% for(var i=0; i<people.length; i++){ %>
            <ul>
                <li><%= people[i].name %></li>
                <li><%= people[i].skill %></li>
            </ul>
        <% } %>

    </script>

    <script>
        var data = {
            people:[
                {name: "baby", skill: "演戲"},
                {name: "yijiang", skill: "負(fù)責(zé)帥"},
                {name: "mage", skill: "負(fù)責(zé)美"}
            ]
        };
        var backHtml = template("temp",data);
        document.write(backHtml);
    </script>
</body>
使用演示:luowang

同源以及跨域

同源

  • 同源策略是瀏覽器的一種安全策略,所謂同源是指域名協(xié)議端口完全相同。
URL 說(shuō)明 是否允許通信
http://www.a.com/a.js
http://www.a.com/b.js
同一域名下 允許
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
同一域名下不同文件夾 允許
http://www.a.com:8000/a.js
http://www.a.com/b.js
同一域名,不同端口 不允許
http://www.a.com/a.js
https://www.a.com/b.js
同一域名,不同協(xié)議 不允許
http://www.a.com/a.js
http://70.32.92.74/b.js
域名和域名對(duì)應(yīng)ip 不允許
http://www.a.com/a.js
http://script.a.com/b.js
主域相同,子域不同 不允許
http://www.a.com/a.js
http://a.com/b.js
同一域名,不同二級(jí)域名(同上) 不允許(cookie這種情況下也不允許訪問(wèn))
http://www.cnblogs.com/a.js
http://www.a.com/b.js
不同域名 不允許

跨域方案

  • 頂級(jí)域名相同的可以通過(guò)domain.name來(lái)解決,即同時(shí)設(shè)置 domain.name = 頂級(jí)域名(如example.com);

  • document.domain + iframe

  • window.name + iframe

  • location.hash + iframe

  • window.postMessage()

  • 瀏覽器中跨域請(qǐng)求方案:http://rickgray.me/2015/09/03/solutions-to-cross-domain-in-browser.html

JSONP

  • JSON with Padding其本質(zhì)是利用了html標(biāo)簽的src屬性標(biāo)簽具有可跨域的特性,實(shí)現(xiàn)跨域用的是script標(biāo)簽,由服務(wù)端返回一個(gè)預(yù)先定義好的Javascript函數(shù)的調(diào)用,并且將服務(wù)器數(shù)據(jù)以該函數(shù)參數(shù)的形式傳遞過(guò)來(lái),此方法需要前后端配合完成;
  • 使用script標(biāo)簽,<script src="xxx.php"></script>,默認(rèn)會(huì)發(fā)送一個(gè)get請(qǐng)求到對(duì)應(yīng)的php頁(yè)面;
  • 只能以GET方式請(qǐng)求
  • 注意只能夠通過(guò)get方法;
  • 服務(wù)端代碼:
<?php
    // echo "alert('天氣不錯(cuò)哦')";
    $callBack = $_GET['callback'];
    $arr = array(
        'name' =>'大帥比' ,
        'color' =>'red'
    );
    echo $callBack."(".json_encode($arr).")";
?>
  • 前端代碼:注意,域名不同
    • 核心是通過(guò)script標(biāo)簽src屬性提交get請(qǐng)求
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>

    <script type="text/javascript">
        function fn(data){
             console.log(data);
        }
    </script>

    <script type="text/javascript" src='http://www.section02.com/seciton02_jsonP.php?callback=fn'></script>
</head>
<body>
    <h1>區(qū)域1的頁(yè)面_jsonP演示</h1>
</body>
</html>
  • 如果我們定義的fn方法有形參,會(huì)將從服務(wù)器拿到的括號(hào)中的值傳遞給形參,并且如果傳遞過(guò)來(lái)的是json字符串,會(huì)自動(dòng)幫我們轉(zhuǎn)化為js對(duì)象。
jq已經(jīng)幫我們封裝好了jsonp的請(qǐng)求,直接使用即可:
  • dataType預(yù)期服務(wù)器返回的數(shù)據(jù)類型為jsonp;
  • "jsonp": JSONP 格式。使用 JSONP 形式調(diào)用函數(shù)時(shí),如 "myurl?callback=?" jQuery 將自動(dòng)替換 ? 為正確的函數(shù)名,以執(zhí)行回調(diào)函數(shù);
  • 如果需要給jsonp指定回調(diào)函數(shù):通過(guò)jsonpCallback為jsonp請(qǐng)求指定一個(gè)回調(diào)函數(shù)名。這個(gè)值將用來(lái)取代jQuery自動(dòng)生成的隨機(jī)函數(shù)名。這主要用來(lái)讓jQuery生成度獨(dú)特的函數(shù)名,這樣管理請(qǐng)求更容易,也能方便地提供回調(diào)函數(shù)和錯(cuò)誤處理。你也可以在想讓瀏覽器緩存GET請(qǐng)求的時(shí)候,指定這個(gè)回調(diào)函數(shù)名。
<script>
    function eatFood() {
        console.log("好好吃喲");
    }
</script>
<script src="../03-jq-ajax/jquery.min.js"></script>
<script >
    $.ajax({
        url:"01-jsonp-script.php",
        dataType:"jsonp",
        callback:eatFood()
    })
</script>

jQuery 的$.ajax()

  • 方法當(dāng)中集成了JSONP的實(shí)現(xiàn),可以非常方便的實(shí)現(xiàn)跨域數(shù)據(jù)的訪問(wèn)。

  • dataType: 'jsonp' 設(shè)置dataType值為jsonp即開(kāi)啟跨域訪問(wèn);

  • jsonp可以指定服務(wù)端接收的參數(shù)的“key”值,默認(rèn)為callback;

  • jsonpCallback可以指定相應(yīng)的回調(diào)函數(shù),默認(rèn)自動(dòng)生成

  • 示例代碼:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>

    <script type="text/javascript" src='jquery/jquery-3.0.0.min.js'></script>
</head>

<body>
<h1>區(qū)域1的頁(yè)面</h1>
    <input type="button" name="" onclick='sendAjax()' value="jquery區(qū)域請(qǐng)求">
</body>

</html>
<script type="text/javascript">
    function sendAjax(){
        $.ajax({
            url:'http://www.section02.com/sectcion02_jqJsonp.php',
            type:'post',
            dataType: 'jsonp',
            data:{name:'itt'},
            success:function(data){
                console.log(data);
            }
        })
    }
</script>

天氣預(yù)報(bào)

  • 一些平臺(tái)為我們提供了可以直接使用的接口,我們只需要按照他們提供的格式提交數(shù)據(jù)即可。

  • 百度車聯(lián)網(wǎng)api:http://developer.baidu.com/map/carapi-7.htm

  • 開(kāi)發(fā)者秘鑰ak:0A5bc3c4fb543c8f9bc54b77bc155724

瀑布流

什么是瀑布流?

  • 瀑布值得是從上往下流動(dòng)的水,并且水量也較大,瀑布流指的是內(nèi)容、信息,像瀑布一樣從上往下進(jìn)行排布。

  • 瀑布流:示例取自:堆糖網(wǎng):http://www.duitang.com/topics/

瀑布流實(shí)現(xiàn)原理

  • 瀑布流的核心為:

  • 寬度一致,高度參差不齊;

  • 新增行的內(nèi)容,優(yōu)先添加到最矮的下方。

  • 難點(diǎn):

  • 當(dāng)我們到了新一行時(shí),如何獲取上一行高度最小的行高?

  • 可以定義數(shù)組用來(lái)保存高度,新增了以后替換數(shù)組中原始的高度即可。

  • 實(shí)現(xiàn)技術(shù):

  • Ajax;

  • jq->Ajax請(qǐng)求;

  • 模板引擎->渲染頁(yè)面。

  • 知識(shí)點(diǎn):

  • 模板引擎;

  • jqajax請(qǐng)求;

  • php中,字符串和php對(duì)象的相互轉(zhuǎn)化;

  • jq插件寫(xiě)法:瀑布流的算法。

  • 補(bǔ)充:

  • 可以直接使用jq對(duì)象點(diǎn)出來(lái)的語(yǔ)法,除了jq本身,還有jq的插件,這里我們將瀑布流封裝成jq插件。

  • jq插件:

    • $.fn.extend,調(diào)用:$('xxx').fun;
    • $.extend,調(diào)用:$.fun;
    • 注:這里的fun跟我們定義的時(shí)候?qū)懙膶傩悦恢拢?/li>
    • jq插件命名一般建議使用jQuery.插件名.js格式;
    • 插件中的方法名建議和插件名一致。
// 為 jq 添加 插件
// 注冊(cè)完畢以后 使用 $("xxx").fun 使用
$.fn.extend({
    study:function () {
        console.log('我要好好學(xué)習(xí)了喲');
        // 在這個(gè)方法中 我們可以使用 $('選擇器')獲取到j(luò)q對(duì)象
        // this 就是我們獲取到的jq對(duì)象
        // 注意:容易搞混 jq對(duì)象跟dom對(duì)象 所以這里建議使用以$開(kāi)頭的this替代
        // 一看到 $_開(kāi)頭的,就知道是jq對(duì)象,防止跟dom對(duì)象弄混
        var $_this = this;
        $_this.css({backgroundColor:'yellow'});
        // jq有一個(gè)特點(diǎn)是 鏈?zhǔn)骄幊?        // 為了能夠鏈?zhǔn)骄幊?建議 return 當(dāng)前使用的jq對(duì)象
        return $_this;
    }
});
// 注冊(cè)完畢以后 使用$.fun 使用
$.extend({
    play:function(){
        console.log('我要玩游戲了喲');
    }
})
案例:(百度開(kāi)發(fā)平臺(tái))
  • 1.天氣展示;
  • 2.近期電影展示。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,316評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,481評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,241評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,939評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,697評(píng)論 6 409
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,182評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,247評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,406評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,933評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,772評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,973評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,516評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,209評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,638評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,866評(píng)論 1 285
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,644評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,953評(píng)論 2 373

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,781評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,636評(píng)論 25 708
  • 放暑假了我們決定去王奶奶家住兩天,王奶奶家位于澠池縣東北部偏遠(yuǎn)的小山村。 爸爸帶上媽媽,奶奶、王奶奶、弟弟和妹...
    07小石頭奧特曼閱讀 514評(píng)論 8 4
  • 雖然新家是北歐風(fēng)格 但我們的心里一直有著 愛(ài)國(guó)情懷 中式風(fēng)格也是我們的心頭好 說(shuō)不定等以后有錢(qián)了 等我們年老了 我...
    PWong閱讀 255評(píng)論 0 0
  • 冬天時(shí)用reveal還是1.X版本。這周發(fā)現(xiàn)已經(jīng)出來(lái)reveal 4了,用原來(lái)的方法配置已經(jīng)失效了。書(shū)歸正傳: s...
    知行合一認(rèn)知升級(jí)閱讀 2,244評(píng)論 2 27