亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

關(guān)于ajax學(xué)習(xí)筆記

YancyYe / 2615人閱讀

摘要:請(qǐng)求主體上行請(qǐng)求,有頭部主體。如何避免緩存問題方法隨機(jī)數(shù)隨機(jī)數(shù),我們不要只要小數(shù)點(diǎn)后面的數(shù)字上面就拼接一個(gè)隨機(jī)字符串,保證每次不一樣方法時(shí)間戳從年月日到這一刻的毫秒數(shù)。

一、什么是AJAX,為什么要使用Ajax(請(qǐng)談一下你對(duì)Ajax的認(rèn)識(shí))

ajax全稱Asynchronous JavaScript and XML(異步的javascript和XML),為什么會(huì)有這么一種技術(shù)的出現(xiàn)呢,因?yàn)榍岸藭r(shí)常會(huì)有這樣的需求,我們只要局部刷新,不需要整一個(gè)刷新的時(shí)候,便催生了這樣的技術(shù)。

在 Ajax應(yīng)用中信息是通過XML數(shù)據(jù)或者字符串在瀏覽器和服務(wù)器之間傳遞的(json字符串居多)

在瀏覽器端通過XMLHttpRequest對(duì)象的responseXMl屬性,得到服務(wù)器端響應(yīng)的XML數(shù)據(jù)。

AJAX優(yōu)點(diǎn):

最大的一點(diǎn)是頁面無刷新,用戶的體驗(yàn)非常好。

使用異步方式與服務(wù)器通信,具有更加迅速的響應(yīng)能力。

可以把以前一些服務(wù)器負(fù)擔(dān)的工作轉(zhuǎn)嫁到客戶端,利用客戶端閑置的能力來處理,減輕服務(wù)器和帶寬的負(fù)擔(dān),節(jié)約空間和寬帶租用成本。并且減輕服務(wù)器的負(fù)擔(dān),ajax的原則是“按需取數(shù)據(jù)”,可以最大程度的減少冗余請(qǐng)求,和響應(yīng)對(duì)服務(wù)器造成的負(fù)擔(dān)。

基于標(biāo)準(zhǔn)化的并被廣泛支持的技術(shù),不需要下載插件或者小程序。

AJAX缺點(diǎn):

ajax不支持瀏覽器back按鈕。

安全問題 AJAX暴露了與服務(wù)器交互的細(xì)節(jié)。

對(duì)搜索引擎的支持比較弱。

破壞了程序的異常機(jī)制。

不容易調(diào)試。

AJAX應(yīng)用和傳統(tǒng)Web應(yīng)用有什么不同?

傳統(tǒng)的web前端與后端的交互中,瀏覽器直接訪問Tomcat的Servlet來獲取數(shù)據(jù)。Servlet通過轉(zhuǎn)發(fā)把數(shù)據(jù)發(fā)送給瀏覽器。

當(dāng)我們使用AJAX之后,瀏覽器是先把請(qǐng)求發(fā)送到XMLHttpRequest異步對(duì)象之中,異步對(duì)象對(duì)請(qǐng)求進(jìn)行封裝,然后再與發(fā)送給服務(wù)器。服務(wù)器并不是以轉(zhuǎn)發(fā)的方式響應(yīng),而是以流的方式把數(shù)據(jù)返回給瀏覽器

XMLHttpRequest異步對(duì)象會(huì)不停監(jiān)聽服務(wù)器狀態(tài)的變化,得到服務(wù)器返回的數(shù)據(jù),就寫到瀏覽器上【因?yàn)椴皇寝D(zhuǎn)發(fā)的方式,所以是無刷新就能夠獲取服務(wù)器端的數(shù)據(jù)】

AJAX是異步執(zhí)行的,如圖所示,異步執(zhí)行不會(huì)阻塞.

二、ajax 的執(zhí)行過程

創(chuàng)建XMLHttpRequest對(duì)象,也就是創(chuàng)建一個(gè)異步調(diào)用對(duì)象

創(chuàng)建一個(gè)新的HTTP請(qǐng)求,并指定該HTTP請(qǐng)求的方法、URL及驗(yàn)證信息

設(shè)置響應(yīng)HTTP請(qǐng)求狀態(tài)變化的函數(shù)

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

獲取異步調(diào)用返回的數(shù)據(jù)

使用JavaScript和DOM實(shí)現(xiàn)局部刷新

基本示例:

