js事件拓展

事件總括

    *   1、行為本身:瀏覽器天生就賦予其行為onclick onmouseover onmouseout (onmouseenter onmouseleave不會產(chǎn)生事件冒泡)  onmousemove
    *   onmousedown onmouseup onmousewheel onscroll onresize onload onunload onfocus onblur onkeydown onkeyup。。。
    *   沒有給上述行為綁定方法,事件也存在,觸發(fā)后執(zhí)行,只是什么都不做而已
    *   2、事件綁定:
    *       oDiv.onclick=function...     DOM0級事件綁定  onclick行為定義在oDiv的私有屬性上
    *       oDiv.addEventListener('click',function(){},false)  DOM2級事件 addEventListener這個屬性是定義在EventTarget
    *       這個類的原型上

事件的傳播機制

    * 捕獲階段:從里往外一次查找元素
    * 目標階段:當(dāng)前事件源本身操作
    * 冒泡階段:從內(nèi)到外依次觸發(fā)相關(guān)行為(最常用)
事件傳播機制.jpg
  • 冒泡和捕獲
    捕獲就是:爹(target)的事件觸發(fā),兒子和孫子的相同的事件也會被觸發(fā)
    冒泡就是:兒子(target)觸發(fā)事件,爹和祖宗的相同的事件也會被觸發(fā)
    阻止冒泡

e.stopPropagation會阻止冒泡,意思就是到我為止,我的爹和祖宗的事件就不要觸發(fā)了。

事件委托

把事件綁定到目標元素群的父元素上,通過e.target來判斷點擊的真正目標,在執(zhí)行相應(yīng)的程序

事件冒泡與默認行為

讓事件處理函數(shù)return false來阻止冒泡和默認行為, 可以認為return false做了三件事情:
1.stopPropagation();
2.preventDefault();
3.立即結(jié)束當(dāng)前函數(shù)并返回。

DOM 0級事件

  • 給元素對象的某一個私有的屬性賦一個值(一個函數(shù)的值),當(dāng)事件觸發(fā)的時候找到對應(yīng)的屬性值,并且執(zhí)行
  • DOM 0級事件只能給元素的某一個事件綁定一次方法,最后綁定的方法會把前面綁定的所有的方法都覆蓋掉

DOM 2級事件

  • 給當(dāng)前元素的某一個事件綁定的方法都放置在事件池中,當(dāng)事件執(zhí)行的時候,會把事件池里的所有的方法依次去執(zhí)行
    1.addEventListener 綁定事件
    2.removeEventListener 移除事件
  • DOM 2級事件可以為當(dāng)前元素的某一個事件綁定多個不同的方法,當(dāng)前事件觸發(fā)時,會到對應(yīng)的事件池中把所有的綁定的方法依次執(zhí)行。
  • DOM2和DOM0事件共存,不會沖突 。
深入
  • DOM2可以給元素的某一個事件行為綁定多個方法
    1.事件觸發(fā)時執(zhí)行對應(yīng)的方法們,此時不管哪個方法中的this指向的都是當(dāng)前元素
    2.我們按順序把順序增加到‘事件池’中,當(dāng)觸發(fā)事件時,方法按照添加的順序依次執(zhí)行
    3.如果當(dāng)前的方法已經(jīng)給元素的這個行為綁定過一次了,事件池中這個方法不會重復(fù)添加
  • DOM2中,我們一般綁定的都是實名函數(shù),只有這樣,當(dāng)移除的時候才知道移除誰,
    在IE6-8中綁定的方法只能在冒泡階段發(fā)生。
  • DOM2事件在IE6-8中兼容問題。
    1.綁定的語法不一樣,IE6-8中,使用attachEvent、detachEvent
    2.標準瀏覽器this指向當(dāng)前元素,IE6-8指向window
    3.重復(fù)綁定問題,IE6-8 相同的方法可以重復(fù)綁定
    4.順序問題,標準瀏覽器按綁定的順序執(zhí)行函數(shù),IE6-8 沒有順序
function on(ele,type,fn){
  if(/^self/.test(type)){//說明是自定義的事件   都帶前綴self
    if(!ele['aself'+type]){
      ele['aself'+type]=[]//創(chuàng)建自定義事件的事件池
    }
    var a=ele['aself'+type];
    for(var i=0;i<a.length;i++){
      if(a[i]==fn)return;
    }
      a.push(fn);//如果這個函數(shù)沒有添加過事件池,那么就添加進去
  }else if(ele.addEventListener){//標準瀏覽器的事件添加
    ele.addEventListener(type,fn,false);
  }else{//IE瀏覽器的事件添加
    if(!ele['aEvent'+type]){
      ele['aEvent'+type]=[];
    }
    var a=ele['aEvent'+type];
    for(var i=0;i< a.length;i++){
       if(a[i]==fn)return;
       ele.attach('on'+type,function(){//提前綁定好事件,只要觸發(fā)就執(zhí)行run
          run.call(ele);
       })
    }
    a.push(fn);
  }
}
function run (){
  var e=e||window.event;
  if(!e.target){
    e.target=e.srcElement;
    e.pageX=e.clientX+(document.documentElement.scrollLeft||document.body.scrollLeft);
e.pageY= e.clientY+(document.documentElement.scrollTop||document.body.scrollTop)
  }
    e.stopPropagation=function(){
      e.cancelBubble=true;
    }
    e.preventDefault=function(){
      e.returnValue=false
    }
    var a= this['aEvent'+type];
    if(a){
      for(var i=0;i< a.length;i++){
        var fn=a[i];
        if(type fn == 'function'){
          fn.call(this,e);
        }else{
          a.splice(i,1)
          i--;
      }
    }
  }
}
function selfRun(selfType,e){
        var a=this['aSelf'+selfType];
        if(a){
            for(var i=0;i< a.length;i++){
                var fn=a[i];
                if(type fn == 'function'){
                    fn.call(this,e);
                }else{
                    a.splice(i,1)
                    i--;
                }
            }
        }
    }
