日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > web前端 > jscript > 使用clickCatcher在JS文件加載完畢/事件應用之前捕獲Click事件

使用clickCatcher在JS文件加載完畢/事件應用之前捕獲Click事件

來源:程序員人生   發布時間:2013-12-12 13:18:26 閱讀次數:2985次

提高網站性能的方法之一就是將JavaScript文件放到文檔的底部(我在Improve Your Web Site Performance – Tips & Tricks To Get A Good YSlow Rating中討論過)。但是,這有一個缺點。

問題

在JavaScript文件加載完畢運行之前,你打算為文檔中一些元素分配一個事件處理器。如果用戶此時單擊這些元素,會發生什么情況?那么瀏覽器將執行元素默認的行為。如,一個將用戶帶到另外一個頁面的鏈接,而你并不打算這么做,而是想通過AJAX或其他方式動態加載一些信息。

理論解決方案

最近,我和我的同事David Billskog討論并研究了這個問題,其解決方案是在文檔的頭部包含一個JavaScript塊(inline或included),并確信能捕獲頁面中所有的click事件。然后過濾它們確定一個元素正是你正打算應用事件處理器的那個元素。

最后,當頁面加載完畢/事件處理器已經分配時,移除先前分配的clickCatcher,迭代在這之前被點擊的所有元素,然后觸發這些元素真正的click事件,引發正常的和應用的事件行為。

實際解決方案

我和David開始各自的工作,對我來說,解決方案不需要任何JavaScript庫,而David的解決方案是基于jQuery版本的(可以很容易的應用到任何其它庫中)。我列出我的解決方案——clickCatcher。

clickCatcher使用一些簡單的script函數作為基礎:

  • addEvent——在不覆蓋任何可能被分配click事件處理器的情況下,為文檔分配一個click事件。
  • removeEvent——一旦頁面加載完畢,移除上面分配的事件,并不再繼續捕獲clilck事件。
  • fireEvent——在JavaScript文件已加載完畢之前,釋放被單擊的所有元素的click事件。

The clickCatcher