//創(chuàng)建 XMLHttpRequest 對(duì)象
var ajax = new XMLHttpRequest();
// 規(guī)定請(qǐng)求的類型、URL 以及是否異步處理請(qǐng)求。
ajax.open("GET",url,true);
//發(fā)送信息至服務(wù)器時(shí)內(nèi)容編碼類型
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
//發(fā)送請(qǐng)求
ajax.send(null);  
//接受服務(wù)器響應(yīng)數(shù)據(jù)
ajax.onreadystatechange = function () {
    if (obj.readyState == 4 && (obj.status == 200 || obj.status == 304)) { 
    }
};

簡單應(yīng)用示例:

    oBtn.onclick = function () {
        //創(chuàng)建對(duì)象
        var xhr = getXMLHttpRequest();
        //當(dāng)xhr對(duì)象的readyState屬性發(fā)生改變的時(shí)候觸發(fā)
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) { //ajax的狀態(tài)4表示加載完成
                if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {// http的狀態(tài)是以上才算正常
                    pp.innerHTML = xhr.responseText;
                } else {
                    throw new Error("文件讀取錯(cuò)誤");
                }
            }
        }
        //open方法表示配置這次請(qǐng)求
        xhr.open("get", "test.txt", true);
        //發(fā)送請(qǐng)求
        //get請(qǐng)求中,沒有任何的上行主體的,所以寫null
        xhr.send(null);
    }

    //工廠函數(shù)(兼容瀏覽器)
    function getXMLHttpRequest() {
        if (window.XMLHttpRequest) {
            //高級(jí)瀏覽器,IE7,IE7+
            return new XMLHttpRequest();
        } else {
            //老版本瀏覽器,IE6
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
2.1 open()方法

xhr.open("get","test.txt",true);

調(diào)用open方法并不會(huì)真正發(fā)送請(qǐng)求,而只是啟動(dòng)一個(gè)請(qǐng)求以備發(fā)送。

它接受三個(gè)參數(shù):

要發(fā)送的請(qǐng)求的類型

請(qǐng)求的URL

表示是否異步的布爾值。

2.2 send()方法

如果要發(fā)送請(qǐng)求,用send()方法。

要發(fā)送特定的請(qǐng)求,需要調(diào)用send()方法。

它接受一個(gè)參數(shù):請(qǐng)求主體發(fā)送的數(shù)據(jù)。

如果不需要通過請(qǐng)求主體發(fā)送數(shù)據(jù),則必須傳入null,不能留空。

請(qǐng)求主體:HTTP上行請(qǐng)求,有頭部、主體。

一般來說,GET請(qǐng)求是只有頭部,沒有主體

而POST請(qǐng)求有請(qǐng)求主體。

一但調(diào)用send()方法,HTTP上行請(qǐng)求就將發(fā)出。

2.3 readyState屬性

表示“就緒狀態(tài)”

0 (uninitialized) 未初始化

1 (loading) XMLHttpRequest對(duì)象正在加載

2 (loaded) XMLHttpRequest對(duì)象加載完畢

3 (interactive) 正在傳輸數(shù)據(jù)

4 (complete) 全部完成

一般來說,只需要使用4狀態(tài)就可以了

只要這個(gè)屬性值發(fā)生了變化,就會(huì)觸發(fā)一個(gè)事件onreadystatechange事件,就可以使用xhr.onreadystatechange = function(){}來捕獲readyState變化之后做的事情。

三、關(guān)于http的狀態(tài)

ajax 也是使用 http 協(xié)議的,所以也需要了解 http協(xié)議的狀態(tài)。

1XX    100-101    信息提示
2XX    200-206    成功
3XX    300-305    重定向
4XX    400-415    客戶端錯(cuò)誤
5XX    500-505    服務(wù)器錯(cuò)誤

200 OK 服務(wù)器成功處理了請(qǐng)求(這個(gè)是我們見到最多的)
301/302 Moved Permanently(重定向)請(qǐng)求的URL已移走。Response中應(yīng)該包含一個(gè)Location URL, 說明資源現(xiàn)在所處的位置
304 Not Modified(未修改)客戶的緩存資源是最新的, 要客戶端使用緩存
404 Not Found 未找到資源
501 Internal Server Error服務(wù)器遇到一個(gè)錯(cuò)誤,使其無法對(duì)請(qǐng)求提供服務(wù)

這是比較齊全的狀態(tài)表:

四、關(guān)于函數(shù)封裝(ajax封裝)

變量、函數(shù)的作用域,是定義這個(gè)變量、函數(shù)時(shí),包裹它的最近父函數(shù)。

沒有在任何function中定義的變量,稱為全局變量。全局變量都是window對(duì)象的屬性。所以,如果想在函數(shù)內(nèi),向全局暴露頂層變量,只需要把頂層變量設(shè)置為window對(duì)象的屬性。

越是大的項(xiàng)目,越需要讓全局變量越少越好。這是為了防止不同工程師之間的程序,命名沖突。所以,每一個(gè)功能包,只能向全局暴露唯一的頂層變量,就是這個(gè)功能包自己的命名空間。

jQuery、YUI、underscore都是這樣的做法。

向外暴露全局變量,設(shè)置window的變量(也是這個(gè)函數(shù)的命名空間),類似jquery的$其實(shí)也就是window.$

良好的代碼風(fēng)格

//=======================屬性=======================

//=======================方法=====================

//=======================內(nèi)部方法=====================

_代表內(nèi)部方法或者屬性,主要是給編程人員看的

屬性和方法寫在前面,內(nèi)部屬性或者內(nèi)部方法寫在后面

通過判斷arguments.length來實(shí)現(xiàn)函數(shù)重載

(function () {
    var myAjax = {};  //空對(duì)象
    //向外暴露這么一個(gè)全局變量
    //就是這個(gè)函數(shù)的命名空間
    window.myAjax = myAjax;

    //=======================屬性=======================
    myAjax.version = "0.2.0";

    //=======================方法=======================
    myAjax.get = function () {
        //參數(shù)個(gè)數(shù)
        var argLength = arguments.length;
        var URL, json, callback;
        if (argLength == 2 && typeof arguments[0] == "string" && typeof arguments[1] == "function") {
            //兩個(gè)參數(shù)
            URL = arguments[0];
            callback = arguments[1];
            //傳給我們的核心函數(shù)來發(fā)出Ajax請(qǐng)求
            myAjax._doAjax("get", URL, null, callback);
        } else if (argLength == 3 && typeof arguments[0] == "string" && typeof arguments[1] == "object" && typeof arguments[2] == "function") {
            //3個(gè)參數(shù)
            URL = arguments[0];
            json = arguments[1];
            callback = arguments[2];
            //傳給我們的核心函數(shù)來發(fā)出Ajax請(qǐng)求
            myAjax._doAjax("get", URL, json, callback);
        } else {
            throw new Error("get方法參數(shù)錯(cuò)誤!");
        }
    }

    myAjax.post = function () {
        //參數(shù)個(gè)數(shù)
        var argLength = arguments.length;
        if (argLength == 3 && typeof arguments[0] == "string" && typeof arguments[1] == "object" && typeof arguments[2] == "function") {
            //3個(gè)參數(shù)
            var URL = arguments[0];
            var json = arguments[1];
            var callback = arguments[2];
            //傳給我們的核心函數(shù)來發(fā)出Ajax請(qǐng)求
            myAjax._doAjax("post", URL, json, callback);
        } else {
            throw new Error("post方法參數(shù)錯(cuò)誤!");
        }
    }

    //post方式提交所有表單
    myAjax.postAllForm = function (URL, formId, callback) {
        //將表單數(shù)據(jù)轉(zhuǎn)為json
        var json = myAjax._formSerialize(formId);
        myAjax._doAjax("post", URL, json, callback);
    }

    //=======================內(nèi)部方法=====================
    //將JSON轉(zhuǎn)換為URL查詢參數(shù)寫法
    //傳入{"id":12,"name":"考拉"}
    //返回id=12&name=%45%45%ED
    myAjax._JSONtoURLparams = function (json) {
        var arrParts = [];  //每個(gè)小部分的數(shù)組
        for (k in json) {
            //組成參數(shù)數(shù)組,然后用& 連接
            arrParts.push(k + "=" + encodeURIComponent(json[k]));//需要uri編碼特殊字符串,例如中文或者符號(hào)
        }
        return arrParts.join("&");
    }

    //最核心的發(fā)出Ajax請(qǐng)求的方法
    myAjax._doAjax = function (method, URL, json, callback) {
        //Ajax的幾個(gè)公式
        if (XMLHttpRequest) {
            var xhr = new XMLHttpRequest();
        } else {
            var xhr = ActiveXObject("Microsoft.XMLHTTP");
        }

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
                    callback(null, xhr.responseText);
                } else {
                    callback("文件沒有找到" + xhr.status, null);
                }
            }
        }

        //現(xiàn)在要根據(jù)請(qǐng)求類型進(jìn)行判斷
        if (method == "get") {
            //請(qǐng)求類型是get
            //如果用戶傳輸了json,此時(shí)要連字
            if (json) {
                //判斷URL本身是否有?,沒有就需要&連接
                var combineChar = URL.indexOf("?") == -1 ? "?" : "&";
                //將json轉(zhuǎn)為url參數(shù)后拼接
                URL += combineChar + myAjax._JSONtoURLparams(json);
            }
            //增加一個(gè)隨機(jī)數(shù)參數(shù),防止緩存
            var combineChar = URL.indexOf("?") == -1 ? "?" : "&";
            URL += combineChar + Math.random().toString().substr(2);
            
            xhr.open("get", URL, true);
            xhr.send(null);
        } else if (method == "post") {
            //增加一個(gè)隨機(jī)數(shù)參數(shù),防止緩存
            var combineChar = URL.indexOf("?") == -1 ? "?" : "&";
            URL += combineChar + Math.random().toString().substr(2);
            
            xhr.open("post", URL, true);
            //post需要有header
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xhr.send(myAjax._JSONtoURLparams(json));
        }
    }
})();
五、關(guān)于ajax緩存問題

