<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>圣誕主題</title>
<script src="observer.js"></script>
</head>
<body>
<button>點擊觸發page任務</button>
<button>點擊取消page任務</button>
<script type="text/javascript">
//觀察者
var observer = new Observer();
//page函數
//模擬運行1秒的一個函數
function page() {
setTimeout(function() {
//發布一個完成的時間
observer.publish("compelte")
}, 1000)
}
//訂閱一個完成的時間
observer.subscribe("compelte", function() {
alert("page任務完成")
})
//觸發任務
document.querySelectorAll("button")[0].addEventListener("click", function() {
page();
}, false)
//取消任務
document.querySelectorAll("button")[1].addEventListener("click", function() {
observer.unsubscribe("compelte")
alert("注銷了訂閱了compelte事件")
}, false)
</script>
</body>
</html>
/**
* 事件
* 觀察者模式
*/
var Observer = (function(slice) {
function bind(event, fn) {
var events = this.events = this.events || {},
parts = event.split(/\s+/),
i = 0,
num = parts.length,
part;
if (events[event] && events[event].length) return this;
for (; i < num; i++) {
events[(part = parts[i])] = events[part] || [];
events[part].push(fn);
}
return this;
}
function one(event, fn) {
this.bind(event, function fnc() {
fn.apply(this, slice.call(arguments));
this.unbind(event, fnc);
});
return this;
}
function unbind(event, fn) {
var events = this.events,
eventName, i, parts, num;
if (!events) return;
parts = event.split(/\s+/);
for (i = 0, num = parts.length; i < num; i++) {
if ((eventName = parts[i]) in events !== false) {
events[eventName].splice(events[eventName].indexOf(fn), 1);
if (!events[eventName].length) { //修正沒有事件直接刪除空數組
delete events[eventName];
}
}
}
return this;
}
function trigger(event) {
var events = this.events,
i, args, falg;
if (!events || event in events === false) return;
args = slice.call(arguments, 1);
for (i = events[event].length - 1; i >= 0; i--) {
falg = events[event][i].apply(this, args);
}
return falg; //修正帶返回
}
return function() {
this.on =
this.subscribe = bind;
this.off =
this.unsubscribe = unbind;
this.trigger =
this.publish = trigger;
this.one = one;
return this;
};
})([].slice);