JavaScript疑難雜症系列-事件

事件這塊知識點雖然是老生長談的,但對於我來講多多整理,多多感悟,溫故知新,每次看看這塊都有不一樣的收穫.( 在這裏我不會長篇大論,只會挑重點;具體的小夥伴們自行查找)

什麼是事件

在編程時系統內發生的動做或者發生的事情.
系統經過它來告訴編程者,在編程者願意的狀況下,編程者一某種方式對它作出迴應.

添加事件方式

元素屬性

var btn = document.querySelector('button');

btn.onclick = function() {
  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
  document.body.style.backgroundColor = rndCol;
}

或者

var btn = document.querySelector('button');

function bgChange() {
  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
  document.body.style.backgroundColor = rndCol;
}

btn.onclick = bgChange

行內事件

<button onclick="bgChange()">Press me</button>

function bgChange() {
  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
  document.body.style.backgroundColor = rndCol;
}

或者

<button onclick="alert('Hello, this is my old-fashioned event handler!');">Press me</button>

註冊事件監聽

addEventListener()和removeEventListener();

btn.addEventListener('click', function() {
  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
  document.body.style.backgroundColor = rndCol;
});

或者

btn.removeEventListener('click', bgChange);

優缺點

  • 元素屬性
優:
     1. 兼容性好
     2. 行爲的分離
     3.便於操做當事對象,由於function是做爲on***的屬性出現的,可直接用this引用當事對象
缺: 
     1. 給同一個監聽器註冊多個處理器,後面的會覆蓋前面
     btn.onclick=function(){alert('a')};
     btn.onclick=function(){alert('b')};
  • 行內事件
優:
     1. 兼容性好,是最先的事件處理方法
     2. 方便快捷
缺: 
     1. 代碼雜糅
     2. 難以管理和效率低下,一個按鈕看起來還好,可是若是有一百個按鈕呢?得在文件中加上100個屬性
     3. 文檔很難解析
  • 註冊事件監聽
優:
     1. 它容許爲事件添加多個單獨的處理程序。這對於DHTML庫或Mozilla擴展尤爲有用,即便使用其餘庫/擴展也須要很好的工做
     2. 它可讓你更好地控制階段,當聽者被激活(捕獲與冒泡)
     3. 它適用於任何DOM元素,而不只僅是HTML元素
     4. 行爲的分離 
缺:
    兼容性(不過網上有不少成熟的hack);

事件對象

具體請看event詳解-https://developer.mozilla.orgcss

  • 在觸發DOM上的某個事件時,會在事件處理程序函數中會產生一個事件對象event,這個對象中包含着全部與事件有關的信息。包括致使事件的元素、事件的類型以及其餘與特定事件相關的信息.
var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
    alert(event.type); //"click"
}
btn.addEventListener("click", function(event) {
    alert(event.type); //"click"
}, false);

event.currentTarget與event.target

事件對象event的target屬性始終是事件剛剛發生的元素的引用
  • 例如,你可能有一組16塊方格,當它們被點擊時就會消失。用e.target老是能準確選擇當前操做的東西(方格)並執行操做讓它消失,而不是必須以更困難的方式選擇它.
var divs = document.querySelectorAll('div');

for (var i = 0; i < divs.length; i++) {
  divs[i].onclick = function(e) {
    e.target.style.backgroundColor = bgChange();
  }
}

阻止默認行爲(event.preventDefault())

  • 有時,你會遇到一些狀況,你但願事件不執行它的默認行爲例如自定義註冊表單
var form = document.querySelector('form');
var fname = document.getElementById('fname');
var lname = document.getElementById('lname');
var submit = document.getElementById('submit');
var para = document.querySelector('p');
form.onsubmit = function(e) {
  if (fname.value === '' || lname.value === '') {
    e.preventDefault();
    para.textContent = 'You need to fill in both names!';
  }
}

事件冒泡及捕獲(event.stopPropagation())