當(dāng)Ajax第一次發(fā)送請(qǐng)求后,會(huì)把請(qǐng)求的URL和返回的響應(yīng)結(jié)果保存在緩存內(nèi),當(dāng)下一次調(diào)用Ajax發(fā)送相同的請(qǐng)求時(shí),注意,這里相同的請(qǐng)求指的是URL完全相同,包括參數(shù),瀏覽器就不會(huì)與服務(wù)器交互,而是直接從緩存中把數(shù)據(jù)取出來,這是為了提高頁面的響應(yīng)速度和用戶體驗(yàn)。(服務(wù)端也會(huì)收到請(qǐng)求響應(yīng)304)

瀏覽器會(huì)自作主張的把所有異步請(qǐng)求來的文件緩存,當(dāng)下一次請(qǐng)求的URL和之前的一樣,那么瀏覽器將不會(huì)發(fā)送這個(gè)請(qǐng)求,而是直接把緩存的內(nèi)容當(dāng)做xhr.responseText。

需要注意的是,post 請(qǐng)求方式不會(huì)被緩存,只有 get 請(qǐng)求方式會(huì)被緩存。
5.1 如何避免 ajax 緩存問題

方法1:隨機(jī)數(shù)

//隨機(jī)數(shù),我們不要0. 只要小數(shù)點(diǎn)后面的數(shù)字:
var random = Math.random().toString().substring(2);
 //URL上面就拼接一個(gè)隨機(jī)字符串,保證每次URL不一樣
