web-dev-qa-db-ja.com

遷移の終わりにコールバックを呼び出す

D3.js を使用して、FadeOutメソッド(jQueryに類似)を作成する必要があります。 transition()を使用して不透明度を0に設定する必要があります。

d3.select("#myid").transition().style("opacity", "0");

問題は、トランジションが終了したことを認識するためにコールバックが必要なことです。コールバックを実装するにはどうすればよいですか?

94
Tony

遷移の「終了」イベントをリッスンする必要があります。

// d3 v5
d3.select("#myid").transition().style("opacity","0").on("end", myCallback);

// old way
d3.select("#myid").transition().style("opacity","0").each("end", myCallback);
  • このデモ は、「終了」イベントを使用して、多くのトランジションを順番にチェーンします。
  • D3に付属している ドーナツの例 は、これを使用して複数の遷移を連結します。
  • 私の独自のデモ は、遷移の開始時と終了時に要素のスタイルを変更します。

transition.each([type],listener) のドキュメントから:

typeが指定されている場合、遷移イベントのリスナーを追加し、「開始」イベントと「終了」イベントの両方をサポートします。遷移の遅延と継続時間が一定であっても、遷移の個々の要素ごとにリスナーが呼び出されます。開始イベントを使用して、各要素が遷移を開始するときに瞬間的な変更をトリガーできます。終了イベントを使用して、現在の要素thisを選択し、新しい遷移を導出することにより、マルチステージ遷移を開始できます。終了イベント中に作成された遷移は、現在の遷移IDを継承するため、以前にスケジュールされた新しい遷移をオーバーライドしません。

詳細については、 このトピックに関するこのフォーラムスレッド を参照してください。

最後に、要素がフェードアウトした後(遷移の終了後)に要素を削除する場合は、 transition.remove() を使用できます。

130
Phrogz

Mike Bostockの solution forv3と小さな更新:

  function endall(transition, callback) { 
    if (typeof callback !== "function") throw new Error("Wrong callback in endall");
    if (transition.size() === 0) { callback() }
    var n = 0; 
    transition 
        .each(function() { ++n; }) 
        .each("end", function() { if (!--n) callback.apply(this, arguments); }); 
  } 

  d3.selectAll("g").transition().call(endall, function() { console.log("all done") });
65
kashesandr

現在、d3 v4.0には、遷移にイベントハンドラーを明示的にアタッチする機能があります。

https://github.com/d3/d3-transition#transition_on

移行が完了したときにコードを実行するには、次のものが必要です。

d3.select("#myid").transition().style("opacity", "0").on("end", myCallback);
45
ericsoco

それぞれが同時に実行される多くの要素を持つ多くの遷移がある場合にも機能するわずかに異なるアプローチ:

var transitions = 0;

d3.select("#myid").transition().style("opacity","0").each( "start", function() {
        transitions++;
    }).each( "end", function() {
        if( --transitions === 0 ) {
            callbackWhenAllIsDone();
        }
    });
10
Jesper We

以下は、マイクボストックの solution の別のバージョンで、@ kashesandrの回答に対する@hughesのコメントに触発されています。 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)) { // 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;
}

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を適用しますifミリ秒数が指定されているまたはif2番目の引数は真実です。これにより、追加の引数もcallbackに転送されます(これらの引数のみ)。重要なことに、これはデフォルトではではなく、callbackが空の場合にtransitionを適用しません。

6
milos

Mike Bostockの ソリューションkashesandr +コールバック関数に引数を渡すことにより改善:

function d3_transition_endall(transition, callback, arguments) {
    if (!callback) callback = function(){};
    if (transition.size() === 0) {
        callback(arguments);
    }

    var n = 0;
    transition
        .each(function() {
            ++n;
        })
        .each("end", function() {
            if (!--n) callback.apply(this, arguments);
    });
}

function callback_function(arguments) {
        console.log("all done");
        console.log(arguments);
}

d3.selectAll("g").transition()
    .call(d3_transition_endall, callback_function, "some arguments");
0
int_ua