天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

事件模塊的演變

  本篇開始將回顧下Javascript的事件機(jī)制。同時會從一個最小的函數(shù)開始寫到最后一個具有完整功能的,強(qiáng)大的事件模塊。為敘述方便將響應(yīng)函數(shù)/回調(diào)函數(shù)/事件Listener/事件handler都稱為事件handler。

  先看看頁面中添加事件的幾種方式:

  1,直接將JS代碼寫在HTML上

<div onclick="alert(4);">Div1 Element</div>

  上一篇我們封裝了一個addEvent:

  1,解決了IE6/7/8下事件handler中this為window的錯誤。

  2,并且統(tǒng)一了事件對象作為事件handler的第一個參數(shù)傳入。

  這篇把對應(yīng)的刪除事件的函數(shù)補(bǔ)上。上一篇中fn在IE6/7/8中實(shí)際上被包裝了,IE6/7/8中真正的handler是el["e"+fn]。因此刪除時要用到它。同時將兩個方法掛在一個對象E上,add,remove分別添加和刪除事件。

E = {
//添加事件
add : function(el, type, fn){
if(el.addEventListener){
el.addEventListener(type, fn,
false);
}
else{
el[
'e'+fn] = function(){
fn.call(el,evt);
};
el.attachEvent(
'on' + type, el['e'+fn]);
}
},
//刪除事件
remove : function(el, type, fn){
if(el.removeEventListener){
el.removeEventListener(type, fn,
false);
}
else if(el.detachEvent){
el.detachEvent(
'on' + type, el['e'+fn]);
}
}
};

  上一篇中的add有個問題,對同一類型事件添加多個hanlder時,IE6/7/8下會無序,如:

<div id="d1" style="width:200px;height:200px;background:gold;"></div>
<script type="text/Javascript">
var el = document.getElementById('d1');
function handler1(){alert('1');}
function handler2(){alert('2');}
function handler3(){alert('3');}
function handler4(){alert('4');}
function handler5(){alert('5');}
E.add(el,
'click', handler1);
E.add(el,
'click', handler2);
E.add(el,
'click', handler3);
E.add(el,
'click', handler4);
E.add(el,
'click', handler5);
</script>

  上一篇解決了IE6/7/8中同一個類型事件的多個handler執(zhí)行無序的情況,為此改動也是較大的。實(shí)現(xiàn)幾乎與前一個版本完全不同。但好處也是明顯的。

  有時需要添加只執(zhí)行一次的事件handler,為此給add方法添加第四個參數(shù)one,one為true則該事件handler只執(zhí)行一次。

<div id="d1" style="width:200px;height:200px;background:gold;"></div>
<script>
var el = document.getElementById('d1');
function handler(){alert(5)}
E.add(el,
'click', handler, true);
</script>

  上一篇正式推出了我的事件模塊event_v1,已經(jīng)搭起了它的初始框架。或許有人要說,與眾多JS庫或框架相比,它還沒有解決事件對象的兼容性問題。是的,我故意將此放到后續(xù)補(bǔ)充。因?yàn)槭录ο蟮募嫒菪詥栴}太多了,太繁瑣了。

  這篇我將引入一個私有的_fixEvent函數(shù),add中將調(diào)用該函數(shù)。_fixEvent將修復(fù)(或稱包裝)原生事件對象,返回一個標(biāo)準(zhǔn)的統(tǒng)一接口的事件對象。如下:

function _fixEvent( evt, el ) {
var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
len
= props.length;
function now() {return (new Date).getTime();}
function returnFalse() {return false;}
function returnTrue() {return true;}
function Event( src ) {
this.originalEvent = src;
this.type = src.type;
this.timeStamp = now();
}
Event.prototype
= {
preventDefault:
function() {
this.isDefaultPrevented = returnTrue;
var e = this.originalEvent;
if( e.preventDefault ) {
e.preventDefault();
}
e.returnValue
= false;
},
stopPropagation:
function() {
this.isPropagationStopped = returnTrue;
var e = this.originalEvent;
if( e.stopPropagation ) {
e.stopPropagation();
}
e.cancelBubble
= true;
},
stopImmediatePropagation:
function() {
this.isImmediatePropagationStopped = returnTrue;
this.stopPropagation();
},
isDefaultPrevented: returnFalse,
isPropagationStopped: returnFalse,
isImmediatePropagationStopped: returnFalse
};

var originalEvent = evt;
evt
= new Event( originalEvent );

for(var i = len, prop; i;) {
prop
= props[ --i ];
evt[ prop ]
= originalEvent[ prop ];
}
if(!evt.target) {
evt.target
= evt.srcElement || document;
}
if( evt.target.nodeType === 3 ) {
evt.target
= evt.target.parentNode;
}
if( !evt.relatedTarget && evt.fromElement ) {
evt.relatedTarget
= evt.fromElement === evt.target ? evt.toElement : evt.fromElement;
}
if( evt.pageX == null && evt.clientX != null ) {
var doc = document.documentElement, body = document.body;
evt.pageX
= evt.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
evt.pageY
= evt.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
}
if( !evt.which && ((evt.charCode || evt.charCode === 0) ? evt.charCode : evt.keyCode) ) {
evt.which
= evt.charCode || evt.keyCode;
}
if( !evt.metaKey && evt.ctrlKey ) {
evt.metaKey
= evt.ctrlKey;
}
if( !evt.which && evt.button !== undefined ) {
evt.which
= (evt.button & 1 ? 1 : ( evt.button & 2 ? 3 : ( evt.button & 4 ? 2 : 0 ) ));
}
if(!evt.currentTarget) evt.currentTarget = el;

return evt;
}

it知識庫事件模塊的演變,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 岛国大片在线观看完整版 | 啊灬啊灬啊灬快高潮视频 | 天天躁日日躁狠狠躁午夜剧场 | DASD-700美谷朱里 | 高清国语自产拍免费 | 日本老妇一级特黄aa大片 | 无限资源日本2019版 | 99久免费精品视频在线观看2 | 青柠电影高清在线观看 | 97资源站超碰在线视频 | 日本漫画母亲口工子全彩 | 丰满大爆乳波霸奶 | 欧美国产一区二区三区激情无套 | 亚洲国产成人精品久久久久 | 国产女人乱人伦精品一区二区 | 好湿好滑好硬好爽好深视频 | 国精品产露脸偷拍视频 | 精品久久99麻豆蜜桃666 | 午夜DY888国产精品影院 | 日韩a在线看免费观看视频 日韩a视频在线观看 | 日韩欧美中文字幕在线二视频 | 日本一二三区在线视频 | 色婷婷粉嫩AV精品综合在线 | 花蝴蝶hd免费 | 国产精品久久久久久人妻精品流 | 最近中文字幕MV免费看 | 乱码中字在线观看一二区 | 御姐被吸奶 | 99久久99久久久99精品齐 | 中文字幕在线观看网站 | 久久久久99精品成人片三人毛片 | 一区二区三区国产 | 国产人在线成免费视频 | 日韩精品免费在线观看 | 草草久久久亚洲AV成人片 | 中文视频在线 | 久久国产精品二区99 | 国产专区青青在线视频 | 久久综合久久鬼色 | 秋霞在线观看视频一区二区三区 | 在线 | 果冻国产传媒61国产免费 |