myAjax.get("text.txt?" + random,function(err,data){
    alert(data);
});

方法2:時(shí)間戳
從1970年1月1日0:00到這一刻的毫秒數(shù)。就叫做時(shí)間戳。英語屬于timestamp。
JS里面時(shí)間戳就是

//時(shí)間戳:
var timestamp = Date.parse(new Date());
 //URL上面就拼接一個(gè)隨機(jī)字符串,保證每次URL不一樣
myAjax.get("text.txt?" + timestamp,function(err,data){
    alert(data);
});
總的來說,原理就是通過將 get 請(qǐng)求的 url 做成每次都不一樣,這樣就不會(huì)被瀏覽器緩存了。
六、json檢測

判斷返回的 json 數(shù)據(jù)是否可用,這個(gè)只是屬性一些日常使用 ajax 的點(diǎn)而已。

6.1 使用 JSON.parse

通過JSON.parse轉(zhuǎn)換為json格式,如果無法轉(zhuǎn)換,會(huì)報(bào)錯(cuò)。

var jsonObj = JSON.parse(str);
6.2 用hasOwnProperty進(jìn)行判斷

hasOwnProperty 這個(gè)方法能夠判斷對(duì)象里面是否有某個(gè)鍵屬性。

var obj = {"a":1,"b":2};
console.log(obj.hasOwnProperty("aaa"));

