8

私には2つの要素があります:

<input type="text" name="pmTo" id="pmTo" onkeyup="offerSuggs('none');" onfocus="showSelect();" onblur="hideSelect();" />

動的に作成されたもの(これはすべて自動提案プログラムの一部です):

$suggString .= '<div name="'.$value.'" id="'.$value.'" class="suggMouseOver" onmouseover="highlightDivs(this);" onmouseout="blurDivs(this);" onclick="fillInput(this);">'.$value.'</div>';

さて、次にonblur、入力要素の、次にonclickdiv要素のに対応するイベント関数があります。

function hideSelect() {
            offerSuggs('checkFinal');
            document.getElementById('nameSugg').style.display="none";
            }


function fillInput(elemName) {
            document.getElementById('pmTo').value=elemName.id;
            }

編集:イベントが最初にdivを非表示onclickにすることなく、クリックした要素でを正しくトリガーするにはどうすればよいですか?ただし、テキストボックスがフォーカスを失ったときに提案divの機能が消えたままにしておきたいと思います。 onbluronclick

4

3 に答える 3

9

あなたの質問は紛らわしいので、あなたは答えが不足していると思います。おそらくあなたは、焦点を合わせると、入力に入力された文字に基づいた提案のリストを表示する入力を持っています。

ユーザーがカーソルを使用してアイテムを選択した場合、divのクリックイベントの前に入力のblurイベントが発生し、クリックが発生する前にdivがdisplay:noneに設定されているため、divが欠落していると考えられます。

修正は、短いタイムアウトの後にonblurリスナーを呼び出すことです。

  <input ... onblur="setTimeout(function(){hideSelect();}, 100);">

多くのブラウザでテストします。タイムアウトを200ミリ秒程度に設定する必要がある場合があります。ぼかしイベントの後、提案が消えるまでに、目に見える短い遅延があるかどうかは関係ありません(つまり、少し長すぎる方が少し短すぎるよりも優れています)。

提案がページ上の重要なものを覆い隠さないようにしてください。そうしないと、ユーザーはそれらをヘルプよりも邪魔になる可能性があります。:-)

于 2011-04-11T02:44:43.603 に答える
7

受け入れられた答えは簡単な修正として機能しますが、に依存setTimeoutすることにより、ユーザーがリリースする前に数ミリ秒未満しかクリックし続けることはないと想定しますn(クリックをためらっている人を想像してください)。クリックが確実に通過するように、タイムアウトを長く設定することもできますが、これは、ぼかし後も非表示にできる要素がずっと長く表示され続けることを意味します。

それでは、問題の根本を見てみましょう。

クリックイベントが通過しないのは、イベントが次の順序で発生した結果です。

  1. mousedown
  2. blur
  3. mouseup
  4. click

したがって、mouseup / clickイベントを発生させる準備ができるまでに、blurリスナーが呼び出され、かつてホバーしていた要素はすでに消えています。

動作するはずの一般的な修正(mousedownイベントが最初に発生するという事実に基づく)は次のとおりです。

var searchEl = $('#search');
var listEl = $('#dropdown');
var keepListOpen = false;

searchEl
  .on('focus', function() {
    listEl.show();
  })
  .on('blur', function() {
    // Hide the list if the blur was triggered by anything other than
    //  one of the list items
    if (!keepListOpen) {
      listEl.hide();
    }
  });

listEl.find('li')
  .on('mousedown', function(event) {
    // Keep the list open so the onClick handler can fire
    keepListOpen = true;
  })
  .on('click', function(event) {
    // Proof that the list item was clicked
    alert('clicked option');
  });

$(window).on('mouseup', function(event) {
  // Return the keepListOpen setting to its default and hide the list

  // *NOTE* We could have tied this handler to the list items, 
  // but it wouldn't have fired if a mousedown happened on a
  // list item and then the user dragged the mouse pointer 
  // out of the area (or out of the window)
  if (keepListOpen) {
    listEl.hide();
    keepListOpen = false;
  }
});

// Bind to `window.top` if your page might be displayed in an iframe
// $(window.top).on('mouseup', function(event) {
//  if (keepListOpen) {
//    listEl.hide();
//    keepListOpen = false;
//  }
//});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="search" type="text" autocomplete="off" placeholder="Click Here">

<ul id="dropdown" style="display: none;">
  <li>Click Me 1</li>
  <li>Click Me 2</li>
  <li>Click Me 3</li>
</ul>

于 2016-04-18T10:40:38.177 に答える
0

解決策はとても簡単です-クリックイベントの代わりにmousedownイベントを使用する必要があります。

イベントの順序は次のとおりです。

  1. mousedown-クリックイベントで使用したいdiv要素の

  2. ぼかし-他の要素の、ロジックが内部にあること。

  3. div要素の-をクリックします

mousedownイベントにフラグを保存してから、onBlurロジックでフラグをチェックして、クリック関数を手動で呼び出す必要があるかどうかを確認できます。

<input onblur="do();" />
<button type="submit" (mousedown)="submitDown()" (click)="save()"></button>

submitDown() {
  saveCalled = true;
}
do(){
....
  if(saveCalled){
     saveCalled = false;
     save();
  }
}
于 2020-03-01T11:48:44.450 に答える