8

我有两个要素:

<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;
            }

编辑:我如何onclick在他们点击的元素上正确触发,而不onblur首先隐藏 div 的事件,这使得onclick毫无意义?但是,当文本框失去焦点时,我仍然希望保留建议 div 消失的功能。

4

3 回答 3

9

我认为您的答案很短,因为您的问题令人困惑。大概您有一个输入,当聚焦时,它会根据输入到输入中的字符显示建议列表。

如果用户使用光标选择一个项目,那么我认为输入的模糊事件在 div 的点击事件之前触发,并且在点击触发之前 div 设置为 display:none,因此错过了 div。

解决方法是在短暂超时后调用 onblur 侦听器,因此:

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

在多个浏览器中测试,可能需要将超时时间设置为 200ms 左右。在模糊事件之后建议消失之前是否有短暂的可见延迟并不重要(即有点太长总比有点太短好)。

确保这些建议不会掩盖页面上的任何重要内容,否则用户可能会发现它们更多的是障碍而不是帮助。:-)

于 2011-04-11T02:44:43.603 回答
7

接受的答案将作为一个快速修复,但通过依赖 a setTimeout,您假设用户n在释放之前只会继续点击不到几毫秒(只需想象有人在点击犹豫)。为了更确定点击会通过,您可以设置更长的超时时间,但这意味着您的可隐藏元素将在模糊后保持可见的时间更长。

那么让我们来看看问题的根源。

点击事件未能通过是按以下顺序触发的事件的结果:

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

因此,当 mouseup/click 事件准备触发时,模糊侦听器已被调用,并且您曾经悬停的元素已经消失。

这是一个应该有效的一般修复(基于 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事件而不是click事件。

事件的顺序是:

  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 回答