這個(gè)示例比較詳細(xì),并且加入了錯(cuò)誤之后的處理:

         //得到頁面上的用戶名的文本框、下拉列表
        var oUsername = document.getElementById("username");
        var oDomain = document.getElementById("domain");

        //得到good、bad、tuijian
        var oTuijian = document.getElementById("tuijian");
        var oBadTip = document.getElementById("badTip");
        var oGoodTip = document.getElementById("goodTip");

        //得到4個(gè)li(事先給定或者從其他接口獲取的)
        var tuijianLis = oTuijian.getElementsByTagName("li");

        //失去焦點(diǎn)和改變下拉列表,都是做同一個(gè)事情
        oUsername.onblur = check;
        oDomain.onchange = check;

        function check(){
            clearAllTip();  //清除所有提示框
            //得到值
            var username = oUsername.value;  //文本框
            //獲取所有用戶選中的郵箱選項(xiàng),并放入到domain數(shù)組
            var domain = (function(){
                //得到所有option
                var options = oDomain.getElementsByTagName("option");
                //遍歷,看看哪個(gè)被selected了
                for(var i = 0 ; i < options.length ; i++){
                    if(options[i].selected){
                        return options[i].value;
                    }
                }
            })();

            //如果這個(gè)值是空,那么什么也不做。
            if(!username) {
                return;
            }
            //正則驗(yàn)證合法性
            //6~18個(gè)字符,可使用字母、數(shù)字、下劃線,需以字母開頭
            var reg = /^[A-Za-z][w]{5,17}$/;
            if (!reg.test(username)) {
                showWrong("6~18個(gè)字符,可使用字母、數(shù)字、下劃線,需以字母開頭");
                return; //不合法的時(shí)候,就返回,不執(zhí)行下面的語句了
            }

            //這里請(qǐng)求一個(gè)靜態(tài)json,實(shí)際上要請(qǐng)求后臺(tái)php頁面。
            myAjax.post("check.json",{"username" : username},function(err,data){
                if(err){
                    showWrong("服務(wù)器錯(cuò)誤,稍后再試");
                    return;
                }
                //轉(zhuǎn)為json格式:
                var dataJSON = JSON.parse(data);
                //獲得result對(duì)象(即獲取服務(wù)器返回的驗(yàn)證結(jié)果)
                var result = dataJSON.result;
                //如果沒有result對(duì)象。就創(chuàng)造一個(gè)result對(duì)象
                if(!result){
                    var result = {}; //因?yàn)樾枰o后續(xù)的hasOwnProperty校驗(yàn)
                }
                //檢測是否可用
                if(result.hasOwnProperty(domain)){//服務(wù)器驗(yàn)證結(jié)果跟用戶選項(xiàng)一致的時(shí)候
                    showRight("恭喜,可用!");
                }else{ //服務(wù)器驗(yàn)證結(jié)果跟用戶選項(xiàng)不一致的時(shí)候
                    //就要給用戶顯示推薦的郵箱
                    oTuijian.style.display = "block";   //顯示推薦框
                    //我們要依次查找這些域名是否可用(事先給定或者從其他接口獲取的)
                    var domainArray = ["163.com","126.com","yeah.net"];
                    //我們?cè)賹懸粋€(gè)結(jié)果數(shù)組
                    var usableArray = [];
                    //遍歷domainArray,把domainArray中的每一個(gè)項(xiàng),進(jìn)行檢測
                    //檢測result對(duì)象中是不是有這個(gè)屬性
                    //直接獲取了判斷的結(jié)果的數(shù)組
                    for(var i = 0 ; i < domainArray.length ; i++){
                        var tOrf = result.hasOwnProperty(domainArray[i]) ? true : false;
                        usableArray.push(tOrf);
                    }
                    console.log(usableArray);

                    //遍歷4個(gè)li標(biāo)簽,根據(jù)我們的結(jié)果數(shù)組來決定他們
                    //是否有disable類、里面的span的內(nèi)容、b的內(nèi)容
                    for(var i = 0 ; i < tuijianLis.length ; i++){
                        var thisli = tuijianLis[i];

                        //通過判斷的結(jié)果的數(shù)組的值來控制是否設(shè)置class
                        //決定這個(gè)li是否有disable類
                        thisli.className = usableArray[i] ? "" : "disable";

                        //往span里面寫內(nèi)容
                        //得到這唯一一個(gè)span
                        var thisspan = thisli.getElementsByTagName("span")[0];
                        //有時(shí)候需要重新解析一些值的格式
                        if(domainArray[i] == "vip163"){
                            domainArray[i] = "vip.163.com";
                        }
                        thisspan.innerHTML = username + "@" + domainArray[i];

                        //往b里面寫內(nèi)容
                        var thisb = thisli.getElementsByTagName("b")[0];
                        //通過判斷的結(jié)果的數(shù)組的值來控制顯示內(nèi)容
                        thisb.innerHTML = usableArray[i] ? "可以使用" : "已經(jīng)被占用";
                    }
                }
            });
        }

        //得到焦點(diǎn)
        oUsername.onfocus = clearAllTip;

        function clearAllTip(){
            //讓所有的提示框消失
            oTuijian.style.display = "none";
            oBadTip.style.display = "none";
            oGoodTip.style.display = "none";
        }

        //顯示錯(cuò)誤提示框
        function showWrong(info){
            oBadTip.innerHTML = info;
            oBadTip.style.display = "block";
        }

        //顯示正確提示框
        function showRight(info){
            oGoodTip.innerHTML = info;
            oGoodTip.style.display = "block";
        }
