国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript 事件綁定及深入

2019-11-20 12:41:48
字體:
來源:轉載
供稿:網友

事件綁定分為兩種:

一種是傳統事件綁定(內聯模型/腳本模型);上一章內容;
一種是現代事件綁定(DOM2級模型);現代事件綁定在傳統事件綁定基礎上提供了更強大的功能;
一 傳統事件綁定的問題

// 腳本模型將一個函數賦值給一個事件處理函數;  var box = document.getElementById('box');  // 獲取元素;  box.onclick = function(){          // 元素點擊觸發事件;    alert('Lee');  }// 問題一:一個事件處理函數觸發兩次事件;  window.onload = function(){         // 第一組程序;    alert('Lee');  }  window.onload = function(){         // 第二組程序;    alert('Mr.Lee');  }  // PS:當兩組程序同時執行的時候,后面一個會把前面一個完全覆蓋;  // 導致前面的window.onload完全失效了;// 解決方案:  window.onload = function(){         // 第一組事件處理程序,會被覆蓋;    alert('Lee');  }  if(typeof window.onload == 'function'){   // 判斷之前是否有window.onload;    var saved = null;            // 創建一個保存器;    saved = window.onload;          // 把之前的window.onload保存起來;  }  window.onload = function(){         // 下一個要執行的事件;    // saved()=window.onload = function    if(saved)saved();            // 判斷之前是否有事件,如果有則先執行之前保存的事件;    alert('Mr.Lee');             // 執行本事件的代碼;  }
// 問題二:事件切換器  box.onclick = boBlue;             // 第一次執行toBlue();  function toRed(){    this.className = 'red';    this.onclick = toBlue;          // 第三次執行roBlue(),然后來回切換;  }  function toBlue(){    this.className = 'blue';    this.onclick = toRed;          // 第二次執行toRed();  }  // 這個切換器在擴展的時候,會出現一些問題:  1.如果增加一個執行函數,那么會被覆蓋;  box.onclick = toAlert;            // 被增加的函數;  box.onclick = toBlue;            // toAlert被覆蓋了;  2.如果解決覆蓋問題,就必須包含同時執行;  box.onclick = function(){          // 包含進去,但可讀性降低;    toAlert();                // 第一次不會被覆蓋,但第二次又被覆蓋;    toBlue.call(this);            // 還必須把this傳遞到切換器里;  }
// 綜上三個問題:覆蓋問題/可讀性問題/this傳遞為題;// 我們創建一個自定義事件處理函數;  function addEvent(obj,type,fn){       // 取代傳統事件處理函數;    var saved = null;            // 保存每次觸發的事件處理函數;    if(typeof obj['on'+type] == 'function'){// 判斷是不是存在事件;      saved = obj['on'+type];       // 如果有,保存起來;    }    obj['on'+type] = function(){      // 然后執行;      if(saved)saved();          // 執行上一個;      fn.call(this);           // 執行函數,把this傳遞進去;    }  }  addEvent(window,'load',function(){    alert('Lee');              // 可以執行;  });  addEvent(window.'load',function(){    alert('Mr.Lee');            // 可以執行;  })// 用自定義事件函數注冊到切換器上查看效果:  addEvent(window,'load',function(){    var box = document.getElementById('box');    addEvent(box,'click',toBlue);  });  function toRed(){    this.className = 'red';    addEvent(this,'click',toBlue);  }  function toBlue(){    this.className = 'blue';    addEvent(this,'click',toRed);

二 W3C事件處理函數
// "DOM2級事件"定義了兩個方法,用于添加事件和刪除事件的處理程序:addEventListener()和removeEventListener();

