摘要:對象待會講,我認為是設計最巧妙的地方。在跨域的時候會使用到,這是為了禁止使用。的目的在于創建一個事件,然后在觸發他,如果默認行為被取消了,則返回。這是的初始化,默認是請求,是新建的對象,表示瀏覽器是否應該被允許緩存響應。
在學習zepto的源碼的時候,不得不稱贊這些人的厲害,我雖然能看明白,但是要我寫,估計吭哧吭哧寫不出來。雖然現在很少人使用zepto了,但是學習這些源碼我相信每次看都能給咱們不同的感受。Deferred對象待會講,deferred我認為是zepto設計最巧妙的地方。先來看zepto的ajax模塊。
;(function($){ var jsonpID = +new Date(); function triggerAndReturn(context, eventName, data) { var event = $.Event(eventName); $(context).trigger(event, data); return !event.isDefaultPrevented(); } })
這里為什么文件開頭都要使用";"這是因為在對多個js文件進行打包的時候,如果使用換行分隔代碼,當合并壓縮多個文件之后,換行符會被刪掉,連在一起可能出錯,加上分號就保險了。
jsonpID在跨域jsonp的時候會使用到,這是為了禁止使用cache。triggerAndReturn()的目的在于創建一個Event事件,然后在context觸發他,如果默認行為被取消了,則返回false。
$.ajaxSettings = { type: "GET", success: empty, xhr: function () { return new window.XMLHttpRequest() }, cache: true, crossDomain: false }
這是ajax的初始化,默認是GET請求,xhr是新建的XMLHttpRequest()對象,cache表示瀏覽器是否應該被允許緩存GET響應。crossDomain表示是否可以來自另外一個域。
下面來看看最核心的$.ajax方法。
$.ajax = function (options) { var settings = $.extend({}, options || {}), deferred = $.Deferred && $.Deferred(), urlAnchor, hashIndex for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key] ajaxStart(settings) ... }
首先傳入options,然后將傳入的options存儲到本地,deferred咱們暫時可以把它看成一個promise對象,遍歷$.ajaxSettings,如果用戶沒有設置里邊有的屬性,那就使用默認的屬性。然后調用ajaxStart開始的函數。
if (!settings.crossDomain) { urlAnchor = document.createElement("a"); urlAnchor.href = settings.url; urlAnchor.href = urlAnchor.href; settings.crossDomain = (originAnchor.protocol + "http://" + originAnchor.host) !== (urlAnchor.protocol + "http://" + urlAnchor.host) }
這里首先crossDomain為false的情況下,進入該邏輯,通過判斷我們傳入的url和當前window.location.href做對比,判斷是不是跨域。
if ((hashIndex = settings.url.indexOf("#")) > -1) settings.url = settings.url.slice(0, hashIndex) var dataType = settings.dataType, hasPlaceholder = /?.+=?/.test(settings.url); if (hasPlaceholder) dataType = "jsonp"; if (settings.cache === false || ( (!options || options.cache !== true) && ("script" == dataType || "jsonp" == dataType) )) settings.url = appendQuery(settings.url, "_=" + Date.now()) function appendQuery(url, query) { if (query == "") return url; return (url + "&" + query).replace(/[&?]{1,2}/, "?") } if ("jsonp" == dataType) { if (!hasPlaceholder) settings.url = appendQuery(settings.url, settings.jsonp ? (settings.jsonp + "=?") : settings.jsonp === false ? "" : "callback=?") return $.ajaxJSONP(settings, deferred) }
如果我們沒有傳入url,那么url就是window.location.href。"#"代表網頁中的一個位置,右邊的字符,就是該位置的標識符,#是用來指導瀏覽器動作的,對瀏覽器沒有用,所以在截取url的時候,沒必要把后面的部分傳給服務器。hasPlaceholder這里的正則表達式,用于匹配類似"?name=?"這種字符串,如果hasPlaceholder為true,則dataType為jsonp。下面的時不使用留在緩存的數據,第一種是設置cache為false,或者dataType為script和jsonp的情況,需要在url后面添加事件。下面是appendQuery方法,就是把字符串拼接到url后邊,但是需要把"&"替換成"?"。如果我們的請求是jsonp請求,需要在url后面添加一些callback=?這種參數。
var mime = settings.accepts[dataType], headers = {}, setHeader = function(name, value) {headers[name.toLowerCase()] = [name, value]}, protocol = /^([w-]+:)///.test(settings.url) ? RegExp.$1 : window.location.protocol, xhr = settings.xhr(), nativeSetHeader = xhr.setRequestHeader, abortTimeout if (deferred) deferred.promise(xhr); if (!settings.crossDomain) setHeader("X-Requested-With", "XMLHttpRequest"); setHeader("Accept", mime || "*/*") if (mime = settings.mimeType || mime) { if (mime.indexOf(",") > -1) mime = mime.split(",", 2)[0] xhr.overrideMimeType && xhr.overrideMimeType(mime) }
settings中的accepts表示從服務器請求的MIME類型,指定dataType的值,包括script、json、xml、html、text。mime存儲的就是類似"application/json"的字符串。protocol就是匹配咱們類似"http://"的這種協議。
如果deferred存在,就把xhr轉換為deferred對象。接著看下去,如果不是跨域的,那就是ajax請求。然后后面的判斷條件查了一下是針對一些mozillar瀏覽器進行修正(有個問題就是他們上哪兒知道的用這種方式來修正啊)。
xhr.onreadystatechange = function() { if (xhr.readyState == 4) { xhr.onreadystatechange = empty if (/*如果成功*/){ // 對返回結果進行處理 } } } xhr.open(settings.type, settings.url, async, settings.username, settings.password)
沒什么難的,就是根據傳入的參數不同進行處理。
$.param這個函數的作用在于序列化傳入對象,下面是他的代碼:
$.param = function (obj, traditional) { var params = [] params.add = function (key, value) { if ($.isFunction(value)) value = value() if (value == null) value = "" this.push(escape(key) + "=" + escape(value)) } serialize(params, obj, traditional) return params.join("&").replace(/%20/g, "+") }
傳入一個對象,和一個標記,這個traditional表示激活傳統的方式通過$.param來得到data。首先定義一個空數組,如果在上面添加方法,這個方法的主要作用向params里邊添加序列化的對象,escape=encodeURIComponent,然后調用serialize,將obj對象添加到params中,最后返回將params數組用"&"拼接,然后這里的%20表示空格,意思是將空格替換成"+"
serialize下面是代碼
function serialize(params, obj, traditional, scope) { var type, array = $.isArray(obj), hash = $.isPlainObject(obj) $.each(obj, function (key, value) { type = $.type(value) if (scope) key = traditional ? scope : scope + "[" + (hash || type == "object" || type == "array" ? key : "") + "]" // handle data in serializeArray() format if (!scope && array) params.add(value.name, value.value) // recurse into nested objects else if (type == "array" || (!traditional && type == "object")) serialize(params, value, traditional, key) else params.add(key, value) }) }
params是帶有add方法的數組,遍歷obj的鍵值對,屬性值可能是對象也可能是數組或者字符串分別進行處理。如果obj的某個屬性值是對象或者數組,scope就代表是該屬性,那么這時候向params傳入的key就需要變化,變成類似"a[b]"這里的b是obj的某個屬性值是對象的一個屬性。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96676.html
摘要:私有變量用來臨時存放配置中的,即請求成功后執行的回調函數名,該配置可以為類型。是根據配置得出的回調函數名。接下來,將的占位符,替換成回調函數名,最后將插入到頁面中,發送請求。 Ajax 模塊也是經常會用到的模塊,Ajax 模塊中包含了 jsonp 的現實,和 XMLHttpRequest 的封裝。 讀 Zepto 源碼系列文章已經放到了github上,歡迎star: reading-...
摘要:讀源碼系列文章已經放到了上,歡迎源碼版本本文閱讀的源碼為改寫原有的方法模塊改寫了以上這些方法,這些方法在調用的時候,會為返回的結果添加的屬性,用來保存原來的集合。方法的分析可以看讀源碼之模塊。 Stack 模塊為 Zepto 添加了 addSelf 和 end 方法。 讀 Zepto 源碼系列文章已經放到了github上,歡迎star: reading-zepto 源碼版本 本文閱讀的...
摘要:形如源代碼在的原型上添加了相關方法。類似源代碼每個表單的和都通過編碼最后通過符號分割有了的基礎,就是將相應的和都通過編碼,然后用符號進行分割,也就達到了我們要的結果。 前言 JavaScript最初的一個應用場景就是分擔服務器處理表單的責任,打破處處依賴服務器的局面,這篇文章主要介紹zepto中form模塊關于表單處理的幾個方法,serialize、serializeArray、sub...
摘要:模塊是為解決移動版加載圖片過大過多時崩潰的問題。因為沒有處理過這樣的場景,所以這部分的代碼解釋不會太多,為了說明這個問題,我翻譯了這篇文章作為附文怎樣處理移動端對圖片資源的限制,更詳細地解釋了這個模塊的應用場景。 assets 模塊是為解決 Safari 移動版加載圖片過大過多時崩潰的問題。因為沒有處理過這樣的場景,所以這部分的代碼解釋不會太多,為了說明這個問題,我翻譯了《How to...
閱讀 2723·2023-04-25 22:15
閱讀 1804·2021-11-19 09:40
閱讀 2149·2021-09-30 09:48
閱讀 3214·2021-09-03 10:36
閱讀 2026·2021-08-30 09:48
閱讀 1854·2021-08-24 10:00
閱讀 2725·2019-08-30 15:54
閱讀 699·2019-08-30 15:54