七、關(guān)于跨域問題

已經(jīng)在另外一篇文章里面說過了,jsonp 是其中一種解決辦法。

微信:地址
blog:地址

7.1 使用jsonp
//給按鈕添加監(jiān)聽
        oBtn.onclick = function(){
            //得到用戶填寫的手機(jī)號(hào)
            var danhao = odanhao.value;
            var kuaidigongsi = okuaidigongsi.value;

            //創(chuàng)建script
            var script = document.createElement("script");
            script.src = "https://sp0.baidu.com/9_Q4sjW91Qh3otqbppnN2DJv/pae/channel/data/asyncqury?cb=xixi&appid=4001&com=" + kuaidigongsi +"&nu=" + danhao +"&vcode=&token=&_=1438916675664"

            //追加然后刪除
            document.body.appendChild(script);
            document.body.removeChild(script);
        }

        function xixi(data){
            console.log(data);
        }
八、關(guān)于ajax的示例:瀑布流

要實(shí)現(xiàn)2個(gè)地方:

滾動(dòng)到底部判斷(包含視口的底部和總的底部)

瀑布流里面的內(nèi)容需要錯(cuò)位顯示

8.1 滾動(dòng)到底部判斷

我們需要知道:

總文檔高度

已經(jīng)滾動(dòng)的高度

視口高度,通過$(document).height(); 獲取,視口底部來觸發(fā)ajax 獲取下一頁的數(shù)據(jù)

總文檔高度-已經(jīng)卷動(dòng)高度-視口高度 < 200 基本上就是滾動(dòng)到底了,滾動(dòng)到文檔底部就停止 ajax 請(qǐng)求。

scroll事件,一定是要截流的。因?yàn)橛脩魸L一個(gè)鼠標(biāo)滾輪的“小咯噔”就觸發(fā)一次scroll事件;滑動(dòng)滾動(dòng)條的時(shí)候,是每一像素觸發(fā)一次這個(gè)事件。還有pageDown、下箭頭按鈕,都能觸發(fā)scroll事件。

如何判斷文章是否到頭,說白了前端開發(fā)工程師不知道一共有多少頁。比如今天又53頁,明天就有55頁了,所以你的JS里面無法寫死一個(gè)文章總頁數(shù)。所以辦法就是,請(qǐng)求下去,請(qǐng)求到page.php?pagenum=54的時(shí)候,發(fā)現(xiàn)終止標(biāo)記,或者這個(gè)頁面返回的json是空,就表示到頭了。

8.2 瀑布流里面的內(nèi)容需要錯(cuò)位顯示

這里分成三列瀑布流,組成一個(gè)數(shù)組管理

這個(gè)數(shù)組會(huì)不斷計(jì)算三列之中的最小值

然后按照每次的最小值進(jìn)行高度插入

圖片判斷是否加載完成需要用load方法,并且圖片需要先new image才能加載方法

圖片的插入次序不是固定的(ajax異步),所以用之前的數(shù)組進(jìn)行管理,每次都對(duì)最小值的高度插入值,這樣就能保證每次都往最靠里面的圖片位置進(jìn)行放置

并且需要使用絕對(duì)位置值,因?yàn)閏ss里面,需要使用絕對(duì)值撐開位置(left 和top)

瀑布流的數(shù)組樣例如下:

// 第一行
// [0,0,0]   minIndex: 0 left 0 top 20  [558,0,0 ]
// [558,0,0] minIndex: 1 left 300 top 20 [558,386,0]
// [558,386,0] minIndex:2 left 600 top 20 [558,386,722]
//第二行
//[558,386,722] minIndex:1 left 300 top 406 [558, 943, 722]
//[558, 943, 722] minIndex:0 left 0 top 578 [1193, 943, 722]
//[1193, 943, 722] minIndex:2 left 600 top 742 [1193, 943, 1128]
8.3 整個(gè)代碼



    
    Document
    



