1

私は問題自体が解決されたように見えますが、誰かがこれの理由に光を当てることができることを望んでいます...

以下は、ユーザーフィードバックメッセージを含むdivを削除することを目的とした同じ関数の2つのスナップショットです。オプションのタイムアウトを使用するように設定されています。タイムアウトが指定されている場合は、setTimeout()を使用して自身を呼び出し、divを削除します。

関数の2つのバージョンの唯一の違いは、this.remove()が呼び出される場所です-問題のあるバージョンでは、最初にblackbirdjsを使用してログにメッセージを送信し、次にthis.remove()を呼び出します-これが実行された後、ログはフラッディングされますブラウザがそれらを送り込むことができるのと同じくらい速く「フィードバックdivを削除しています...」の終わりのないログメッセージで。

ただし、作業バージョンでは、順序を逆にすると、すべてが正常に実行され、すべてが正常に実行されます...

私は困惑しています。この場合の順序は些細なことだと思いますが、明らかにそうではありません。なぜこれが起こるのか、誰かが光を当てることができますか?これはjQueryのバグですか、それともブラックバードの問題ですか、それともJavaScriptの奇妙な癖ですか?

注:
confirm()の呼び出しを使用して、さまざまな成功を収めました-falseに戻った場合は、戻るように指示しましたが、これで停止しました-ただし、remove呼び出しの後にreturnを追加しても効果はありませんでした。

興味深いことに、どちらのバージョンもIE8で正常に動作するようです。したがって、これはFirefox / geckoの問題である可能性がありますか?

問題コード:

function clear_feedback(target_container, timeout){
    log.debug("timeout: " + timeout);
    log.debug("target_container: " + target_container);

    if(timeout == undefined){
        log.info("removing target...");

        $(target_container).children(".update_feedback").slideUp("slow",
            function() {
                log.info("Removing feedback div...");
                this.remove();
            }
        );
    }
    else{
        log.info("Setting timeout, THEN removing target...");

        setTimeout("clear_feedback('" + target_container + "')", timeout);
    }
}

作業コード:

function clear_feedback(target_container, timeout){
    log.debug("timeout: " + timeout);
    log.debug("target_container: " + target_container);

    if(timeout == undefined){
        log.info("removing target...");

        $(target_container).children(".update_feedback").slideUp("slow",
            function() {
                this.remove();
                log.info("Removing feedback div...");
            }
        );
    }
    else{
        log.info("Setting timeout, THEN removing target...");

        setTimeout("clear_feedback('" + target_container + "')", timeout);
    }
}
4

2 に答える 2

1

blackbirdjs コンソールだけに依存するのではなく、ブラウザーのエラー コンソールを確認する必要があります。

次に、ブラウザのエラーコンソールにもエラーメッセージが殺到していることに気付いたでしょう(どちらのコードバージョンでも)

コードの実際の問題は

this.remove();

thisはコールバック関数の HTML DOM 要素であり、関数を持たないremove()ため、子は非表示になるだけで、実際には削除されません。そしてthis.remove()、例外が発生します。コールバック関数が例外をスローすると、jQuery はその仕事をしようとして無限ループに陥ります。

必要なことは、要素を jQuery オブジェクトにラップすることです。

$(this).remove();

これで、2 番目のバージョンでエラーが修正されたように見える理由も明らかになりました

log.info("Removing feedback div..."); //error logged
this.remove();  //exception

this.remove();  //exception
//log line not executed as previous line threw exception
log.info("Removing feedback div...");

jQuery がエンドレス ループになってしまうという事実と、これが正しい動作であるかどうかについては議論の余地があり、jQuery の内部の仕組みをさらに深く調査する必要があります。しかし、これはあなたの興味の対象ではありません

興味のある方は、バグチケットを入手してください。

http://dev.jquery.com/ticket/2846

于 2009-12-19T13:41:52.383 に答える
0

私はこのような問題を見てきましたが、状況は異なります。しかし、根本的な原因は同じだと思います。

log.infoを見ると、DOMにノードが挿入されていることがわかります。jquery関数の1つがたまたま正しい場所、特にlog.infoがノードを挿入している場所でDOMをトラバースしている場合、それによってコールバックが呼び出されると、コールバックは別の場所を挿入しますノード、そしてあなたは無限ループになってしまいます。

IE8でこれが発生しない理由は、2つの理由のいずれかである可能性があります。DOM構造がブラウザー間で完全に同じではないか、JavaScriptコードがトラバースしているときにIE8がDOMノードの挿入を処理するために異なる戦略を使用するかのいずれかです。木。

Firebugを使用して、問題のある行の周囲にブレークポイントを配置してから、DOMツリーを表示して、このような動作を見つけることができるかどうかを確認してみてください。

于 2009-12-19T02:55:59.770 に答える