function off(ele,type,fn){
        if(/^self/.test(type)){
            var a=ele['aSelf'+type];
            if(a){
                for(var i=0;i< a.length;i++){
                    if(a[i]==fn){
                        a[i]=null;
                        return;
                    }
                }
            }
        }
        if(ele.removeEventListener){
            ele.removeEventListener(type,fn,false);
        }else{
            var a=ele['aEvent'+type]
            if(a){
                for(var i=0;i< a.length;i++){
                    if(a[i]==fn){
                        a[i]=null;
                        return;
                    }
                }
            }
        }
    }

自定義事件(訂閱發(fā)布模式)

function EventEmitter(){
}
EventEmitter.prototype.on=function(type,fn){
  if(!this['aEmitter'+type]){
    this['aEmitter'+type]=[]
  }
  var a=this['aEmitter'+type];
  for(var i=0i<a.length;i++){
    if(a[i]==fn)return;
    a.push(fn);
  }
}
EventEmitter.prototype.run=function(type,e){
  var a=this['aEmitter'+type];
  if(a){
    for(var i=0i<a.length;i++){
      if(typeof a[i]=='function'){
        a[i].call(this,e);
      }else{
        a.split(i,1);
        i--;
      };
    }
  }
}
EventEmitter.prototype.off=function(type,fn){
  var a=this['aEmitter'+type];
  if(a){
    for(var i=0i<a.length;i++){
      if(a[i]==fn){
        a[i]=null;
      };
    }
  }
}

jquery綁定

$(ele).bind() ------在新版本已經(jīng)淘汰
  • 將會給所有匹配的元素都綁定一次事件,當(dāng)元素很多時性能會變差。 而且后來動態(tài)新增的元素不會被綁定。

  • 可以添加自定義事件 然后用trigger來手動觸發(fā)該事件。

  • 多個事件類型可以通過用空格隔開一次性綁定:

$('#foo').bind('mouseenter mouseleave', function() {
  $(this).toggleClass('entered');
});
  • 可以通過傳遞一個事件類型/處理函數(shù)的數(shù)據(jù)鍵值對映射來綁定多個事件處理程序
$('#foo').bind({
  click: function() {
    // do something on click
  },
  mouseenter: function() {
    // do something on mouseenter
  }
});
$(ele).delegate()
  • 它將事件處理函數(shù)綁定在指定的根元素上, 由于事件會冒泡,它用來處理指定的子元素上的事件。
  • 用于事件委托。
$("table").delegate("td", "click", function() {
  $(this).toggleClass("chosen");
});

是等價于下面使用.on()的代碼:

$("table").on("click", "td", function() {
  $(this).toggleClass("chosen");
});
$(ele).on()
  • 綁定事件最通用的方法,用$(ele).off()解綁事件
  • 向事件處理函數(shù)中傳入數(shù)據(jù),并且在事件處理函數(shù)中通過名字來獲取傳入的數(shù)據(jù):
function myHandler(event) {
  alert(event.data.foo);
}
$("p").on("click", {foo: "bar"}, myHandler)
$(ele).one()
  • 處理函數(shù)在每個元素上每種事件類型最多執(zhí)行一次
$( "#foo" ).one( "click", function() {
  alert( "這個函數(shù)只會執(zhí)行一次" );
});
  • 如果該方法的第一個參數(shù)包含多個用空格分隔的事件類型的話,那么每種類型的事件被觸發(fā)時,處理函數(shù)僅會被每個事件類型調(diào)用一次。
$( "#foo" ).one( "click mouseover", function( event ) {
  alert( "The " + event.type + " event happened!" );
});
$(ele).trigger()
  • 用來觸發(fā)事件
$('#foo').on('click', function() {
      alert($(this).text());
    });
 $('#foo').trigger('click');//相當(dāng)于用戶點擊了該元素
  • 若要觸發(fā)通過 jQuery 綁定的事件處理函數(shù),而不觸發(fā)原生的事件,使用.triggerHandler() 來代替。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么是事件: 我們可以簡單的把事件理解為瀏覽器的感知系統(tǒng)。比如說:他可以感覺到用戶是否點擊(click)了頁面、鼠...
    張松1366閱讀 6,989評論 1 6
  • 總結(jié): 鼠標事件 1.click與dbclick事件$ele.click()$ele.click(handler(...
    阿r阿r閱讀 1,714評論 2 10
  • 第1章 鼠標事件 1-1 jQuery鼠標事件之click與dbclick事件 用交互操作中,最簡單直接的操作就是...
    mo默22閱讀 1,343評論 0 6
  • 天上飄著細雨 水面漾著漣漪 走在水鎮(zhèn)的小路上 我遇見了你 你的眼睛望著天 你的心中可下著雨 你用手心接雨滴 你的心...
    大毛愣星閱讀 638評論 0 0
  • 《管理的常識》拆書分享-聽聽管理咨詢菜鳥談管理(二) 第二部分:對績效負責(zé)的管理觀 1) 管理只對績效負責(zé) ...
    淺淺的夕陽閱讀 730評論 0 2

友情鏈接更多精彩內(nèi)容