(function () {	clickCatcher = function () {		var clicks = [],			addClicks = function (evt) {				var classCheck = /catch/,					body = /body/i,					target = (evt.target)? evt.target : evt.srcElement;				while (!classCheck.test(target.className) && !body.test(target.nodeName)) {					target = target.parentNode;				}				if (classCheck.test(target.className)) {					clicks.push(target);					if (evt.preventDefault) {						evt.preventDefault();					}					evt.returnValue = false;					return false;				}			},			callClicks = function () {				removeEvent(document, "click", addClicks);				for (var i=0, il=clicks.length; i<il; i++) {					fireEvent(clicks[i], "click");				};			},			init = function () {				addEvent(document, "click", addClicks);				// Could be called here, but now called manually in script loaded later - adapt to your situation				//addEvent(window, "load", callClicks);			};		return {			init : init,			callClicks : callClicks		};	}();	clickCatcher.init();	return clickCatcher;})();

clickCatcher封裝在一個匿名的自調用函數之中,這樣就不會與網頁的全局變量相混淆,而是創建自己的作用域。如果你想在其它地方訪問它,這部分代碼可以選擇性的暴露clickCatcher對象自身。代碼給文檔附加一個事件處理器,如果被單擊的元素(或任何它的父元素)有類名catch(如鏈接),就將每一個click存儲到一個數組中。

一旦頁面加載完畢,你可以讓其自動調用,或你可以通過調用clickCatcher.callClicks()方法手動觸發它;

包含addEvent, removeEvent, fireEvent方法完整的代碼,看起來就是這樣:

// By Robert Nyman, http://robertnyman.com/clickcatcher/ - This content is released under the MIT License: http://www.opensource.org/licenses/mit-license.php(function () {	// addEvent by John Resig, http://ejohn.org/blog/flexible-javascript-events/	function addEvent( obj, type, fn ) {		if ( obj.attachEvent ) {			obj['e'+type+fn] = fn;			obj[type+fn] = function(){obj['e'+type+fn]( window.event );}			obj.attachEvent( 'on'+type, obj[type+fn] );		} else			obj.addEventListener( type, fn, false );	}	function removeEvent( obj, type, fn ) {		if ( obj.detachEvent ) {			obj.detachEvent( 'on'+type, obj[type+fn] );			obj[type+fn] = null;		} else			obj.removeEventListener( type, fn, false );	}	// fireEvent by Jehiah Czebotar, http://jehiah.cz/archive/firing-javascript-events-properly	function fireEvent(element, event) {		var evt;		if (document.createEvent) {			// dispatch for firefox + others			evt = document.createEvent("HTMLEvents");			evt.initEvent(event, true, true ); // event type,bubbling,cancelable			return !element.dispatchEvent(evt);		} else {		// dispatch for IE			evt = document.createEventObject();			return element.fireEvent('on'+event,evt);		}	}	clickCatcher = function () {		var clicks = [],			addClicks = function (evt) {				var classCheck = /catch/,					body = /body/i,					target = (evt.target)? evt.target : evt.srcElement;				while (!classCheck.test(target.className) && !body.test(target.nodeName)) {					target = target.parentNode;				}				if (classCheck.test(target.className)) {					clicks.push(target);					if (evt.preventDefault) {						evt.preventDefault();					}					evt.returnValue = false;					return false;				}			},			callClicks = function () {				removeEvent(document, "click", addClicks);				for (var i=0, il=clicks.length; i<il; i++) {					fireEvent(clicks[i], "click");				};			},			init = function () {				addEvent(document, "click", addClicks);				// Could be called here, but now called manually in script loaded later - adapt to your situation				//addEvent(window, "load", callClicks);			};		return {			init : init,			callClicks : callClicks		};	}();	clickCatcher.init();	return clickCatcher;})();

你可以到clickCatcher頁測試這些代碼。

setTimeout 技巧

但是,不管是是從clickCatcher內部來觸發clicks的執行,還是手動調用它們,你要確信這是最后調用的。David研究中的一個有趣的結果是,你可以通過使用setTimeout控制調用棧,time設置為0,這樣,相對于其它完全相同load事件處理器,它將被放置到棧的最后。

也將就是說,如果你在window已加載時使用addEvent調用某些東西,你可以像這樣控制它(或許只在同一個script塊或JavaScript文件中時相對安全)。

// Calling click handlersetTimeout(function () {	addEvent(window, "load", callClicks);}, 0);// My own function - will be called before the above functionaddEvent(window, "load", myCoolFunc);

jQuery 版本

先前我提到過David的jQuery版本,這意味著在你調用之前須包含jQuery,但是你可以將其它JavaScript文件放到頁面底部。他介紹了他的方法,結果在clickCatcher with jQuery 。

反饋?

從我們的測試中看到,在JavaScript加載完畢之前捕獲click事件,這是一個有效可靠的方法。你仍可以在文檔的底部放置js來提升網站性能。

原文地址:http://robertnyman.com/2010/05/24/catching-clicks-with-clickcatcher-before-your-javascript-files-have-loadedevents-been-applied/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+robertnyman+%28Robert%27s+talk%29

轉載地址:http://www.denisdeng.com/?p=1018

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 美女视频一区二区三区 | 五月激情av | 国产精品黄| 精品福利在线观看 | 中文字幕免费在线 | 国产精品第一国产精品 | 91私密视频| 欧美巨猛xxxx猛交黑人97人 | 久久久蜜桃 | 91精品国产综合久 | 精品久久免费 | 久久国产精品免费一区二区三区 | 国产搞逼视频 | 国外成人在线视频网站 | 在线国产网站 | 成人精品视频在线 | 欧美一区二区免费 | 国产成人精品免费 | 久久新 | 干色网| 性欧美三级 | 精品国产综合区久久久久久 | 日韩精品一二 | 91久久久久久久久久久 | 精品国产一二 | 成人高清av | 亚洲视频中文 | av片免费| 国产精品xxx在线观看www | 日本色网址 | 国产一区视频在线 | 亚洲视频在线一区 | 黄色二区 | 美女视频网站色 | 免费在线色 | 亚洲免费综合 | 中文字幕高清av | 欧美日韩视频一区二区三区 | 日日噜噜噜夜夜爽爽狠狠视频, | 在线观看国产一区 | 日韩欧美自拍 |