0

setTimeout 関数に少し問題があります。

$(this)は、特定のクラスを持つすべての DOM 要素です。

マウスが要素に入ってから離れる場合は問題ありません。しかし、マウスが (500 ミリ秒のタイムアウト内で) 要素から別の要素に直接移動した場合、最初の要素 (マウスが離れた要素) がフェードアウトすることはありません。

したがって、新しい mouseenter-Event の種類は、timeOut が関数を呼び出すのを防ぎます。setTimeout-wrapper がなければ、すべて正常に動作します。

これが私のコードです:

$(this).hover(methods['mouseenterManager'], methods['mouseleaveManager']);


/**
 * manage mouseenter events
 */
mouseenterManager: function() {

    clearTimeout(timer);

    //create toolbar, if no toolbar is in dom
    if ($(this).data("layouter").toolbar == undefined) {

        //get bottom center of this element
        pos_left = ($(this).width() / 2) + $(this).offset().left;
        pos_top = $(this).height() + $(this).offset().top;

        //create toolbar element
        toolbar = $('<div style="display:none; left:' + parseInt(pos_left) + 'px; top:' + parseInt(pos_top) + 'px;" class="layouter_bar"><ul><li><a class="edit" href="javascript:;">Edit</a></li><li><a class="copy" href="javascript:;">Edit</a></li><li><a class="remove" href="javascript:;">Edit</a></li></ul></div>');

        //bind this element to toolbar
        toolbar.data("layouter", {
            parent: $(this),
        });

        //bind toolbar to this element
        data = $(this).data("layouter");
        data.toolbar = toolbar;
        $(this).data("layouter", data);

        //bind this element to toolbar
        data = toolbar.data("layouter");
        data.parent = $(this);
        toolbar.data("layouter", data);

        element = $(this);
        toolbar.mouseleave(function() {

            toolbar = $(this);
            timer = setTimeout(function() {
                if (!toolbar.is(":hover") && !element.is(":hover")) {

                    toolbar.fadeOut("fast", function() {
                        $(this).remove();
                    });

                    data = element.data("layouter");
                    data.toolbar = undefined;
                    element.data("layouter", data);
                }
            }, 500);
        });

        //display the toolbar  
        $("body").append(toolbar);
        toolbar.fadeIn("fast");
    }
},


/**
 * manage mouseleave events
 */
mouseleaveManager: function() {

    toolbar = $(this).data("layouter").toolbar;
    element = $(this);
    if (toolbar != undefined) {
        timer = setTimeout(function() {
            if (!toolbar.is(":hover")) {

                toolbar.fadeOut("fast", function() {
                    $(this).remove();
                });

                data = element.data("layouter");
                data.toolbar = undefined;
                element.data("layouter", data);
            }
        }, 500);
    }
},

};​

何か案は?

ありがとう!

4

2 に答える 2

0

編集する要素をタイマーの関数に渡します。

例えば:

timer = setTimeout(function(toolbar, element) {
        if (!toolbar.is(":hover")) {

            toolbar.fadeOut("fast", function() {
                toolbar.remove();
            });

            data = element.data("layouter");
            data.toolbar = undefined;
            element.data("layouter", data);
        }
    }, 500)
于 2012-04-18T09:48:56.363 に答える
0

多くのグローバル変数を使用しているように見えますが、別の要素に入ると、それらすべてのグローバル変数の値が変更されます。タイムアウト関数はこれらのグローバル変数を参照しているため、別の要素を入力して変更された場合、正しく機能しません。

また、別の要素に入るとすぐに、タイマーをクリアして実行を防止するように見えます。これはグローバルタイマーであるため、1つしかないため、起動したいタイマーを強制終了しました。

グローバル変数の問題については、var次のようにローカルにする必要があるすべての変数の前に置きます。

var toolbar = $(this).data("layouter").toolbar;
var element = $(this);

//get bottom center of this element
var pos_left = ($(this).width() / 2) + $(this).offset().left;
var pos_top = $(this).height() + $(this).offset().top;

タイマーの問題については、単一のグローバル タイマーを持つ必要はなく、要素ごとにタイマーが必要なように思えます。それはもう少し複雑です。実行してテストできるものがなければ、これが他の変更なしで機能するかどうかはわかりませんが、これは、変数をローカルに修正し、タイマーを各要素に対してローカルにするための正しい方向へのステップです。

$(this).hover(methods['mouseenterManager'], methods['mouseleaveManager']);


/**
 * manage mouseenter events
 */
mouseenterManager: function() {

    var self = $(this);
    var timer = self.data("timer");
    if (timer) {
        clearTimeout(timer);
    }

    //create toolbar, if no toolbar is in dom
    if (self.data("layouter").toolbar == undefined) {

        //get bottom center of this element
        var pos_left = ($(this).width() / 2) + $(this).offset().left;
        var pos_top = $(this).height() + $(this).offset().top;

        //create toolbar element
        var toolbar = $('<div style="display:none; left:' + parseInt(pos_left) + 'px; top:' + parseInt(pos_top) + 'px;" class="layouter_bar"><ul><li><a class="edit" href="javascript:;">Edit</a></li><li><a class="copy" href="javascript:;">Edit</a></li><li><a class="remove" href="javascript:;">Edit</a></li></ul></div>');

        //bind this element to toolbar
        toolbar.data("layouter", {
            parent: self,
        });

        //bind toolbar to this element
        var data = self.data("layouter");
        data.toolbar = toolbar;
        self.data("layouter", data);

        //bind this element to toolbar
        data = toolbar.data("layouter");
        data.parent = self;
        toolbar.data("layouter", data);

        var element = self;
        toolbar.mouseleave(function() {

            toolbar = self;
            timer = setTimeout(function() {
                self.data("timer", null);
                if (!toolbar.is(":hover") && !element.is(":hover")) {

                    toolbar.fadeOut("fast", function() {
                        $(this).remove();
                    });

                    data = element.data("layouter");
                    data.toolbar = undefined;
                    element.data("layouter", data);
                }
            }, 500);
            self.data("timer", timer);
        });

        //display the toolbar  
        $("body").append(toolbar);
        toolbar.fadeIn("fast");
    }
},


/**
 * manage mouseleave events
 */
mouseleaveManager: function() {

    var toolbar = $(this).data("layouter").toolbar;
    var element = $(this);
    var timer = element.data("timer");
    if (toolbar != undefined && !timer) {
        timer = setTimeout(function() {
            element.data("timer", null);
            if (!toolbar.is(":hover")) {

                toolbar.fadeOut("fast", function() {
                    $(this).remove();
                });

                var data = element.data("layouter");
                data.toolbar = undefined;
                element.data("layouter", data);
            }
        }, 500);
        element.data("timer", timer);
    }
},

};​
于 2012-04-18T09:51:55.480 に答える