无法将 .focus() 赋予下拉菜单的元素

Posted

技术标签:

【中文标题】无法将 .focus() 赋予下拉菜单的元素【英文标题】:Cannot give .focus() to an element of a dropdown menu 【发布时间】:2014-11-25 15:01:08 【问题描述】:

这是一个 Boostrap 导航栏,包含一个 dropdown 菜单,它本身包含一个 <input>

当我点击下拉菜单时,它会成功显示。 <input> 的值已成功更改为 Bonjour 但此 <input> 没有获得焦点。为什么?

http://jsfiddle.net/rzsmdg4f/1/

如何使用.focus() 将焦点放在下拉菜单中包含的输入上?


代码:

<div class="navbar navbar-default navbar-static-top" role="navigation">
    <div class="container">
        <ul class="nav navbar-nav">
            <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="maa">Dropdown<span class="caret"></span></a>
                <ul class="dropdown-menu" role="menu" style="min-width: 250px;">
                    <li>
                        <div style="padding:4px 20px;">Link:</div>
                    </li>
                    <li>
                        <div style="padding:4px 20px;">
                            <input class="form-control" id="ha" type="text" placeholder="blabla" />
                        </div>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
</div>

JS:


    var maa = document.getElementById('maa');
    console.log(maa);
    maa.addEventListener('click', function () 
        console.log($('#ha'));
        $('#ha').val('Bonjour');
        $('#ha').focus();
    );
;

【问题讨论】:

【参考方案1】:

jsFiddle Demo

元素在点击时存在,因此更改它的值并记录它会正确显示元素的当前状态。但是,它尚未显示,因此聚焦它不会真正产生任何效果。您可能可以重构库中的一些小 sn-p 以公开一个可用于使您的焦点工作的钩子。或者,您可以观察到在下一个事件处理程序中该元素将是可见的并使用一个小的超时。

maa.addEventListener('click', function () 
    console.log($('#ha'));
    $('#ha').val('Bonjour');
    setTimeout(function()$('#ha').focus();,10);//timeout here
);

【讨论】:

感谢它有效!但是当我们点击这个菜单时,例如选择 框,下拉菜单消失了...我们可以禁用下拉菜单的自动消失吗...并且设置只有当我们点击下拉菜单之外时才会消失 当然,只要让 click 事件对该输入返回 false 即可。 $('#ha').click(function()return false;);jsfiddle.net/rzsmdg4f/11 谢谢@TravisJ。您已经可以在这里看到它的实际效果:bigpicture.bi/jjwpi6! :) '保存时生成新 URL' 还不起作用...... &lt;input&gt;有焦点时,你知道如何删除默认的类似Boostrap的highlight吗? #ha:focus 过渡:无;盒子阴影:无;边框:默认; 【参考方案2】:

我想到的最简单的解决方案就是延迟焦点。其不聚焦的原因是该元素尚不可见。

http://jsfiddle.net/xab7Leoq/

setTimeout(function() 
  $('#ha').focus();
, 100);

另一种解决方案是找出它何时可见,然后执行此操作。它可能是一个更好但更复杂的解决方案。 :)

edit1:停止传播:

// Prevents the propagation
$('#ha').click(function(ev) 
  ev.stopPropagation();
);

点赞http://jsfiddle.net/xab7Leoq/

【讨论】:

也谢谢!你知道为什么当我们点击输入时下拉菜单会消失吗?我们能不能禁用它,让下拉菜单只有在我们点击外部时才会消失? 您需要停止传播。我在我的答案中添加了这个。 也在努力解决这个问题,但既然你打败了我......只是想补充一下,我认为问题不是因为它还不可见。如果您将输入放在菜单之外(始终可见)并尝试将焦点设置为它,它也不起作用。我认为下拉菜单的某些内容将重点放在点击上(在点击事件返回之后)。您可能会关注焦点事件或鼠标上移事件,但我只需使用 setTimeout,它就可以工作。 如果您要向该下拉列表(或其他)添加更多输入字段,我将定位 $('.dropdown-menu input') 而不仅仅是单个输入元素。只是一个想法。【参考方案3】:

想我也可以发布一个答案,即使迟到了......因为这似乎运作良好并且不需要 setTimeout:http://jsfiddle.net/cvLbfttL/

$("#maa").focus(function () 
    $('#ha').val('Bonjour');
    $('#ha').focus();
    return false;
);
$('#ha').click(function()return false;);

锚点“maa”在点击时获得焦点,它发生在点击回调/事件返回之后。因此,您可以改为在焦点事件中编写代码。我不知道如何在 JSFiddle 中标记到锚点,但我认为如果您使用其他方法将焦点设置到锚点,代码也会运行,但我认为这应该没问题,甚至可能很好。

【讨论】:

【参考方案4】:

一个使用回调函数的例子。避免使用 setTimeout() 函数,因为结果是不可预测的。

http://jsfiddle.net/v62tdn9z/

var $maa=$('#maa'), $ha=$('#ha');

$maa.mousedown( function () 
    $ha.val('Bonjour');
    $maa.mousemove(function ()  $ha.focus(); );
);

【讨论】:

【参考方案5】:

在元素上设置 tabindex 可能是解决方案。这在我的情况下有效。

【讨论】:

请包含一些代码(最好带有可运行的“代码 sn-p”),以便此答案有用。

以上是关于无法将 .focus() 赋予下拉菜单的元素的主要内容,如果未能解决你的问题,请参考以下文章

无法修复 laravel 上的顺风组件下拉菜单

asp二级联动下拉菜

Jquery:下拉菜单在移动设备上无法正常工作

Jquery下拉菜单单击始终打开

无法从下拉菜单中选择选项

选择固定宽度的下拉菜单,在 IE 中截断内容