【问题标题】:jQuery: On form input focus, show div. hide div on blur (with a caveat)jQuery:在表单输入焦点上,显示 div。隐藏 div 模糊(有一个警告)
【发布时间】:2021-07-08 17:02:22
【问题描述】:

当输入字段处于焦点/模糊状态时,我可以使用以下代码显示/隐藏隐藏的 div:

  $('#example').focus(function() {
    $('div.example').css('display','block');
  }).blur(function() {
    $('div.example').fadeOut('medium');
  });

问题是我希望div.example 在用户此 div 中交互时继续可见。例如。单击或突出显示div.example 中的文本等。然而div.example 会在输入不在焦点上且鼠标与 div 中的元素交互时淡出。

input和div元素的html代码如下:

<p>
<label for="example">Text:</label>
<input id="example" name="example" type="text" maxlength="100" />
<div class="example">Some text...<br /><br />More text...</div>
</p>

如何使div.example 仅在用户单击输入和/或div.example 外部时消失?我尝试使用 focusin/focusout 来检查 &lt;p&gt; 上的焦点,但这也不起作用。

div.example 使用 jQuery 直接位于输入字段 #example 的下方是否重要?执行此操作的代码如下:

var fieldExample = $('#example');
$('div.example').css("position","absolute");
$('div.example').css("left", fieldExample.offset().left);
$('div.example').css("top", fieldExample.offset().top + fieldExample.outerHeight());

如果之前有人问过这个问题,我深表歉意,但我阅读的许多显示/隐藏 div 问题并未涵盖这一点。谢谢你的建议。 :)

【问题讨论】:

    标签: jquery focus blur


    【解决方案1】:

    如果您跟踪文档上的 focusin 事件,因为 focusin 冒泡,那么您可以确定焦点中的新事物是否在“外部”,如果是,则对其进行处理。这适用于点击和标签。

    $('#example').focus(function() {
        var div = $('div.example').show();
        $(document).bind('focusin.example click.example',function(e) {
            if ($(e.target).closest('.example, #example').length) return;
            $(document).unbind('.example');
            div.fadeOut('medium');
        });
    });
    $('div.example').hide();​
    

    更新了代码以同时使用 focusin 和 click 事件来决定是否隐藏 div.example。我正在使用命名空间事件,这样我就可以调用 unbind('.example') 来解除它们的绑定。

    示例:http://jsfiddle.net/9XmVT/11/

    旁注 将您的 css 定位代码更改为仅调用 css 方法一次:

    $('div.example').css({
        "position":"absolute",
        "left": fieldExample.offset().left,
        "top": fieldExample.offset().top + fieldExample.outerHeight()
    });
    

    使用绝对定位 div 的示例:http://jsfiddle.net/9XmVT/14/

    更新

    Ben Alman 刚刚更新了他的 clickoutside 事件并将其转换为处理大量 *outside 事件。 http://benalman.com/projects/jquery-outside-events-plugin/

    会让你做这样的事情:

    $('#example').focus(function() {
        $('div.example').show().bind('focusoutside clickoutside',function(e) {
            $(this).unbind('focusoutside clickoutside').fadeOut('medium');
        });
    });
    $('div.example').hide();
    

    【讨论】:

    • 嗨,彼得,不幸的是,div 仍然消失了。当您单击或选择该 div.example 中的文本时,我希望它保持可见。直到用户专门点击其他地方,div 才会消失。在这里感谢您的帮助。谢谢:)
    • @Lyon 你是对的。刚刚用适合您的方式更新了我的答案。
    • 谢谢彼得。我真的很感谢你在这方面的帮助。我一直在绞尽脑汁想弄清楚如何做到这一点。是否也可以这样做,当用户单击其他地方时,例如页面上的文本或页面背景(例如 input/div 不再是焦点),该 div.example 也会消失?目前,它仅在我单击下一个输入时才会消失。太感谢了。我正在尝试调整您的代码以无济于事:(
    • @Lyon 更新了处理点击和制表符的答案,应该解决点击文本而不隐藏的问题
    • @Lyon Ben Alman 刚刚更新了他的 clickoutside 事件插件以处理更多内容,而不仅仅是点击外部。 benalman.com/projects/jquery-outside-events-plugin 你可能感兴趣的东西。
    【解决方案2】:

    http://jsfiddle.net/9XmVT/699/

    使用 iframe 进行点击时死机

    【讨论】:

      【解决方案3】:

      您可以使用计时器来引入轻微的延迟,如果焦点在字段上或单击 div,则停止计时器:

      var timer = false ;
      $('#example').focus(function() {
          if (timer)
              clearTimeout(timer);
          $('div.example').css('display','block');
      
        }).blur(function() {
      
          if (timer)
              clearTimeout(timer);
      
          timer = setTimeout(function(){
                  $('div.example').fadeOut('medium');
              },500);
      
        });
      
      $('div.example').click(function(){
          if (timer)
              clearTimeout(timer);
      })
      

      【讨论】:

      • 并没有真正解决问题,只是延迟了问题的出现。
      【解决方案4】:

      解决这个问题的简单 JavaScript 方法是结合使用 relatedTarget 和包装器。由于relatedTarget 的工作方式,您的div.example 需要具有焦点才能与relatedTarget 一起使用。但是因为div 元素默认情况下是不可聚焦的,所以您需要通过将tabindex="0"tabindex="-1" 属性添加到元素来使您的div.example 可聚焦。您可以在此 MDN tabindex 文档中阅读两者之间的区别。

      运行以下代码以查看实际情况。我为div.example 元素添加了一个红色边框,以便更好地表示。

      const wrapper = document.getElementById("wrapper");
      const toggle = document.querySelector("#example");
      const target = document.querySelector("div.example");
      
      toggle.addEventListener("focus", () => {
        target.style.display = "";
      });
      
      wrapper.addEventListener("focusout", (event) => {
        if (wrapper.contains(event.relatedTarget)) {
          return;
        }
        target.style.display = "none";
      });
      <div id="wrapper">
        <label for="example">Text:</label>
        <input id="example" name="example" type="text" maxlength="100" />
        <div class="example" tabindex="0" style="border: 1px solid red;">Some text...<br />More text...</div>
      </div>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-03
        相关资源
        最近更新 更多