ต่อไปนี้เป็นโซลูชันของ Mike Bostock อีกเวอร์ชันหนึ่งและได้รับแรงบันดาลใจจากความคิดเห็นของ @hughes ถึงคำตอบของ @ kashesandr ทำให้การโทรกลับเพียงครั้งเดียวเมื่อtransition
สิ้นสุด
ให้drop
ฟังก์ชั่น ...
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);
}
... เราสามารถขยายได้d3
ดังนี้:
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)) {
d3.timer(function() {
f.apply(transition, args);
return true;
}, typeof(delay) === "number" ? delay : 0);
} else {
var n = 0;
transition.each(function() { ++n; })
.each("end", function() {
if (!--n) f.apply(transition, args);
});
}
});
return transition;
}
ในฐานะที่เป็น JSFiddle
ใช้transition.end(callback[, delayIfEmpty[, arguments...]])
:
transition.end(function() {
console.log("all done");
});
... หรือด้วยการหน่วงเวลาหากtransition
ว่างเปล่า:
transition.end(function() {
console.log("all done");
}, 1000);
... หรือมีcallback
ข้อโต้แย้งเพิ่มเติม:
transition.end(function(x) {
console.log("all done " + x);
}, 1000, "with callback arguments");
d3.transition.end
จะใช้การส่งผ่านcallback
แม้ว่าจะว่างเปล่าtransition
หากระบุจำนวนมิลลิวินาทีหรือถ้าอาร์กิวเมนต์ที่สองเป็นจริง นอกจากนี้ยังจะส่งต่ออาร์กิวเมนต์เพิ่มเติมไปยังcallback
(และเฉพาะอาร์กิวเมนต์เหล่านั้น) ที่สำคัญโดยค่าเริ่มต้นจะไม่ใช้callback
if transition
ว่างซึ่งอาจเป็นข้อสันนิษฐานที่ปลอดภัยกว่าในกรณีเช่นนี้