Sau đây là một phiên bản khác của giải pháp của Mike Bostock và được truyền cảm hứng từ nhận xét của @hughes cho câu trả lời của @ kashandr. Nó thực hiện một cuộc gọi lại duy nhất khi transition
kết thúc.
Cho một drop
hàm ...
function drop(n, args, callback) {
for (var i = 0; i < args.length - n; ++i) args[i] = args[i + n];
args.length = args.length - n;
callback.apply(this, args);
}
... chúng tôi có thể mở rộng d3
như vậy:
d3.transition.prototype.end = function(callback, delayIfEmpty) {
var f = callback,
delay = delayIfEmpty,
transition = this;
drop(2, arguments, function() {
var args = arguments;
if (!transition.size() && (delay || delay === 0)) { // if empty
d3.timer(function() {
f.apply(transition, args);
return true;
}, typeof(delay) === "number" ? delay : 0);
} else { // else Mike Bostock's routine
var n = 0;
transition.each(function() { ++n; })
.each("end", function() {
if (!--n) f.apply(transition, args);
});
}
});
return transition;
}
Là một JSFiddle .
Sử dụng transition.end(callback[, delayIfEmpty[, arguments...]])
:
transition.end(function() {
console.log("all done");
});
... hoặc với độ trễ tùy chọn nếu transition
trống:
transition.end(function() {
console.log("all done");
}, 1000);
... hoặc với các callback
đối số tùy chọn :
transition.end(function(x) {
console.log("all done " + x);
}, 1000, "with callback arguments");
d3.transition.end
sẽ áp dụng giá trị được truyền callback
ngay cả với giá trị trống transition
nếu số mili giây được chỉ định hoặc nếu đối số thứ hai là đúng. Điều này cũng sẽ chuyển tiếp bất kỳ đối số bổ sung nào đến callback
(và chỉ những đối số đó). Quan trọng hơn, điều này sẽ không theo mặc định áp dụng callback
nếu transition
là trống rỗng, mà có lẽ là một giả định an toàn trong trường hợp này.