防止焦点事件后单击

Prevent click after focus event

本文关键字:单击 事件 焦点      更新时间:2023-09-26

当用户点击输入字段时,两个连续的事件正在执行:focusclick

focus总是首先执行并显示通知。但是紧跟在focus之后运行的click隐藏了通知。我只有在输入字段不集中并且两个事件连续执行时才有这个问题。

我正在寻找一个干净的解决方案,可以帮助我实现这样的功能(没有任何超时或奇怪的hack)。

:

<label for="example">Example input: </label>
<input type="text" id="example" name="example" />
<p id="notice" class="hide">This text could show when focus, hide when blur and toggle show/hide when click.</p>
JavaScript

:

$('#example').on('focus', _onFocus)
             .on('blur', _onBlur)
             .on('click', _onClick);
function _onFocus(e) {  
    console.log('focus');
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    $('#notice').removeClass('hide');
}
function _onClick(e) {
   console.log('click');
   $('#notice').toggleClass('hide');
}
function _onBlur(e) {
    console.log('blur');
    $('#notice').addClass('hide');
}

已更新的小提琴在这里

我觉得你把开关弄混了。不需要阻止传播之类的。只需检查click触发时通知是否已经可见。

演示:http://jsfiddle.net/3Bev4/13/

代码:

var $notice = $('#notice'); // cache the notice
function _onFocus(e) {  
    console.log('focus');
    $notice.removeClass('hide'); // on focus show it
}
function _onClick(e) {
   console.log('click');
    if ($notice.is('hidden')) { // on click check if already visible
       $notice.removeClass('hide'); // if not then show it
    }
}
function _onBlur(e) {
    console.log('blur');
    $notice.addClass('hide'); // on blur hide it
}

希望对你有帮助。

更新: 基于OP关于点击切换的说明:

只需将焦点事件缓存到状态变量中,然后根据状态显示通知或切换类。

演示2:http://jsfiddle.net/3Bev4/19/

更新代码:

var $notice = $('#notice'), isfocus = false; 
function _onFocus(e) {  
    isFocus = true; // cache the state of focus
    $notice.removeClass('hide');
}
function _onClick(e) {
    if (isFocus) { // if focus was fired, show/hide based on visibility
        if ($notice.is('hidden')) { $notice.removeClass('hide'); }
        isFocus = false; // reset the cached state for future
    } else {
        $notice.toggleClass('hide'); // toggle if there is only click while focussed
    }
}

更新2:基于OP在标签焦点后第一次点击的观察:

再想一下,你能绑定mousedownmouseup而不是click吗?这不会点燃焦点。

演示3:http://jsfiddle.net/3Bev4/24/

更新代码:

$('#example').on('focus', _onFocus)
             .on('blur', _onBlur)
             .on('mousedown', _onClick);
var $notice = $('#notice');
function _onFocus(e) { $notice.removeClass('hide'); }
function _onClick(e) { $notice.toggleClass('hide'); }
function _onBlur(e) { $notice.addClass('hide'); }

这对你有用吗?

为"focus"设置一个变量似乎可以达到目的:http://jsfiddle.net/3Bev4/9/

Javascript:

$('#example').on('focus', _onFocus)
    .on('click', _onClick)
    .on('blur', _onBlur);
focus = false;
function _onFocus(e) {
    console.log('focus');
    $('#notice').removeClass('hide');
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    focus = true;
}
function _onClick(e) {
    console.log('click');
    if (!focus) {
        $('#notice').toggleClass('hide');
    } else {
        focus = false;
    }
}
function _onBlur(e) {
    console.log('blur');
    $('#notice').addClass('hide');
}

如果你想隐藏通知的onBlur,当然需要:

function _onBlur(e) {
    console.log('blur');
    $('#notice').addClass('hide'); // Add the hidden class, not remove it
}

当在小提琴中这样做时,它似乎修复了它。

您所写的代码是正确的,除了您必须将$('#notice').removeClass('hide');替换为$('#notice').addClass('hide');

因为onBlur你想隐藏,所以添加隐藏类,而不是删除"hide"类。

我希望这就是你所犯的错误。如果我说错了请更正,因为我对JQuery了解不多,我只知道JavaScript。

您可以使用许多jQuery方法,而不是添加或移动类:

更新:添加一个参数来处理点击函数http://jsfiddle.net/3Bev4/23/

var showNotice = false;
$('#example').focus(function(){
     $('#notice').show();
     showNotice = true;
}).click(function(){
    if(showNotice){                
         $('#notice').show();
        showNotice = false;
    }else{
         showNotice = true;
        $('#notice').hide();
    }

}).blur(function(){
     $('#notice').hide(); 
});