【问题标题】:jQuery events; prevent "siblings" from triggering eachothers eventsjQuery 事件;防止“兄弟姐妹”触发彼此的事件
【发布时间】:2011-07-21 21:23:57
【问题描述】:

使用 jQuery 1.6.1,假设我有以下 HTML:

<div class="control">
    <label>My Control</label>
    <input type="text" />
    <input type="text" />
</div>

&lt;div class="control"&gt;以下仅control)中的&lt;input&gt; 被聚焦时,&lt;label&gt;position: relative;)动画: p>

$('.control :input').bind('focus', function(e){
    $(this).prevAll('label').animate({
        'left': '-50px'
    }, 250);
});

当模糊时,&lt;label&gt; 返回:

.bind('blur', function(e){
    $(this).prevAll('label').animate({
        'left': '0px'
    }, 250);
});

但是,如果 &lt;input&gt; 元素之一获得焦点,然后随着焦点切换到同一 control 内的另一个 &lt;input&gt;通过 Tab 或鼠标单击)当然,事件仍然会触发,&lt;label&gt; 会来回动画。

如何仅在给定control 内的所有输入失去焦点时才强制触发模糊事件?

【问题讨论】:

    标签: javascript-events event-handling jquery


    【解决方案1】:

    编辑:根据 OP 提供的更多输入更新了答案。

    如果隐藏标签稍微延迟一秒钟就可以了,那么您可以使用 setTimeout/clearTimeout 组合。 比如:

    <div class="control">
        <label>My Control</label>
        <input type="text" />
        <input type="text" />
        <input type="text" />
    </div>
    <div class="control">
        <label>My Control</label>
        <input type="text" />
        <input type="text" />
        <input type="text" />
    </div>
    
    <div class="control">
        <label>My Control</label>
        <input type="text" />
        <input type="text" />
        <input type="text" />
    </div>
    
    <div class="control">
        <label>My Control</label>
        <input type="text" />
        <input type="text" />
        <input type="text" />
    </div>
    
        <script type="text/javascript"> 
            var timeoutIds = [];
                $('.control').each(function(index, el){
                    $(':input', el).bind('focus', function(e){     
                            clearTimeout(timeoutIds[index]);
                            $(this).prevAll('label').animate({        
                                    'left': '-50px'     
                            }); 
                    });
    
                    $(':input', el).bind('blur', function(e){     
                            var that = this;
                            timeoutIds[index] = setTimeout(function(){
                                $(that).prevAll('label').animate({        
                                        'left': '0px' 
                                }); 
                        }, 500);
                    });
                });
        </script>
    

    工作示例:http://jsfiddle.net/Tn9sV/2/

    【讨论】:

    • 谢谢@Cyber​​nate - 几乎就像一个魅力。也许这是我的错,因为我没有提到会有不止一个control。从control 切换到control 时,由于第二个调用了clearTimeout(),第一个模糊无法触发。
    • @Tomcat:但是先触发模糊,然后聚焦第二个。
    • 谢谢,但没有@Cyber​​nate,很抱歉没有。这就是我的意思jsfiddle.net/Tn9sV/1 有什么想法吗?
    • 直接解决您的答案,我必须分配(和管理)一个 timeoutIds 数组,也许将它们分配给给定的 control 元素作为任意 @987654329 @,但对于一些容易误导的简单事情来说,这似乎是一个非常大的开销。
    • @TomcatExodus:我明白您所说的多个控件是什么意思。让我看看是否有任何简单的替代方案
    【解决方案2】:

    在您的模糊回调中,我会查看类似于 1.6 中引入的 :focus 选择器:

    Using jQuery to test if an input has focus

    如果$('.control :focus).length &gt; 0return 停止运行的函数。

    【讨论】:

    • 感谢@Alex Mcp - 不幸的是,模糊事件似乎(在我粗略的测试中)在下一个焦点事件之前立即触发,即使是从@987654325 立即切换@到input;它总是计算为 0。
    • 啊,有趣。根据其他答案,我认为稍微延迟一下就可以了。给焦点一个注册的机会,然后评估是否存在 :focused 元素。
    • 也许,我希望@Cyber​​nate 提出的答案能让我到达那里。
    【解决方案3】:

    我过去通过将新焦点绑定到文档或表单并让它触发标签返回来实现类似的效果,而不是将模糊绑定到输入。

    【讨论】:

    • 谢谢@citizen conn - 这似乎是一个可行的解决方案,但是我似乎无法将focus 事件绑定到bodydocumentwindow 等。什么元素具体来说,您是否将事件处理程序附加到?
    • @TomcatExodus 抱歉,绑定 mousedown 事件,不关注
    • 感谢@citizen conn - 但问题是,如果我Tab 退出控制组,它不会触发。
    • @TomcatExodus GP... 然后您可以将焦点事件绑定到以下和以前的字段。我知道,情节变厚了,但否则它可能需要更多疯狂的 js,而不仅仅是 jquery 事件处理。
    【解决方案4】:

    blur 回调中,您可以使用此$("input:focus").length 检测现在是否有任何输入元素被聚焦。如果length&gt;0比不动画

    更新

    这段代码呢?

        var control;
        var inTheSameControl=false;
        $('.control :input').bind('focus', function(e){
            if(control)
            {
                if(control.find(this).length>0)
                    inTheSameControl=true;
                else
                    inTheSameControl=false;
            }
            control=$(this).parent();
            if(!inTheSameControl)
            {
                console.log('focus');
            }
        });
        $('.control :input').bind('blur', function(e){
            if(!inTheSameControl)
            {
                console.log('blur');
            }
        });
    

    它适用于多个div.control 当您将焦点切换到另一个.contor 中的input 时,文本“焦点”会登录到控制台,如果您留在同一个.control - 不会。 你可以写你想要的,而不是console.log(...)。我没有写你的代码(动画),因为它不是主题。

    希望对你有帮助。

    【讨论】:

    • 谢谢@Ruslan Polutsygan - 不幸的是它不起作用,请参阅我对亚历克斯回答的评论。
    【解决方案5】:

    我能想到的两个选项:

    • 选项 1(使用当前方案):

      • 模糊:将动画延迟几分之一秒

      • 焦点:.停止您现有的动画

    • 选项 2(更改模糊项):

      • 将模糊项更改为在您的 div 上而不是标签上

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 2017-12-09
      • 1970-01-01
      相关资源
      最近更新 更多