Allow `on` to return the current listener.

Fixes #216.
This commit is contained in:
Mike Bostock 2011-08-22 18:50:14 -07:00
Родитель a0fa7a00e5
Коммит a4500fcfb1
4 изменённых файлов: 35 добавлений и 15 удалений

20
d3.js поставляемый
Просмотреть файл

@ -1676,26 +1676,32 @@ d3_selectionPrototype.on = function(type, listener, capture) {
if (arguments.length < 3) capture = false;
// parse the type specifier
var i = type.indexOf("."),
typo = i === -1 ? type : type.substring(0, i),
name = "__on" + type;
var name = "__on" + type, i = type.indexOf(".");
if (i > 0) type = type.substring(0, i);
// if called with only one argument, return the current listener
if (arguments.length < 2) return (i = this.node()[name]) && i._;
// remove the old event listener, and add the new event listener
return this.each(function(d, i) {
if (this[name]) this.removeEventListener(typo, this[name], capture);
if (listener) this.addEventListener(typo, this[name] = l, capture);
var node = this;
if (node[name]) node.removeEventListener(type, node[name], capture);
if (listener) node.addEventListener(type, node[name] = l, capture);
// wrapped event listener that preserves i
var node = this;
function l(e) {
var o = d3.event; // Events can be reentrant (e.g., focus).
d3.event = e;
try {
listener.call(this, node.__data__, i);
listener.call(node, node.__data__, i);
} finally {
d3.event = o;
}
}
// stash the unwrapped listener for retrieval
l._ = listener;
});
};
d3_selectionPrototype.each = function(callback) {

2
d3.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -4,25 +4,31 @@ d3_selectionPrototype.on = function(type, listener, capture) {
if (arguments.length < 3) capture = false;
// parse the type specifier
var i = type.indexOf("."),
typo = i === -1 ? type : type.substring(0, i),
name = "__on" + type;
var name = "__on" + type, i = type.indexOf(".");
if (i > 0) type = type.substring(0, i);
// if called with only one argument, return the current listener
if (arguments.length < 2) return (i = this.node()[name]) && i._;
// remove the old event listener, and add the new event listener
return this.each(function(d, i) {
if (this[name]) this.removeEventListener(typo, this[name], capture);
if (listener) this.addEventListener(typo, this[name] = l, capture);
var node = this;
if (node[name]) node.removeEventListener(type, node[name], capture);
if (listener) node.addEventListener(type, node[name] = l, capture);
// wrapped event listener that preserves i
var node = this;
function l(e) {
var o = d3.event; // Events can be reentrant (e.g., focus).
d3.event = e;
try {
listener.call(this, node.__data__, i);
listener.call(node, node.__data__, i);
} finally {
d3.event = o;
}
}
// stash the unwrapped listener for retrieval
l._ = listener;
});
};

Просмотреть файл

@ -80,6 +80,14 @@ suite.addBatch({
},
"returns the current selection": function(body) {
assert.isTrue(body.on("submit", function() {}) === body);
},
"returns the assigned listener if called with one argument": function(body) {
body.on("mouseover", f).on("click.foo", f);
function f() {}
assert.equal(body.on("mouseover"), f);
assert.equal(body.on("click.foo"), f);
assert.isUndefined(body.on("click"));
assert.isUndefined(body.on("mouseover.foo"));
}
}
});