简体   繁体   English

jQuery:在表单输入焦点上,显示 div。 隐藏 div 模糊(有一个警告)

[英]jQuery: On form input focus, show div. hide div on blur (with a caveat)

I am able to make a hidden div show/hide when an input field is in focus/blur using the following code:当输入字段处于焦点/模糊状态时,我可以使用以下代码显示/隐藏隐藏的 div:

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

The problem is I want div.example to continue to be visible when the user is interacting within this div.问题是当用户这个 div 中交互时,我希望div.example继续可见。 Eg click, or highlighting the text etc. within div.example .例如,单击或突出显示div.example的文本等。 However div.example fades out whenever the input is not in focus and the mouse is interacting with elements within the div.然而,每当输入不在焦点上并且鼠标与 div 内的元素交互时, div.example就会淡出。

The html code for the input and div elements is as follows: 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>

How do I make it such that the div.example only disappears when the user clicks outside the input and/or div.example ?如何使div.example仅在用户单击 input 和/或div.example外部时才会消失? I tried experimenting with focusin/focusout to check the focus on <p> but that didn't work either.我尝试尝试使用 focusin/focusout 来检查<p>上的焦点,但这也不起作用。

Would it matter that div.example is positioned directly below the input field #example using jQuery?使用 jQuery 将div.example直接定位在输入字段 #example 下方是否重要? The code that does that is as follows:执行此操作的代码如下:

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

My apologies if this has been asked before, but the many show/hide div questions I read does not cover this.如果之前有人问过这个问题,我深表歉意,但我阅读的许多显示/隐藏 div 问题并未涵盖这一点。 Thanks for your advice.谢谢你的建议。 :) :)

If you track the focusin event on the document since focusin bubbles then you can figure out if the new thing in focus is "outside" and if so do something about it.如果您在 focusin 气泡后跟踪文档上的 focusin 事件,那么您可以确定焦点中的新事物是否在“外部”,如果是,则对其进行处理。 This will work for both clicks and tabbing.这将适用于点击和标签。

$('#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();​

Updated the code to use both the focusin and click event to decide if to hide the div.example.更新了代码以使用 focusin 和 click 事件来决定是否隐藏 div.example。 I am using namespaced events so that I can call unbind('.example') to unbind both of them.我正在使用命名空间事件,以便我可以调用 unbind('.example') 来解除它们两个的绑定。

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

Side Note Change your css positioning code to only call the css method once:旁注更改您的 css 定位代码以仅调用一次 css 方法:

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

Example with using the absolute positioned div: http://jsfiddle.net/9XmVT/14/使用绝对定位 div 的示例: http : //jsfiddle.net/9XmVT/14/

UPDATE更新

Ben Alman just updated his clickoutside event and converted it to handle alot of *outside events. Ben Alman 刚刚更新了他的 clickoutside 事件并将其转换为处理大量 *outside 事件。 http://benalman.com/projects/jquery-outside-events-plugin/ http://benalman.com/projects/jquery-outside-events-plugin/

Would let you do something like this:会让你做这样的事情:

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

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

dead while onclick with Iframe使用 Iframe 在点击时死亡

You could use a timer to introduce a slight delay, and stop the timer if there's a focus on the field or a click on the div:您可以使用计时器来引入轻微的延迟,并在该字段上有焦点或单击 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);
})

A plain JavaScript way of solving this would be to use relatedTarget in combination with a wrapper.解决这个问题的一个简单的 JavaScript 方法是将relatedTarget与包装器结合使用。 And because of how relatedTarget works, your div.example will need to be focusable for it to work with relatedTarget .而且,因为如何relatedTarget工作,你div.example需要聚焦,它与工作relatedTarget But because div elements aren't focusable by default, you will need to make your div.example focusable by adding either tabindex="0" or tabindex="-1" attribute to the element.但是由于默认情况下div元素不可聚焦,您需要通过向div.example添加tabindex="0"tabindex="-1"属性来使div.example可聚焦。 You can read the difference between the two in this MDN tabindex documentation.您可以在此 MDN tabindex文档中阅读两者之间的区别。

Run the following code to see this in action.运行以下代码以查看此操作。 I have added a red border to the div.example element for better representation.我为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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM