25

ドロップダウンのように機能するdivがあります。そのため、ボタンをクリックするとポップアップし、この大きなリストをスクロールできます。したがって、divには垂直スクロールバーがあります。divの外側、つまりぼかしをクリックすると、divが消えるはずです。

問題は、ユーザーがdivのスクロールバーをクリックすると、IEが誤ってonblurイベントを発生させるのに対し、Firefoxは発生しないことです。Firefoxはまだスクロールバーをdivの一部として扱っていると思いますが、これは正しいと思います。IEが同じように動作するようにしたいだけです。

4

8 に答える 8

18

オートコンプリートドロップダウンのスクロールバーでも同様の問題が発生しました。ドロップダウンは、それがアタッチされているフォーム要素がフォーカスを失ったときに非表示にする必要があるため、正しい要素にフォーカスを維持することが問題になりました。スクロールバーがクリックされたとき、Firefox(10.0)のみが入力要素にフォーカスを保ちました。IE(8.0)、Opera(11.61)、Chrome(17.0)、Safari(5.1)はすべて入力からフォーカスを削除し、ドロップダウンが非表示になりました。また、非表示になっているため、ドロップダウンでクリックイベントが発生しませんでした。

幸いなことに、問題のあるブラウザのほとんどでは、フォーカスの移動を簡単に防ぐことができます。これは、デフォルトのブラウザアクションをキャンセルすることによって行われます。

dropdown.onmousedown = function(event) {
    // Do stuff
    return false;
}

イベントハンドラーに戻り値を追加すると、IEを除くすべてのブラウザーで問題が解決されました。これを行うと、デフォルトのブラウザアクション(この場合はフォーカスシフト)がキャンセルされます。また、クリックの代わりにマウスダウンを使用すると、入力要素でblurイベントが発生する前にイベントハンドラーが実行されます。

これはIEを唯一の残りの問題として残しました(そこに驚くことはありません)。IEのフォーカスシフトをキャンセルする方法はありません。幸い、IEはドロップダウンでフォーカスイベントを発生させる唯一のブラウザーです。つまり、入力要素へのフォーカスはIE専用のイベントハンドラーで復元できます。

dropdown.onfocus = function() {
    input.focus();
}

IEのこのソリューションは完璧ではありませんが、フォーカスシフトをキャンセルすることはできませんが、これが最善の方法です。何が起こるかというと、blurイベントが入力で発生し、ドロップダウンが非表示になります。その後、フォーカスが非表示になったドロップダウンで発生し、入力へのフォーカスが復元され、ドロップダウンの表示がトリガーされます。私のコードでは、ドロップダウンの再入力もトリガーされ、選択が少し遅れて失われますが、ユーザーがスクロールしたい場合は、とにかく選択が役に立たない可能性があるため、これは許容できると思いました。

私の例は質問とは少し異なりますが、これがお役に立てば幸いです。私が集めたものから、質問は、ドロップダウンを開いたボタンではなく、ドロップダウン自体でぼかしイベントを発生させることについてでした。これは私には意味がありません...フォーカスイベントハンドラーの使用が示すように、スクロールバーをクリックしますスクロールバーがIEの一部である要素にフォーカスを移動する必要があります。

于 2012-02-09T11:44:38.473 に答える
5

遅い答えですが、同じ問題があり、現在の答えはうまくいきませんでした。

ポップアップ要素のホバー状態は期待どおりに機能するため、blurイベントでは、ポップアップ要素がホバーされているかどうかを確認し、ホバーされていない場合にのみ削除/非表示にすることができます。

$('#element-with-focus').blur(function()
{
    if ($('#popup:hover').length === 0)
    {
        $('#popup').hide()
    }
}

ぼかしイベントがバインドされている元の要素にフォーカスを戻す必要があります。これはスクロールを妨げません:

$('#popup').focus(function(e)
{
    $('#element-with-focus').focus();
});

これはIE7以下では機能しません-したがって、サポートを削除するだけです...

例: http: //jsfiddle.net/y7AuF/

于 2014-05-22T22:26:31.060 に答える
3

スクロールバーをクリックしたときにIEがblurイベントを発生させるという同様の問題が発生しています。どうやらそれはIE7以下でのみ発生し、IE8はquirksmodeで発生します。

これが私がグーグルで見つけたものです

https://prototype.lighthouseapp.com/projects/8887/tickets/248-results-popup-from-ajaxautocompleter-disappear-when-user-clicks-on-scrollbars-in-ie6ie7

基本的に、現在フォーカスされているdiv以外のドキュメントのどこかをクリックしたことがわかっている場合にのみ、ぼかしを行います。スクロールバーをクリックしてもdocument.onclickが起動しないため、スクロールバーのクリックを逆に検出することができます。

于 2010-01-25T22:53:34.767 に答える
3

これは古い質問ですが、IE11にも当てはまるので、ここで私が行いました。

メニューのmousedownイベントを聞いて、このイベントにフラグを設定します。ぼかしイベントをキャッチしたときに、mousedownフラグがオンになっている場合は、フォーカスを戻します。Edge、FF、およびChromeはblurイベントを発生させませんが、mouseupイベントを発生させます(IEは発生しません)ので、(IEのblurで)それらのmouseupのmousedownフラグをリセットします。

  mousedown: function (e) {
      this.mouseddown = true;
      this.$menu.one("mouseup", function(e){
        // IE won't fire this, but FF and Chrome will so we reset our flag for them here
        this.mouseddown = false;
      }.bind(this));
    }

 blur: function (e) {
      if (!this.mouseddown && this.shown) {
        this.hide();
        this.focused = false;        
      } else if (this.mouseddown) {
        // This is for IE that blurs the input when user clicks on scroll.
        // We set the focus back on the input and prevent the lookup to occur again
        this.skipShowHintOnFocus = true; // Flag used to avoid repopulating the menu
        this.$element.focus();
        this.mouseddown = false;    
      } 
    },

そうすれば、メニューは表示されたままになり、ユーザーは何も失うことはありません。

于 2016-07-18T13:29:18.487 に答える
1

focusoutとfocusinを使用する(IE固有のイベント)

$(document).bind('focusout', function(){
     preventHiding = false;
     //trigger blur event
     this.$element.trigger('blur');

});

$(document).bind('focusin', function(){
     preventHiding = true;
});

$(document).bind('blur', function(){
       // Did anyone want us to prevent hiding?
       if (this.preventHiding) {
         this.preventHiding = false;
         return;
       }
       this.hide();
});
于 2014-01-06T12:25:51.317 に答える
0

私も同じ問題を抱えていました。メニューをラッピング(より大きな)divに入れることで解決しました。ラッパーにぼかしを適用すると、うまくいきました!

于 2010-02-10T16:02:33.233 に答える
0

おそらく、tabindex属性セットを-1ノードdivに追加してみてください。

于 2011-09-18T16:54:25.807 に答える
0

これはIEの問題ではないと思います。

それは、インタラクションを設計する方法と、どのイベントを処理するかというケースです。関連するターゲットに一意のcss-class-accessorがある場合は、blurイベントの開始を許可または禁止する要素のevent.relatedTargetのclassListを確認することで、blurイベントをキャンセルできます。私のES2015プロジェクトのカスタムオートコンプリートドロップダウンから私のonBlurHandlerを参照してください(古いJSサポートのために回避する必要があるかもしれませんcontains()):

onBlurHandler(event: FocusEvent) {
  if (event.relatedTarget 
      && (event.relatedTarget as HTMLElement).classList.contains('folding-select-result-list')) {
    // Disallow any blur event from `.folding-select-result-list`
    event.preventDefault();
  } else if (!event.relatedTarget
      || event.relatedTarget 
      && !(event.relatedTarget as HTMLElement).classList.contains('select-item')) {
    // If blur event is from outside (not `.select-item`), clear the suggest list
    // onClickHandler of `.select-item` will clear suggestList as configured with this.clearAfterSelect
    this.clearOptions(this.clearAfterBlur);
  }
}
  • .folding-select-result-list私の提案です-ドロップダウンには「空のスポット」と「おそらくスクロールバー」があり、このぼかしイベントは必要ありません。
  • .select-item選択のXHRリクエストを起動し、コンポーネントの別のプロパティがである場合にドロップダウンを閉じる独自のonClickHandlerがありthis.clearAfterSelectますtrue
于 2020-06-29T22:04:18.237 に答える