描述事件觸發時序問題的術語。
事件捕獲指的是從document到觸發事件的那個節點,即自上而下的去觸發事件。
事件冒泡是自下而上的去觸發事件。
綁定事件方法的第三個參數,就是控制事件觸發順序是否爲事件捕獲。true,事件捕獲;false,事件冒泡。默認false,即事件冒泡

圖片描述

事件委託

冒泡還容許咱們利用事件委託——這個概念依賴於這樣一個事實,若是你想要在大量子元素中單擊任何一個均可以運行一段代碼,您能夠將事件監聽器設置在其父節點上,並將事件監聽器氣泡的影響設置爲每一個子節點,而不是每一個子節點單獨設置事件監聽器

如:鼠標放到li上對應的li背景變灰編程

<ul>
    <li>item1</li>
    <li>item2</li>
    <li>item3</li>
    <li>item4</li>
    <li>item5</li>
    <li>item6</li>
</ul>
  • 利用事件冒泡實現
$("ul").on("mouseover",function(e){
     $(e.target).css("background-color","#ddd").siblings().css("background-color","white");
})
  • 給全部li都綁上事件
$("li").on("mouseover",function(){
      $(this).css("background-color","#ddd").siblings().css("background-color","white");
})
代碼簡潔程度上,二者是相若彷彿的。
前者少了一個遍歷全部li節點的操做,因此在性能上確定是更優的
若是在綁定事件完成後,頁面又動態的加載了一些元素
第二種方案,因爲綁定事件的時候item7還不存在,因此爲了效果,咱們還要給它再綁定一次事件.

自定義事件(DOM的事件模擬又稱「僞DOM自定義事件」)

  • js原生自定義事件分三個階段(創造、初始化、觸發)
摘自 https://developer.mozilla.org...

(1). 創造數組

var event = document.createEvent(type);
type:是一個字符串,表示要建立的事件類型。事件類型可能包括是一個字符串,表示要建立的事件類型。
事件類型可能包括"UIEvents", "MouseEvents", "MutationEvents", 或者 "HTMLEvents"

(2) 初始化app

event.initEvent('build', true, true);
於初始化經過DocumentEvent接口建立的Event的值。支持三個參數:initEvent(eventName, canBubble,preventDefault)
分別表示事件名稱,是否能夠冒泡,是否阻止事件的默認操做

(3). 觸發dom

elem.dispatchEvent(event);
參數event表示事件對象,是createEvent()方法返回的建立的Event對象

監聽方法函數

elem.addEventListener('build', function (e) {
// e.target matches elem
}, false);
  • jq自定義dom事件

(1). trigger()性能

經常使用模擬
  模擬方法操做
   $("#btn").trigger("click");
     或者    
   $("#btn").click();
自定義事件
   $("#btn").on("myClick", function () {
       $("#test").append("<p>個人自定義事件。</p>");
    });    
   $("btn").trigger("myClick");
傳遞數據
  trigger(tpye[,datea]);
  第一個參數是要觸發的事件類型,
  第二個單數是要傳遞給事件處理函數的附加數據,以數組形式傳遞。
  一般能夠經過傳遞一個參數給回調函數來區別此次事件是代碼觸發的仍是用戶觸發的
   $("#btn").bind("clickCustomize", function (event, message1, message2) { //獲取數據
        $("#test").append("p" + message1 + message2 + "</p>");
   });
   $("#btn").trigger("clickCustomize",["個人自定義","事件"]); //傳遞兩個數據
   $(「#btn」).trigger(「clickCustomize」,["個人自定義","事件"]); //傳遞兩個數據

(2). triggerHandler();(阻止默認事件)ui

triggerHandler("lickCustomize");
  • DOM自定義事件優點與劣勢:

(1)、優點:this

一、自定義事件徹底由咱們控制觸發時機,這就意味着實現了一種 JavaScript 的解耦。咱們能夠把多個關聯但邏輯複雜的操做利用自定義事件的機制靈活地控制好
二、既然綁定也能夠解綁,若是不須要了,直接移除綁定事件

(2)、劣勢spa

一、兼容性差,要本身hack(jq除外)
相關文章
相關標籤/搜索