3

私は独自の「ツールチップ」を実装しており、ホバーするたびに新しい div 要素を作成し、ホバーアウトすると削除します。以下のコードは、私が使用しているものから削除されていますが、問題を示しています: このコードは、ユーザーがゆっくりとマウスを $('#' + fieldName) オブジェクトの上に置いたり離したりするときに完璧に機能しますが、マウスを上に移動するとオブジェクトをツールチップからすばやく引っ張っても、削除されません。コードを改善する方法はありますか?

すべてのツールチップ ボックスを作成して非表示にし、ホバー時に表示するシステムを実装しようとしましたが、マウスがオブジェクトからすばやく移動し、ホバー アウトが起動しないという同じ問題が発生しました。

$('#' + fieldName).hover(
    function () { /* Create new DOM element */
        /* My ajax stuff here */
        var data = 'test';
        var tooltipBox = $('<div id="' + fieldName + '_tooltip">' + data + '</div>');
        $("body").prepend(tooltipBox);
    },
    function () { /* Remove Tooltip from DOM */
        $('#' + fieldName + '_tooltip').remove();
    }
);

答え:

Robert Koritnik と sajawikio の助けを借りて:

ホバーでAJAX呼び出しを使用してホバーでツールチップを作成する必要がある場合は、それを機能させるために小さなハックを行うことができます。

var callingAjax = false;
var removeTooltip = false;
$('#tooltip').hover(
     function() {
          callingAjax = true;
          $.post(.. {
              callingAjax = false;
              /* do stuff */
              if(removeTooltip)
                   /* code to remove tooltip */
              removeTooltip = false;
          });
     },
     function() {
          if(callingAjax) 
              removeTooltip = true;
          else
              /* code to remove tooltip */
     }
);
4

2 に答える 2

6

あなたのコードは動作します

私はあなたのコードをJSFiddleに入れましたが、それは機能するので、他の問題があるに違いありません。リンク上でマウスをできるだけ速く動かすことができますが、毎回ツールチップが削除されます。

私はクロムを使用しています。あなたのは何ですか?

: JSFiddle の私のコードとあなたのコードの唯一の違いは、私が使用したappendことと、あなたが使用したことですprepend。明らかな理由でそれを変更しました。変更してみると、その理由がわかります。しかし、それは両方の方法で機能します。

注 2 :オブジェクトがプリペンドされた瞬間にマウスがリンクの外に移動するため、実際にこれに変更appendすると、マウスの速い動きが実際にシミュレートされます。prependしたがって、マウスをできるだけ速く動かす代わりに、要素を動かして同じ動作をシミュレートします。

実際の問題

問題は、 tooltip を作成する前にホバーで他のことを実行していることです。それが Ajax 呼び出しであるかどうかは問題ではありません。Javascriptスレッドが次の機能を実行できるように、非同期のものであれば何でもかまいません。そして、それが要素にとどまるよりも長く実行される場合、マウスアウトはまだ作成されていないものを削除したいです(後で作成されます)。

考えられる解決策は次の 2 つです。

  1. 最初にツールチップを追加してから、他のものを実行してください。
  2. ホバー イベントの実行後に Ajax 呼び出しを延期します。

警告

ホバー イベントで ajax コードを実行しないことを強くお勧めします。実際には、ブラウザが処理できる以上のものです。ホバー時に ajax リクエストを実行する必要がある場合は、次のようにします。ホバーが起動し、その直後に実行される関数呼び出しを準備しますが、その関数は、まだ進行中でない場合にのみ Ajax 呼び出しを発行します。

// variable outside of hover closures
var ajaxExecuting = false;

// code to put within your hover handler
setTimeout(function() {
    if (!ajaxExecuting)
    {
        ajaxExecuting = true;
        // do your AJAX stuff
    }
}, 0);
于 2012-09-04T15:32:34.167 に答える
1

はい、問題があります。速度はまったく問題にしないでください - 偶然に任せず、ホバーインするとホバーアウトがアクティブになることを確認してください - そしてホバーアウトするとホバーインがアクティブになるようにしてください! フールプルーフ!このようにして、あなたが述べたように「拡張」されて行き詰まることはありません! つまり、永続的なハンドラーを使用する代わりに、一度に 1 つずつ「前後のトグル スタイル」でイベントを実行します。

(実際のコード例を参照してください-もちろん、使用する要素が大きい場合はうまく機能します)- http://jsfiddle.net/4jArC/

var fieldName = "whatever";

function b(evt) { /* Remove Tooltip from DOM */
    $('#' + fieldName + '_tooltip').remove();
    $(evt.currentTarget).one('mouseover',a);
}

function a (evt) { /* Create new DOM element */
    /* My ajax stuff here */
    var data = 'test';
    var tooltipBox = $('<div id="' + fieldName + '_tooltip">' + data + '</div>');
    $("body").prepend(tooltipBox);
    $(evt.currentTarget).one('mouseout',b);
}

$('#' + fieldName).one('mouseover', a);
​
于 2012-09-04T15:40:17.193 に答える