Javascript新手 - 似乎onBlur的一个元素“覆盖”另一个元素的onclick

时间:2011-04-10 21:15:27

标签: javascript javascript-events onclick onblur

我有两个要素:

<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,然后是div元素的onclick:

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


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

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

3 个答案:

答案 0 :(得分:8)

我认为你的答案很简短,因为你的问题令人困惑。据推测,您有一个输入,在聚焦时,根据输入到输入中的字符显示建议列表。

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

修复是在短暂超时后调用onblur监听器,所以:

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

在许多浏览器中测试,您可能需要将超时设置为200ms左右。如果在建议消失之前模糊事件之后存在短暂的可见延迟,则无关紧要(即,有点太长会比有点太短)。

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

答案 1 :(得分:2)

接受的答案可以作为快速解决方案,但依靠setTimeout,您可以假设用户只会在发布前不到n毫秒点击一下(只是想象一下某人)犹豫点击)。为了更加确定点击是否会通过,您可以设置更长的超时,但这意味着您的可隐藏元素将在模糊后更长时间保持可见。

让我们看一下问题的根源。

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

  1. mousedown
  2. blur
  3. mouseup
  4. click
  5. 因此,当鼠标注射/单击事件准备好触发时,模糊侦听器已被调用,而您曾经悬停过的元素已经消失。

    这是一个常规修复(基于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" 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>

答案 2 :(得分:0)

解决方案非常简单-您只需使用 mousedown 事件而不是 click 事件。

事件的顺序是:

  1. 鼠标右键-您要在div元素中使用的 点击事件

  2. 模糊-另一个元素是您的逻辑在里面。

  3. 单击-div元素的

您可以在 mousedown 事件中保存一个标志,然后在onBlur逻辑中检查该标志以了解是否需要手动调用 click 函数

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

submitDown() {
  saveCalled = true;
}
do(){
....
  if(saveCalled){
     saveCalled = false;
     save();
  }
}