1. 程式人生 > >jQuery封裝一個方法實現監控頁面所有ajax請求

jQuery封裝一個方法實現監控頁面所有ajax請求

我在使用裡面的程式碼後發現存在以下問題:

1.這種寫法重寫了jQuery中的$.ajax,如果說頁面本身用了iframe的形式設計的話,內部的頁面第一次載入使用此方法可以正常執行,但是第二次載入內部頁面的話,可能會造成jQuery相關的函式失效(報undefined的錯誤)

2.ajax請求完成之後的操作(回撥)直接寫在了這個方法裡面,如果下次對於請求完成後有新的操作,這個方法估計又得重寫

考慮到以上的問題,我在參考了原始程式碼的基礎上,使用jQuery進行了封裝。封裝程式碼如下:

pageRequest.js

/**
 * 監控頁面所有ajax請求,如果處理完,則執行特定操作
 */

(function($){
	// 將$.ajax存放到window物件中
	var ajaxBack = window.ajaxBack||$.ajax;
	// 上面這種寫法與window.ajaxBack?window.ajaxBack:$.ajax等效
	window.ajaxBack = ajaxBack;
	
	var PageRequest = function(pageRequest) {
		
		var _this_ = this;
		
		this.pageRequest = pageRequest;
		
		// 預設配置引數
		this.options = {
			// 請求成功後要做的操作
			success:initSeePage
		};
		
		// 如果傳了options,則覆蓋預設的options
		if(this.getOptions()){
			$.extend(this.options, this.getOptions());
		}
		
		// 儲存配置引數
		var options = this.options;
		
		// 當sucess不為空時,執行函式
		if(options.success) {
			_this_.invoke(options);
		}
	};
	
	PageRequest.prototype = {
		// 獲取配置引數
		getOptions:function() {
			// 拿到初始化時傳入的引數
			var pageRequest = this.pageRequest;
			
			// 確保有配置引數
			if(pageRequest) {
				return pageRequest;
			} else {
				return null;
			}
		},
		
		// 事件驅動函式
		invoke:function(options) {
			//前提:所有ajax請求都是用jquery的$.ajax發起的,而非原生的XHR;
		    // var ajaxBack = $.ajax;
		    var ajaxCount = 0;
		    var allAjaxDone = function(){
		    	options.success();
		    } //一行程式碼,就可以知道所有ajax請求什麼時候結束
		    
		    //由於get/post/getJSON等,最後還是呼叫到ajax,因此只要改ajax函式即可
		    $.ajax = function(setting){
		      ajaxCount++;
		      var cb = setting.complete;
		      setting.complete = function(){
		        if($.isFunction(cb)){cb.apply(setting.context, arguments);}
		        ajaxCount--;
		        if(ajaxCount==0 && $.isFunction(allAjaxDone)){
		          allAjaxDone();
		          $.ajax = ajaxBack; // 將$.ajax恢復成原來的jquery物件
		        }
		      }
		      ajaxBack(setting);
		    }
		}
	}
	
	PageRequest.init = function(pageRequest) {
		var _this_ = this;
		new _this_(pageRequest);
	}
	
	window.PageRequest = PageRequest;
	
	// 初始化檢視頁面
	function initSeePage() {
		// 將頁面上的按鈕禁用
		$("input[type=button]").attr("class", "disabled_button")
		$("select").attr("disabled", "disabled");
		$("textarea").attr("disabled", "disabled");
		$("input").each(function(i) {
			if ($(this).is(":visible")) {
				$(this).attr("disabled", "disabled");
			}
		});
		$("img").attr("onclick", "");
		$("img").unbind("click");
		
		$("div").attr("onclick", "");
		$("div").unbind("click");
		
		var images = document.getElementsByTagName("img");
		for ( var i = 0; i < images.length; i++) {
			try {
				images[i].removeEventListener("onclick", function() {
				});
			} catch (e) {
				images[i].attachEvent("onclick", function() {
				});
			}
		}
	}
	
})(jQuery);

使用方法如下:

1.不傳入引數的情況下,ajax所有請求完成後,會執行initSeePage方法(該方法將頁面上的所有按鈕等元素禁用,及相關的click事件解除)

<script type="text/javascript">
	// 在點選查詢後,頁面所有ajax請求完成後,禁用掉頁面元素
	$(document).ready(function() {
		var initPage = function() {
			PageRequest.init()
		};
		$("#searchBtn").click();
		initPage();
	});
</script>

2.如果想要在頁面點選查詢按鈕後,所有除查詢以外的元素被禁用,但是再次點選查詢,依然仍維持這種效果,可以這樣寫

(注:這裡傳入了自定義操作,該操作替換了預設的initSeePage方法)

<script type="text/javascript">
	// 在點選查詢後,頁面所有ajax請求完成後,禁用掉頁面元素
	$(document).ready(function() {
		var initPage = function() {
			PageRequest.init({
				"success":myOperation
			})
		};
		$("#searchBtn").on("click", initPage).click();
		initPage();
	});
</script>

// 自定義操作
function myOperation() {
	$("input").each(function(i) {
		if ($(this).is(":visible")) {
			var butValue=$(this).attr("value");
			if(butValue=="新增"||butValue=="編輯"||butValue=="刪除"||butValue=="新增"||butValue=="儲存"){
				$(this).attr("class", "disabled_button");
				$(this).attr("disabled", "disabled");
			}
		}
	});
}