到最后了親!
    var $waterfall = $(".waterfall");
    //得到模板
    var templateString = $("#feed-template").html();
    //準(zhǔn)備模板函數(shù),通過underscore將模板函數(shù)轉(zhuǎn)為html模板,全局使用,所以多帶帶拿出來
    var compile = _.template(templateString);

    //準(zhǔn)備總高度數(shù)組
    var colAllHeight = [0, 0, 0]; //三個(gè)表示頁面的瀑布的三列的每一個(gè)塊的高度

    var pagenum = 1;    //頁碼

    getAndRender(1); //先渲染第一頁的內(nèi)容

    var lock = true;    //函數(shù)截流

    //窗口卷動(dòng)監(jiān)聽
    //每滾動(dòng)一次都會(huì)觸發(fā)
    $(window).scroll(function () {
        //jquery幫我們做了關(guān)于滾動(dòng)的三個(gè)兼容處理:總文檔高度,已經(jīng)卷動(dòng)高度,視口高度
        var scrollTop = $(window).scrollTop();
        var windowHeight = $(window).height();
        var documentHeight = $(document).height();
        //已經(jīng)滾動(dòng)到底部并且已經(jīng)被lock
        if (documentHeight - windowHeight - scrollTop < 200 && lock) {
            lock = false; //解除鎖定
            pagenum++; //滾動(dòng)一次加一次頁數(shù)
            getAndRender(pagenum); //根據(jù)頁數(shù)渲染數(shù)據(jù),并且里面會(huì)重新鎖定
        }
    });

    function getAndRender(pagenum) {
        //讓加載logo顯示
        $waterfall.addClass("loading");
        //發(fā)出Ajax請(qǐng)求
        //這里的頁數(shù)是用簡單的文件的數(shù)字編號(hào)來代替
        $.get("json/json" + pagenum + ".txt", function (data, statusText) { //jq的ajax的get方法
            //把字符串轉(zhuǎn)為對(duì)象
            var dataJSON = JSON.parse(data);
            //news這個(gè)數(shù)組,仔細(xì)想想,news這個(gè)數(shù)組里面裝的是什么?
            var dictionaryArray = dataJSON.news;

            //如果數(shù)組為空,就表示到最后了
            if (dictionaryArray.length == 0) {
                $(".end").show();
                $waterfall.removeClass("loading");
                return;
            }

            //遍歷從接口獲取的數(shù)據(jù)
            for (var i = 0; i < dictionaryArray.length; i++) {
                var thisDictionary = dictionaryArray[i];
                //馬上發(fā)出請(qǐng)求這個(gè)字典里面圖片的請(qǐng)求
                var image = new Image();
                //一旦設(shè)置src,上行HTTP請(qǐng)求將發(fā)出
                image.src = thisDictionary.imgurl;
                image.index = i; //設(shè)置這個(gè)image的索引值
                //監(jiān)聽這個(gè)圖片是不是加載完畢
                $(image).load(function () {
                    //這張圖片加載完畢了
                    //console.log(this.index + "號(hào)圖片加載完畢");

                    //填充字典
                    //哪個(gè)圖片已經(jīng)填充完了,就注入幾號(hào)字典
                    //例如第一個(gè)圖片,傳入轉(zhuǎn)為html模板的函數(shù)
                    var compiledString = compile(dictionaryArray[this.index]);

                    //得到這個(gè)盒子,變?yōu)閖Query對(duì)象
                    var $box = $(compiledString);

                    //上DOM
                    $waterfall.append($box);

                    //尋找最小列
                    var min = _.min(colAllHeight);
                    //尋找最小列的索引
                    var minIndex = _.indexOf(colAllHeight, min);
                    //絕對(duì)定位:
                    $box.css("left", 300 * minIndex);
                    $box.css("top", colAllHeight[minIndex] + 20);
                    //將自己的高度,也加到數(shù)組的指定列中:
                    colAllHeight[minIndex] += $box.outerHeight() + 20;
                    //淡入
                    $box.fadeIn();
                    //讓加載滾動(dòng)的logo有高度,跟隨移動(dòng)位置
                    $waterfall.css("height", _.max(colAllHeight));
                    $waterfall.removeClass("loading");

                    lock = true;
                });
            }
        });
    }

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/108341.html

