[英]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.