Poniżej znajduje się kolejna wersja Mike'a Bostocka roztworze i zainspirowany komentarzem @hughes' do użytkownika @ kashesandr odpowiedź. Wykonuje pojedyncze wywołanie zwrotne po transitionzakończeniu.
Dawać drop funkcję ...
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);
}
... możemy przedłużyć d3 sposób:
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;
}
Jako JSFiddle .
Posługiwać się transition.end(callback[, delayIfEmpty[, arguments...]]) :
transition.end(function() {
console.log("all done");
});
... lub z opcjonalnym opóźnieniem, jeśli transition jest pusty:
transition.end(function() {
console.log("all done");
}, 1000);
... lub z opcjonalnymi callbackargumentami:
transition.end(function(x) {
console.log("all done " + x);
}, 1000, "with callback arguments");
d3.transition.endzastosuje przekazaną wartość callbacknawet z pustą wartością, transition jeśli podano liczbę milisekund lub jeśli drugi argument jest prawdziwy. Spowoduje to również przekazanie wszelkich dodatkowych argumentów do callback(i tylko tych argumentów). Co ważne, domyślnie nie będzie to miało zastosowania, callbackjeśli if transitionjest puste, co jest prawdopodobnie bezpieczniejszym założeniem w takim przypadku.