相關(guān)文章

  • AJAX學(xué)習(xí)筆記(二)

    摘要:與不同的是,應(yīng)該以發(fā)送的數(shù)據(jù)作為請(qǐng)求的主體。有了這些不同的事件支持,開發(fā)者可以免去檢查之類的工作,更加的方便。其中事件和事件比較重要。而事件則會(huì)為在瀏覽器接收數(shù)據(jù)期間周期性地觸發(fā)。 在上篇筆記中,我們主要談了一些概述和跨域的問題,這一次我們聊聊請(qǐng)求和響應(yīng)的具體內(nèi)容。 向服務(wù)器發(fā)起請(qǐng)求 我們?cè)趧?chuàng)建了XHR對(duì)象后,接著需要用兩個(gè)方法來發(fā)送請(qǐng)求:open()和send(),這兩個(gè)方法有點(diǎn)像賽...

    Charles 評(píng)論0 收藏0
  • Ajax筆記

    摘要:本文主要是我學(xué)習(xí)的筆記,不涉及到原理,只是記錄如何使用。成功的含義取決于方法資源已被提取并在消息正文中傳輸。是請(qǐng)求鏈接到服務(wù)器,服務(wù)器響應(yīng)錯(cuò)誤后服務(wù)器返回瀏覽器的狀態(tài)碼。是指響應(yīng)時(shí)間,開始請(qǐng)求到接收到響應(yīng)開始處理的時(shí)間,單位為。 本文主要是我學(xué)習(xí)ajax的筆記,不涉及到原理,只是記錄如何使用。如果有錯(cuò)歡迎各位大佬指出。提前先轉(zhuǎn)一篇寫的非常全面的博客你真的會(huì)使用XMLHttpReques...

    macg0406 評(píng)論0 收藏0
  • 26天學(xué)通前端開發(fā)(配資料)

    摘要:網(wǎng)上有很多前端的學(xué)習(xí)路徑文章,大多是知識(shí)點(diǎn)羅列為主或是資料的匯總,數(shù)據(jù)量讓新人望而卻步。天了解一個(gè)前端框架。也可以關(guān)注微信公眾號(hào)曉舟報(bào)告,發(fā)送獲取資料,就能收到下載密碼,網(wǎng)盤地址在最下方,獲取教程和案例的資料。 前言 好的學(xué)習(xí)方法可以事半功倍,好的學(xué)習(xí)路徑可以指明前進(jìn)方向。這篇文章不僅要寫學(xué)習(xí)路徑,還要寫學(xué)習(xí)方法,還要發(fā)資料,干貨滿滿,準(zhǔn)備接招。 網(wǎng)上有很多前端的學(xué)習(xí)路徑文章,大多是知...

    blair 評(píng)論0 收藏0
  • 《Head First JavaScript》讀書筆記

    摘要:設(shè)定的值的時(shí)候,即已自動(dòng)暗示類型。第五章循環(huán)自我重復(fù)的風(fēng)險(xiǎn)數(shù)組用于在單一場所存儲(chǔ)多段數(shù)據(jù)數(shù)組的頁碼稱為鍵,索引只是一種形式特殊的鍵,它是數(shù)值鍵存儲(chǔ)在數(shù)組里的數(shù)據(jù)不一定為相同類型并不要求二維數(shù)組具有相同的行數(shù),但是最好保持一致。 ** 簡介 **書名:《Head First JavaScript》中文譯名:《深入淺出JavaScript》著:Michael Morrison編譯:O’R...

    ztyzz 評(píng)論0 收藏0
  • Ajax學(xué)習(xí)筆記

    摘要:最近在學(xué),剛剛?cè)腴T,用到很多與相關(guān)的交互。也用了挺久的了,想寫一下學(xué)習(xí)筆記來記錄一下。實(shí)現(xiàn)過程是的基礎(chǔ),是核心對(duì)象,首先要實(shí)例化一個(gè)對(duì)象進(jìn)行請(qǐng)求,規(guī)定請(qǐng)求的類型以及是否異步處理請(qǐng)求。響應(yīng)服務(wù)器狀態(tài)響應(yīng)服務(wù)器狀態(tài)涉及對(duì)象的三個(gè)重要的屬性。 最近在學(xué)php,剛剛?cè)腴T,用到很多與Ajax相關(guān)的交互。Ajax也用了挺久的了,想寫一下學(xué)習(xí)筆記來記錄一下。今天先簡單寫一下原理和過程。歡迎大家一起探...

    Forest10 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<