// 所有DOM節點中都包含這兩個方法,并且它們都接收3個參數:事件名/函數/冒泡或捕獲的布爾值(true表示捕獲,false表示冒泡);  window.addEventListener('load',function(){    alert('Lee');  },false);  window.addEventListener('load',function(){    alert('Mr.Lee');  },false);  // PS:W3C的事件綁定好處:1.不需要自定義了;2.可以屏蔽相同的函數;3.可以設置冒泡和捕獲;  window.addEventListener('load',init,false);    // 第一次執行了;  window.addEventListener('load',init,false);    // 第二次被屏蔽了;  function init(){    alert('Lee');  }// 事件切換器  window.addEventListener('load',function(){    var box = document.getElementById('box');    box.addEventListener('click',function(){    // 不會被覆蓋/誤刪;      alert('Lee');    },false);    box.addEventListener('click',toBlue,false);  // 引入切換;  },false);  function toRed(){    this.className = 'red';    this.removeEventListener('click',toRed,false); // 移除事件處理函數;    this.addEventListener('click',toBlue,false);  // 添加需要切換的事件處理函數;   }  function toBlue(){    this.className = 'blue';    this.removeEventListener('click',toBlue,false);    this.addEventListener('click',toRed,false);  }// 設置冒泡和捕獲階段  document.addEventListener('click',function(){    alert('document');  },true);                    // 設置為捕獲;  document.addEventListener('click',function(){    alert('Lee');  },false);                    // 設置為冒泡;

三 IE事件處理函數
// IE中實現了與DOM中類似的兩個方法:attachEvent()和detachEvent();

// 這兩個方法接收相同的參數:事件名和函數;

// 在使用這兩組函數的時候,區別:// 1.IE不支持捕獲,只支持冒泡;// 2.IE添加事件不能屏蔽重復的函數;// 3.IE中的this指向的是window而不是DOM對象;// 4.在傳統事件上,IE是無法接受到event對象的;但使用了attachEvent()卻可以;  window.attachEvent('onload',function(){    var box = document.getElementById('box');    box.attachEvent('onclick',toBlue);  });  function toRed(){    var that = window.event.srcElement;    that.className = 'red';    that.detachEvent('onclick',toRed);    that.attachEvent('onclick',toBlue);  }  function toBlue(){    var that = window.event.srcElement;    that.className = 'blue';    that.detachEvent('onclick',toBlue);    that.attachEvent('onclick',toRed);  }  // PS:IE不支持捕獲;  // IE不能屏蔽;  // IE不能傳遞this,可以call過去;// 在傳統綁定上,IE是無法像W3C那樣通過傳參接受event對象;但如果使用了attachEvent()卻可以;  box.onclick = function(evt){    alert(evt);                // undefined;  }  box.attachEvent('onclick',function(evt){    alert(evt);                // object;    alert(evt.type);              // click;  });// 兼容IE和W3C的事件切換器函數;  function addEvent(obj,type,fn){        // 添加事件處理程序兼容;    if(obj.addEventListener){      obj.addEventListener(type,fn);    }else if(obj.attachEvent){      obj.attachEvent('on'+type,fn);    }  }  function removeEvent(obj,type,fn){      // 移除事件處理程序兼容;    if(obj.removeEventListener){      obj.removeEventListener(type,fn);    }esle if(obj.detachEvent){      obj.detachEvent('on'+type,fn);    }  }  function getTarget(evt){           // 得到事件目標;    if(evt.target){      return evt.target;    }else if(window.event.srcEleemnt){      return window.event.srcElement;    }  }

四 事件對象補充

1.relatedTarget// 這個屬性可以在mouseover和mouseout事件中獲取從哪里移入和從哪里移出的DOM對象;  box.onmouseover = function(evt){      // 鼠標移入box;    alert(evt.relatedTarget);        // 獲取移入box之前的那個元素;  }  box.onmouseout = function(evt){       // 鼠標移出box;    alert(evt.relatedTarget);        // 獲取移出box之后到的那個元素;  }// IE提供了兩組與之對應的屬性:fromElement和toElement;// 兼容函數  function getEarget(evt){    var e = evt || window.event;      // 得到事件對象;    if(e.srcElement){            // 如果支持srcElement,表示IE;      if(e.type == 'mouseover'){     // 如果是over事件;        return e.fromeElement;     // 就使用from;      }else if(e.type == 'mouseout'){   // 如果是out;        return e.toElement;       // 就使用to;      }    }else if(e.relatedTarget){       // 如果支持relatedTarget,表示W3C;      return e.relatedTarget;    }  }

