DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> JavaScript綜合知識 >> JavaScript使用自定義事件實現簡單的模...
JavaScript使用自定義事件實現簡單的模...
編輯:JavaScript綜合知識     

 WEB前端最常見驅動方式就是事件了, 所有交互等等都是通過事件,前端的常見事件有:


UI事件;
焦點事件;
鼠標事件;
滾輪事件;
文本事件;
鍵盤事件;
變動事件;

現在網頁上有一個輸入框, 如果我們要對用戶輸入的字符串進行過濾, 或者是截獲用戶的輸入進行處理的話, 我們要腫麼辦

同學們紛紛舉手說:“老師,我知道,是使用添加事件“,

老師也很欣慰地點了點頭, 這群家伙真的是越來越聰明了,

老師又問了”如果要取消用戶的輸入怎麼辦了“,

坐在最前排眼睛最小的同學急忙說”ev.preventDefault(),ev.returnValue = false;"

老師又說“不錯啊,都學會搶答了啊, 我褲子都脫了, 你就答這個2?”



過了一秒鐘, 又一位同學主動跑到黑板這邊寫了如下的代碼:

運行下面代碼
復制代碼

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MAKER</title>
</head>
<body>
<div id="log">
Log:
</div>
<input id="text">data</input>

<script>
window.onload = init;

if(console&&console.log) {
var originalLog = console.log;
var log = document.getElementById("log");
console.log = function(arg) {
var eDiv = document.createElement("div");
eDiv.innerHTML = typeof arg === "string" ? arg : arg.toString();
log.appendChild( eDiv );
originalLog.apply(console, arguments);
};
};

function init () {
var eText = document.getElementById("text");
eText.addEventListener("keypress", function( ev ) {
//邏輯全部在這裡面, 很簡單吧;
var code = ev.which = ev.which ev.keyCode ev.charCode;
console.log( code );
if(code > 80) {
console.log("code>80");
};
if(ev.shiftKey === true) {
console.log("shift key is pressed!")
}
});
};
</script>
</body>
</html>

復制代碼

"哎喲,不錯哦,這個*x"老師說道:"這個就是我們最常用的方法, 直接為元素綁定了keypress事件,然後通過這個事件的回調對用戶的輸入進行處理";

如果在事件裡面的代碼多了, 我們又可以把事件的代碼單獨取出來作為一個函數:

運行下面代碼
復制代碼

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MAKER</title>
</head>
<body>
<div id="log">
Log:
</div>
<input id="text">data</input>

<script>
window.onload = init;

if(console&&console.log) {
var originalLog = console.log;
var log = document.getElementById("log");
console.log = function(arg) {
var eDiv = document.createElement("div");
eDiv.innerHTML = typeof arg === "string" ? arg : arg.toString();
log.appendChild( eDiv );
originalLog.apply(console, arguments);
};
};
var 我是事件 = function(ev) {
//邏輯全部在這裡面, 很簡單吧;
var code = ev.which = ev.which ev.keyCode ev.charCode;
console.log( code );
if(code > 80) {
console.log("code>80");
};
if(ev.shiftKey === true) {
console.log("shift key is pressed!")
};
};
function init () {
var eText = document.getElementById("text");
eText.addEventListener("keypress", function( ev ) {
我是事件(ev);
});
};
</script>
</body>
</html>

復制代碼

看起來清楚多了是吧, 但是在大的項目中(我說的是如果哇), 我們想要充分解耦代碼, 可以事件裡面的代碼全部重新分開:

函數1 :console.log( code );

函數2:

if(code > 80) {

console.log("code>80");

};

函數3: 
if(ev.shiftKey === true) {
console.log("shift key is pressed!")
};
好吧,現在問題來了....

現在有要上菜了哇, JS中的自定義事件, 充分利用JS的事件機制,
抄自百科:對於自定義事件最需要了解的一點是,您的代碼必須導致這些事件發生。這些事件不會為響應用戶或系統的動作而自動發生,即使能夠編寫導致事件確實以這種方式發生的代碼也不例外。包含自定義事件的類模塊還必須包括一個喚起事件的公有方法。這個方法通過調用 RaiseEvent 語句並傳入為事件定義的任何參數來喚起事件。這些參數按順序傳入為響應事件而運行的事件過程中
自定義事件就是一種的設計模式,比如訂閱者發布者模式, 觀察者模式等等, 都是自定義事件基礎上的模式(個人觀點, 勿拍磚), 關鍵是很多大神寫代碼喜歡用這一種模式寫, 那麼我們也可以借鑒, 這樣就夠了;
我們現在把上面那段通過自定義事件的方式寫出來:

