我遇到过这个问题几次,之前用过的解决方案让我不太满意。
我有一个输入框,带有模糊事件来验证其内容,并且有一个按钮,点击该按钮会填充输入框。问题是,点击按钮会触发输入框的失焦事件和按钮的点击事件,因此由按钮插入的内容不是被验证的内容。
请参见http://jsfiddle.net/jakecr/dL3K3/
我知道这是正确的行为,但我想不到一个干净的方法来解决这个问题。
我遇到过这个问题几次,之前用过的解决方案让我不太满意。
我有一个输入框,带有模糊事件来验证其内容,并且有一个按钮,点击该按钮会填充输入框。问题是,点击按钮会触发输入框的失焦事件和按钮的点击事件,因此由按钮插入的内容不是被验证的内容。
请参见http://jsfiddle.net/jakecr/dL3K3/
我知道这是正确的行为,但我想不到一个干净的方法来解决这个问题。
在工作中我们遇到了类似的问题。最后我们发现,mousedown事件会在blur事件之前触发,这样你就可以在验证之前设置内容,甚至可以使用标志完全取消验证过程。
查看我使用你的示例创建的这个fiddle - http://jsfiddle.net/dL3K3/31/
$(function(){
var flag = true;
$('input').blur(function(){
if(!$(this).val() && flag){
alert("Grrr, It's empty");
}
});
$('button').mousedown(function(){
flag = false;
});
$('button').mouseup(function(){
flag = true;
$('input').val('content').focus();
});
});
-编辑-
正如@mclin建议的那样,使用mousedown事件和preventDefault将防止失焦行为。
而且你可以保留原来的click事件不变 -
http://jsfiddle.net/dL3K3/364/
$(function(){
$('input').blur(function(){
if(!$(this).val()){
alert("Grrr, It's empty");
}
});
$('button').mousedown(function(e){
e.preventDefault();
});
$('button').click(function(){
$('input').val('content');
});
});
这个解决方案可能会更加清晰,适用于大多数情况,但请注意如果使用它,您将会阻止当前焦点元素的preventDefault和blur事件,但对于大多数用例来说,这不应该是一个问题。
我有比Yoni Jah更好的解决方案:
在按钮的鼠标按下事件上调用preventDefault。因此onBlur事件永远不会发生,所以你可以在点击事件中自由地做任何事情。
这样做更好,因为它不会通过在鼠标弹起而不是在鼠标按下时执行操作来改变单击行为,这可能会让人感到意外。
// Namespace for timer var setTimer = { timer: null }
$('input,select').blur(function () {
setTimer.timer = setTimeout(function () {
functionCall();
}, 1000);
});
$('input,select').focus(function () {
setTimer.timer = setTimeout(function () {
functionCall();
}, 1000);
});
$("#btn").click(function () {
clearTimeout(setTimer.timer);
functionCall();
});
$('input').blur(function() {
validate(this);
});
$('submit').click(function() {
//modify the input element
validate(inputElement);
});
var validate = function(obj) {
// validate the object
}
var cancelHide = false;
$('.my-input').blur(function() {
if (!cancelHide) {
$('.my-item').hide();
}
});
$('.my-input').click(function() {
$('.my-item').show();
});
$('.my-item').mousedown(function() {
cancelHide = true;
});
$('.my-item').mouseup(function() {
var text = $(this).text();
alert(text);
cancelHide = false;
$('.my-input').blur();
});
html
<input type="text" class="my-input"/>
<div class="my-item">Hello</div>
<div class="my-item">Lovely</div>
<div class="my-item">World</div>
CSS
。.my-item {
display:none;
}
https://jsfiddle.net/tic84/on421rxg/
单击列表项仅会在鼠标弹起时发出警报,尽管父元素试图在模糊时隐藏它们
诀窍在于不要使用模糊和点击事件,因为它们总是按照模糊先,点击后的顺序执行。相反,您应该检查具有焦点的元素何时发生了更改,因为这只会在单击后发生。
我认为我对此有一个优雅的解决方案:
var alreadyValidated = 'true';
setInterval(function(){
if(document.activeElement.id != 'validation-field-id'){
if(alreadyValidated=='false'){
alreadyValidated = 'true';
validate(document.activeElement);
}
}
else {
alreadyValidated = 'false';
}
}, 200);
现今的现代浏览器都支持document.activeElement。
true
和 false
而不是字符串,因为 Boolean('false') === true
。 - Jake