2.阻止事件的默認行為

// 一個超鏈接的默認行為就點擊然后跳轉到指定的頁面;// 那么阻止默認行為就可以屏蔽跳轉的這種操作,而實現自定義操作;// 取消事件默認行為還有一種不規范的做法,就是返回false;  link.onclick = function(){    alert('Lee');                return false;              // 直接返回false,就不會跳轉了;  }  // PS:雖然return false;可以實現這個功能,但有漏洞;  // 第一:代碼必須寫到最后,這樣導致中間的代碼執行后,有可能執行不到return false;  // 第二:return false寫到最前那么之后的自定義操作就失敗了;  // 解決方案:在最前面就阻止默認行為,并且后面還能執行代碼;  function preDef(evt){            // 跨瀏覽器兼容阻止默認行為;    var e = evt || window.event;    if(e.preventDefault){      e.preventDefault();         // W3C,阻止默認行為;    }else{      e.returnValue = false;        // IE,阻止默認行為;    }  }
3.上下文菜單事件contextmenu// 當我們右擊網頁的時候,會自動出現windows自帶的菜單;// 那么我們可以使用contextmenu事件來修改我們指定的菜單;但前提是把右擊的默認行為取消;  addEvent(window,'load',function(){    var text = docuemnt.getElementById('text');    addEvent(text,'contextmenu',function(evt){    // 添加右鍵菜單事件處理程序;      var e = evt || window.event;      preDef(e);                  // 阻止默認行為函數;      var menu = document.getElementById('menu');  // 找到自定義的menu對象;      menu.style.left = e.clientX+'px';       // 確定自定義menu在屏幕上的位置;      menu.style.top = e.clientX+'px';      menu.style.visibility = 'visible';      // 設置自定義menu的屬性為可見;      addEvent(document,'click',function(){     // 給document添加單擊事件處理程序;        docuemnt.getElementById('myMenu').style.visibility = 'hidden';  //將自定義的menu隱藏;      });    });  });

4.卸載前事件beforeunload

// 這個事件可以幫助在離開本頁的時候給出相應的提示;"離開"或"返回"操作;  addEvent(window.'beforeunload',function(evt){    var evt = event || window.event;    var message = '是否離開此頁?';    evt.returnValue = message;    return message;  });

5.鼠標滾輪(mousewheel)和DOMMouseScroll

// 用于獲取鼠標上下滾輪的距離;  addEvent(docuemnt,'mousewheel',function(evt){    // 非Firefox;    alert(getWD(evt));  });  addEvent(docuemnt,'DOMMouseScroll',function(evt){  // Firefox;    alert(getWD(evt));  });   function getWD(evt){    var e = evt || window.event;    if(e.wheelDelta){                // mousewheel事件的滾動值保存在wheelDelta里;      return e.wheelDelta;    }else if(e.detail){               // DOMMouseScroll事件的滾動值保存在detail里;      return -evt.detail*30;            // 保持計算的統一;    }  }
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 汉中市| 乐亭县| 潞西市| 宜春市| 高安市| 沂南县| 舞钢市| 锦屏县| 资中县| 万源市| 德化县| 图们市| 江源县| 文水县| 尉犁县| 施秉县| 阳泉市| 清涧县| 泰来县| 宝鸡市| 嘉定区| 大化| 慈利县| 和顺县| 汶上县| 广河县| 德兴市| 阿克陶县| 九寨沟县| 茌平县| 新营市| 松阳县| 阿鲁科尔沁旗| 湖口县| 瑞金市| 温宿县| 德阳市| 瑞金市| 嵩明县| 伊金霍洛旗| 义乌市|