運行下面代碼
復制代碼

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MAKER</title>
</head>
<body>
<script>
//d為目標對象, b為一個函數對象;
var __extends = this.__extends function (d, b) {
//繼承了靜態屬性
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
//繼承了原型
__.prototype = b.prototype;
d.prototype = new __();
};

var EventEmitter = (function () {
function EventEmitter() {
this._events = {};
}
EventEmitter.prototype.emit = function (type) {
var _this = this;
var args = [];
for (var _i = 0; _i < (arguments.length - 1); _i++) {
args[_i] = arguments[_i + 1];
}
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events[type] (Array.isArray(this._events[type]) && !this._events[type].length)) {
if (args[0] instanceof Error) {
throw args[0];
} else {
throw new Error("Uncaught, unspecified 'error' event.");
}
return false;
}
}
if (this._events[type]) {
this._events[type].forEach(function (handler) {
return handler.apply(_this, args);
});
return true;
}
return false;
};

EventEmitter.prototype.addListener = function (type, listener) {
if ('function' !== typeof listener) {
throw new Error('addListener only takes instances of Function');
}
var events = this._events;
var listeners = events[type];
if (!listeners)
listeners = events[type] = [];
else if (listeners.indexOf(listener) >= 0)
return this;
listeners.push(listener);
return this;
};

EventEmitter.prototype.removeListener = function (type, listener) {
var events = this._events;
if (!events[type])
return this;
var listeners = events[type];
var i = listeners.indexOf(listener);
if (i >= 0)
listeners.splice(i, 1);
return this;
};
return EventEmitter;
})();

//寫一個小的案例, 為了充分解耦代碼, 我們可以把代碼通過自定義的事件分成幾個模塊;

</script>

<input id="text">data</input>

<script>
window.onload = init;
function init () {
var TextEvent = (function(Emiter) {
__extends(TextEvent, Emiter);
function TextEvent() {
Emiter.apply(this);
};
return TextEvent;
}.call(TextEvent,EventEmitter));

//創建了這個實例;
var textEvent = new TextEvent();

//為實例添加自定義事件;
textEvent.addListener("keypress", function preventDefault(ev) {
ev.preventDefault();
});
//為實例添加自定義事件;
textEvent.addListener("keypress", function(ev) {
var code = ev.which = ev.which ev.keyCode ev.charCode;
console.log( code );
});
//為實例添加自定義事件;
textEvent.addListener("keypress", function(ev) {
var code = ev.which = ev.which ev.keyCode ev.charCode;
if(code > 80) {
console.log("code>80");
};
});
//為實例添加自定義事件;
textEvent.addListener("keypress", function(ev) {
var code = ev.which = ev.which ev.keyCode ev.charCode;
if(ev.shiftKey === true) {
console.log("shift key is pressed!")
};
});

document.getElementById("text").addEventListener("keypress", function( ev ) {
textEvent.emit("keypress",ev)
});
};
</script>
</body>
</html>

復制代碼

樓主你他媽在逗我? 這麼多

實現要懂JS的繼承:

//d為目標對象, b為一個函數對象;
var __extends = this.__extends function (d, b) {
//繼承了靜態屬性
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
//繼承了原型
__.prototype = b.prototype;
d.prototype = new __();
};

其次呢, 自定義事件的代碼要懂, 很多地方都有用到;
+ View Code



最後通過組合繼承, 實現了一個自定義事件類方法:

var TextEvent = (function(Emiter) {
__extends(TextEvent, Emiter);
function TextEvent() {
Emiter.apply(this);
};
return TextEvent;
}.call(TextEvent,EventEmitter));



我們通過實例化TextEvent, 為這個實例添加自定義的方法;

在onkeypress的事件回調觸發自定義事件textEvent.emit("keypress",ev), 最後的最後只要為textEvent綁定自定義事件即可,這樣做的優勢就是: 我們可以通過removeListener去除事件, 事件函數也可以直接復用, 很靈活

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved