零JS筆記 | 面向對象 | 自定義事件
什麼是組件?
對面向對象的深入應用(UI組件、功能組件)
將配置參數、方法、事件,三者分離
創建自定義事件:
有利於多人協作開發;
如何去掛載自定義事件與事件函數
自定義事件:主要與函數有關,讓函數具備事件某些特性
(比如,多个函数也可如事件都执行,而不是像同名函数后覆盖前)
原理:
window.onload = function () {
var _div = document.getElementById('div1')
var _span = document.getElementById('span1')
bind(_div, 'click', function () {
console.log(1);
})
bind(_div, 'click', function () {
console.log(2);
})
bind(_span, 'show', function () {
console.log(3);
})
bind(_span, 'show', function () {
console.log(4);
})
bind(_span, 'hide', function () {
console.log(5);
})
//觸發自定義事件:
autoEvent(_span, 'show') // 3,4
autoEvent(_span, 'hide') // 3,4
function bind(obj, events, fn) { //建立关系 ;
//obj:楼层;
//events:书架
//fn:一本书
obj.listeners = obj.listeners || {} //樓層
obj.listeners[events] = obj.listeners[events] || []; //樓層下創建書架
obj.listeners[events].push(fn); //push方法把對應的書存到書架下
if (obj.addEventListener) {
obj.addEventListener(events, fn, false)
}
else {
obj.attachEvent('on' + events, fn)
}
}
function autoEvent(obj, events) { //主动触发自定义事件;
for (var i = 0; i < obj.listeners[events].length; i++) {
obj.listeners[events][i](); //循環數組執行即可
}
}
}
改寫實例:
window.onload = function () {
var d1 = new Drag()
var d2 = new Drag()
var d3 = new Drag()
var d4 = new Drag()
d1.init({
id: 'div1'
})
d2.init({
id: 'div2'
})
bind(d2, '_down', function () {
document.title = 'down'
})
d3.init({
id: 'div3'
})
bind(d3, '_up', function () {
document.title = 'up'
})
d4.init({
id: 'div4'
})
bind(d4, '_up', function () {
document.title = 'bybybybyb'
})
//所以,最大的好處:如果想讓最後一個變大,只需要再綁定一次即可;而不是寫在原有代碼裏;
bind(d4, '_up', function () {
document.getElementById('div4').style.width = '200px'
})
}
function Drag() {
this.obj = null;
this.disX = 0;
this.dixY = 0;
this.settings = {}
}
Drag.prototype.init = function (opt) {
this.obj = document.getElementById(opt.id)
var _this = this;
extend(this.settings, opt)
this.obj.onmousedown = function (ev) {
var ev = ev || event;
_this.fnDown(ev)
//執行
autoEvent(_this, '_down')
document.onmousemove = function (ev) {
var ev = ev || event;
_this.fnMove(ev)
}
document.onmouseup = function () {
_this.fnUp();
//執行
autoEvent(_this, '_up')
}
return false //最後加阻止默認事件;
}
}
Drag.prototype.fnDown = function (ev) {
this.disX = ev.clientX - this.obj.offsetLeft;
this.disY = ev.clientY - this.obj.offsetTop;
}
Drag.prototype.fnMove = function (ev) {
this.obj.style.left = ev.clientX - this.disX + 'px'
this.obj.style.top = ev.clientY - this.disY + 'px'
}
Drag.prototype.fnUp = function () {
document.onmousemove = document.onmouseup = null;
}
function extend(o1, o2) {
for (var attr in o2) {
o1[attr] = o2[attr]
}
}
function bind(obj, events, fn) {
obj.listeners = obj.listeners || {};
obj.listeners[events] = obj.listeners[events] || [];
obj.listeners[events].push(fn);
if (obj.nodeType) { //判斷是否為dom元素
if (obj.addEventListener) {
obj.addEventListener(events, fn, false)
}
else {
obj.attachEvent('on' + events, fn)
}
}
}
function autoEvent(obj, events) {
if (obj.listeners && obj.listeners[events]) { //判斷是否存在
for (var i = 0; i < obj.listeners[events].length; i++) {
obj.listeners[events][i]()
}
}
}