首頁 >web前端 >js教程 >web開發中事件處理規則有哪些

web開發中事件處理規則有哪些

php中世界最好的语言
php中世界最好的语言原創
2018-06-04 10:14:301675瀏覽

這次帶給大家web開發中事件處理規則有哪些,web開發中事件處理的注意事項有哪些,下面就是實戰案例,一起來看一下。

事件處理

我們知道事件觸發時,事件物件(event物件)會作為回呼參數傳入事件處理程序中,舉例說明:

// 不好的写法function handleClick(event) {  var pop = 
document
.getElementById('popup');
  popup.style.left = event.clientX + 'px';
  popup.style.top = event.clientY + 'px';
  popup.className = 'reveal';
}// 你应该明白addListener函数的意思addListener(element, 'click', handleClick);

這段程式碼只用到了event物件的兩個屬性:clientX和clientY。在將元素顯示在頁面里之前先用這兩個屬性個它作定位。儘管這段程式碼看起來非常簡單且沒有什麼問題,但實際上是不好的寫法,因為這種做法有其限制。

規則1:隔離應用邏輯

上段實例程式碼的第一個問題是事件處理程序包含了應用程式用邏輯(application logic)。應用邏輯是和應用相關的功能性程式碼,而不是和使用者行為相關的。上段實例程式碼中應用邏輯是在特定位置顯示一個彈出框。儘管這個互動應該是在使用者點擊某個特定元素時發生,但情況並不總是如此。

將應用程式邏輯從所有事件處理程序中抽離出來的做法是一種最佳實踐,因為說不定什麼時候其他地方就會觸發同一段邏輯。例如,有時你需要在使用者將滑鼠移到某個元素上時判斷是否顯示彈出框,或者當按下鍵盤上的某個鍵時也作同樣的邏輯判斷。這樣多個事件的處理程序執行了同樣的邏輯,而你的程式碼卻被不小心複製了多份。

將應用程式邏輯放置在事件處理程序中的另一個缺點是和測試有關的。測試時需要直接觸發功能程式碼,而不必透過模擬對元素的點擊來觸發。如果將應用邏輯放置於事件處理程序中,唯一的測試方法是製造事件的觸發。儘管某些測試框架可以模擬觸發事件,但實際上這不是測試的最佳方法。呼叫功能性程式碼最好的做法就是單一的函數呼叫。

你總是需要將應用邏輯和事件處理的程式碼分開。如果要對上一段實例程式碼進行重構,第一步是將處理彈出框邏輯的程式碼放入單獨的函數中,這個函數很可能會掛載於為該應用程式定義的一個全域物件上。事件處理程序應總是在一個相同的全域物件中,因此就有了以下兩個方法。

// 好的写法 - 拆分应用逻辑var MyApplication = {  handleClick: function (event) {    this.showPopup(event);
  },  showPopup: function (event) {    var pop = document.getElementById('popup');
    popup.style.left = event.clientX + 'px';
    popup.style.top = event.clientY + 'px';
    popup.className = 'reveal';
  }
};
addListener(element, 'click', function (event) {
  MyApplication.handleClick(event);
});

之前在事件處理程序中包含的所有應用邏輯現在轉移到了MyApplication.showPopup()方法中。現在MyApplication.handleClick()方法只做一件事情,也就是呼叫MyApplication.showPopup()。若應用邏輯被剝離出去,對同一段功能代碼的呼叫可以在多點發生,則不需要一定依賴某個特定事件的觸發,這顯然更加方便。但這只是拆解事件處理程序程式碼的第一步。

規則2:不要分發事件物件

在剝離出應用邏輯之後,上段實例程式碼還存在一個問題,就是event物件被無節制地分發。它從匿名的事件處理函數傳入了MyApplication.handleClick(),然後又傳入了MyApplication.showPopup()。如同上文所提到的,event物件上包含很多和事件相關的額外信息,而這段程式碼只用到了其中的兩個而已。應用邏輯不應依賴event物件來正確完成功能,原因如下:

方法介面並沒有顯示哪些資料是必要的。好的API一定是對於期望和依賴都是透明的。將event物件作為參數並不能告訴你event的哪些屬性是有用的,用來幹什麼?

因此,如果你想測試這個方法,你必須重新建立一個event物件並將它作為參數傳入。所以,你需要確切地知道這個方法使用了哪些訊息,這樣才能正確地寫出測試程式碼。

這些問題(指介面格式不清晰且自行建構event物件來用於測試)在大型Web應用程式中都是不可取的。程式碼不夠明晰就會導致bug。

最佳的方法是讓事件處理程序使用event物件來處理事件,然後拿到所有需要的資料傳給應用邏輯。例如,MyApplication.showPopup()方法只需要兩個數據,x座標和y座標。這樣我們將方法重寫一下,讓它來接收這兩個參數。

// 好的写法var MyApplication = {  handleClick: function (event) {    this.showPopup(event.clientX, event.clientY);
  },  showPopup: function (x, y) {    var pop = document.getElementById('popup');
    popup.style.left = x + 'px';
    popup.style.top = y + 'px';
    popup.className = 'reveal';
  }
};
addListener(element, 'click', function (event) {
  MyApplication.handleClick(event);
});

在这段新重写的代码中,MyApplication.handleClick()将x坐标和y坐标传入了MyApplication.showPopup(),代替了之前传入的事件对象。可以很清晰地看到MyApplication.showPopup()所期望传入的参数,并且在测试或代码的任意位置都可以很轻易地直接调用这段逻辑,比如:

// 这样调用非常棒MyApplication.showPopup(10, 10);

当处理事件时,最好让事件处理程序成为接触到event对象的唯一的函数。事件处理程序应当在进入应用逻辑之前针对event对象执行任何必要的操作,包括阻止默认事件或阻止事件冒泡,都应当直接包含在事件处理程序中。比如:

// 好的写法var MyApplication = {  handleClick: function (event) {    // 假设事件支持DOM Level2
    event.preventDefault();
    event.stopPropagation();    // 传入应用逻辑
    this.showPopup(event.clientX, event.clientY);
  },  showPopup: function (x, y) {    var pop = document.getElementById('popup');
    popup.style.left = x + 'px';
    popup.style.top = y + 'px';
    popup.className = 'reveal';
  }
};
addListener(element, 'click', function (event) {
  MyApplication.handleClick(event);
});

在这段代码中,MyApplication.handleClick()是事件处理程序,因此它在将数据传入应用逻辑之前调用了event.preventDefault()和event.stopPropagation(),这清除地展示了事件处理程序和应用逻辑之间的分工。因为应用逻辑不需要对event产生依赖,进而在很多地方都可以轻松地使用相同的业务逻辑,包括写测试代码。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样利用JS做出引用传递与值传递

如何做出node.js界面

以上是web開發中事件處理規則有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn