d3的dispatch模組是對原生事件處理的封裝,通過該模組可以註冊自定義的事件並繫結回撥函式。
d3.dispatch
該模組用於註冊自定義名稱的回撥函式,並且可以呼叫這些函式。
function dispatch() {
/*將傳入的引數作為鍵值存入Dispatch物件中,引數以陣列的形式傳入並且不能有重複的元素
*初始化時引數只包含型別,不應包含名稱,併入初始化時可以傳入['click', 'drag'],在之後呼叫on方法時可以通過on('click.my1 drag.my2 hover', callback)這種方式來繫結回撥函式
*在dispatch中是以如下方式儲存:
*
* {
* 'click': [
* {
* name: 'my1',
* value: callback
* }
* ],
* 'drag': [
* {
* name: 'my2',
* value: callback
* }
* ],
* 'hover': [
* {
* name: '',
* value: callback
* }
* ]
* }
*/
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
_[t] = [];
}
return new Dispatch(_);
}
//Dispatch建構函式
function Dispatch(_) {
this._ = _;
}
複製程式碼
將傳入的事件型別存入dispatch物件中。
dispatch.on(typenames[, callback])
用於將事件和回撥函式進行繫結。
//繫結事件型別和回撥函式
on: function(typename, callback) {
var _ = this._,
T = parseTypenames(typename + "", _),
t,
i = -1,
n = T.length;
// 如果沒有callback引數,則返回以指定type和name註冊的callback函式。
if (arguments.length < 2) {
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
return;
}
// 如果傳入了callback函式,則對指定的type和name設定該回撥函式。
// 如果callback為null,則可以移除指定的回撥函式
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
while (++i < n) {
if (t = (typename = T[i]).type) _[t] = set$1(_[t], typename.name, callback);
else if (callback == null) for (t in _) _[t] = set$1(_[t], typename.name, null);
}
return this;
},
//獲取回撥函式
function get(type, name) {
for (var i = 0, n = type.length, c; i < n; ++i) {
if ((c = type[i]).name === name) {
return c.value;
}
}
}
//設定回撥函式
function set$1(type, name, callback) {
for (var i = 0, n = type.length; i < n; ++i) {
if (type[i].name === name) {
//如果type中已有指定的name,則將其從type陣列中移除
type[i] = noop$1, type = type.slice(0, i).concat(type.slice(i + 1));
break;
}
}
if (callback != null) type.push({name: name, value: callback});
return type;
}
複製程式碼
其他方法:
//對dispatch進行拷貝,對拷貝後的內容進行修改不會影響之前的內容
copy: function() {
var copy = {}, _ = this._;
for (var t in _) copy[t] = _[t].slice();
return new Dispatch(copy);
},
call: function(type, that) {
//第二個引數之後的引數會傳入callback函式中
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
//會呼叫type下的所有回撥函式
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
},
apply: function(type, that, args) {
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
}
複製程式碼