我有一个带有模糊事件的标准文本输入。单击文档中的任何内容(输入AND <div id='show-anyways'></div>
除外)时,应触发blur事件。
我的问题是我不知道如何添加<div id='show-anyways'></div>
来否定模糊事件功能。
希望我已经解释得很好,我知道这有点奇怪。如果您需要更多信息,请与我们联系。
答案 0 :(得分:10)
使用事件目标确定点击的内容。以下将跟踪文档的所有点击,如果元素是DIV或输入,则不会触发blur()。
var $input=$( '#MY-Input-ID');
$(document).click(function(evt){
var $tgt=$(evt.target);
if( !$tgt.is( '#show-anyways') && !$tgt.is($input) ){
$input.blur()
}
})
它不会触发设置了任何preventPropogation的元素。
答案 1 :(得分:1)
更新:必须完全重写我的解决方案。 blur
事件处理程序附加到失去焦点的事件:如果它与mouseout
事件类似,我们可以知道哪个元素将获得焦点,但是没有这样的运气。因此,我们必须采用捕获.click
事件 - 并根据它触发某些功能,而不是监听blur
事件。
var inputIsBlurred = function() {
console.log('Run away!!!');
};
$(document).click(function(e){
var $target = $(e.target);
console.log($target);
if ($target.is('#some_input') // fired by an input - no special effects
|| $target.is('#show-anyways') // fired by 'show-anyways' div
|| $target.parents('#show-anyways').length > 0 // ... or its children
) {
return true; // move along, nothing to do here
}
inputIsBlurred();
});
这里是a fiddle。对不起由我的原始答案引起的混乱。 (
答案 2 :(得分:1)
其他解决方案中缺少一些东西。最重要的是,您需要在调用模糊事件之前检查输入是否已被聚焦。另一件事是,不仅在你点击其他地方时调用模糊事件:当你转到浏览器中的另一个标签或者点击tab
或shift + tab
进入时,你也可以调用它下一个/上一个输入。最后,当您检查目标元素是否是模糊事件的异常(它可能是您的异常的子代)时,您需要考虑使用jQuery函数closest()。
所以,我想出了这个jQuery原型函数:
$.fn.extend({
blurIfNot : function(options, handler)
{
var defaults =
{
except : [],
maxParent : null // A DOM element within which
// a matching element may be found
};
var opt = $.extend({}, defaults, options);
var time = new Date().getTime();
this.each(function()
{
var thisInp = $(this);
thisInp[0].blurIfNot = {};
time += 1000000000000;
var except = opt.except;
if ($.isFunction(opt.except))
{ except = opt.except.call(thisInp[0]); }
function fire_blur_event(_tar, evt, mousedown)
{
var proceed = true;
for (var i in except)
{
if (_tar.is(thisInp) ||
_tar.closest(except[i], opt.maxParent).length)
{
proceed = false;
break;
}
}
if (proceed)
{
thisInp[0].blurIfNot.focus = false;
handler.call(thisInp[0], evt);
}
else if (mousedown)
{
$('html').one('mouseup', function(e)
{
thisInp[0].focus();
});
}
}
if (!thisInp[0].blurIfNot.isset)
{
$('html').mousedown(function(e)
{
if (thisInp[0].blurIfNot.focus)
{
var tar = $(e.target);
if (!tar.is('input'))
{ fire_blur_event(tar, e, true); }
}
});
$(window).blur(function(e)
{
if (thisInp[0].blurIfNot.focus)
{
thisInp[0].blurIfNot.focus = false;
handler.call(thisInp[0], e);
}
});
}
else
{ // to be able to update the input event if you have
// created new inputs dynamically
$('input').off('focus.blufIfNot' + time);
}
$('input').on('focus.blurIfNot' + time, function(e)
{
var tar = $(e.target);
if (tar[0] == thisInp[0])
{ thisInp[0].blurIfNot.focus = true; }
else if (thisInp[0].blurIfNot.focus)
{ fire_blur_event(tar, e); }
});
thisInp[0].blurIfNot.isset = true;
});
return this;
}
});
$('#input_blur_if_not').blurIfNot(
{
except : [
$('.autocomplete'), $('.question')
],
// You can also define the elements with a function:
// except : function()
// {
// return [ $(this).parent().find('.autocomplete') ];
// },
maxParent : $('#parent')[0] // optional
},
function(e)
{
var rand = Math.random();
$('#test').css('padding', rand * 100 + "px").
html(rand + " blur !");
});
&#13;
.autocomplete {
background: #eee;
}
.autocomplete, input {
width: 200px;
padding: 3px;
border: 1px solid #555;
}
.question {
display:inline-block;
border-radius:50%;
background:#137dba;
color:#fff;
font-weight:bold;
padding:2px 7px;
cursor:pointer;
}
#test {
position:absolute;
top:0;
left:260px;
color:red;
font-weight:bold;
padding:10px 0;
vertical-align:bottom;
}
&#13;
<script src="http://code.jquery.com/jquery-latest.js"></script>
<div id="parent">
<input value="an input" />
<br><br>
<input id="input_blur_if_not" value="input with autocomplete menu" />
<div class="question">?</div>
<div class="autocomplete">
<div>option 1</div>
<div>option 2</div>
</div>
<br>
<input value="another input" />
<div id="test"></div>
</div>
&#13;
在Chrome和IE11中测试过。如果您需要更多解释,请随时发表评论。
答案 3 :(得分:0)
可以尝试添加一些逻辑吗?
$('input').blur(function(e){
var tester = e.target;
if ($(tester).attr('id') == 'show-anyways'){
return false;
}
else {
// do something?
}
});
这基本上会在模糊发生时触发,它会检查点击/标记的内容以及是否恰好是show-anyways然后它将返回false并停止执行任何操作。但是如果它不显示 - 那么它可以做你的模糊事件吗?
未经测试,但这是你的意思吗?