禁用聚焦按钮不会将焦点移动到下一个可聚焦项目

时间:2018-02-07 05:37:19

标签: javascript jquery html

根据标题,我有一个按钮只能被击中3次然后它将禁用(使用jQuery)本身。

的test.html

<div class="main">
  <input  class="one" type="text" />
  <button class="two" >If you hit me I will disabling myself...</button>
  <button class="three">...and focus should be moved to me!</button>
</div>

test.js

$('.two').on('keyup', function(event) {
    $(event.target).attr('disabled', true);
});

假设用户正在使用键盘,方法是按Enter键

为什么当当前关注的按钮被禁用时焦点不会移动到下一个按钮?

这里有一个指向小提琴的链接,显示我的意思:https://jsfiddle.net/8dyk2b2m/

修改1

假设:

  1. 你不知道下一个可聚焦的项目是什么,但你想让它成为焦点
  2. 我有一些情况下,下一个可聚焦的项目不是当前的一个兄弟(next()不起作用)
  3. 修改2

    我的DOM是动态生成的,这就是为什么我无法逐个管理但我需要更通用的算法。对我来说,陌生的事情仍然是当我禁用当前聚焦的字段时,浏览器无法移动焦点。

    编辑3

    在下面的评论中,此StackOverflow question的关联解决方案并未涵盖所有情况,因为禁用操作会阻止keyup事件被触发,并且 - 另一方面 - keydown事件是提前的,因为当按下按钮时会创建一个新的部分(显然是由其他地方的另一个keydown处理程序和,我无法修改那个处理程序直接)

4 个答案:

答案 0 :(得分:3)

好的,最后我得到了一个好结果。我会在这里发布我的答案,以防有人想要做同样的事情或改进它:

<强> utils.js

function setFocusToClosestTabbableField(target, forward) {
    var promise = $timeout(function () {
        // Find the focused element in case of the given target is not valid
        var $focused = (target instanceof Element || target instanceof jQuery) ? $(target) : $(document.activeElement);

        // Check if the element is visible and enabled
        var isDisabled = $focused.is(':disabled');
        var isHidden   = $focused.is(':hidden');
        if (isDisabled || isHidden) {
            // If the focused element is disabled we have to enable it temporarily in order to find it 
            // in the list of the tabbable elements
            if (isDisabled) {
                $focused.attr('disabled', false);
            }

            // Retrieving now the list of tabbable elements and restore the status of the focused one if needed
            var $tabbables = $(':tabbable');
            if (isDisabled) {
                $focused.attr('disabled', true);
            }

            // Find the index of the current focused element and retrieve the index of the next on tabbable 
            // in the list
            var focusedIndex = $tabbables.index($focused);
            var nextIndex    = focusedIndex + ((forward == null || forward == true) ? 1 : -1);
            if (nextIndex < 0 || nextIndex > $tabbables.length - 1) {
                nextIndex = (forward == null || forward == true) ? 0 : $tabbables.length - 1;
            }

            // Get the next element focusable and put the focus on it
            $focused = $($tabbables.get(nextIndex));
            $focused.focus();

            // If the field is disable force a keyup event because the browser engine prevents it
            if (isDisabled) {
                $focused.keyup();
            }
        }

        // Return the focused element
        return $focused;
    }, 200);

    return promise;
}

<强> main.js

// Registering both keydown and keyup since the browser will prevent the second one if the 
// focused field becomes disabled in a previously attache handler to the keydown event
$('body').on('keydown keyup', function() {
    var key = event.keyCode | -1
    var managedKeys = [
        -1,  // Manually triggered key event
        9,   // Tab
        13,  // Enter
        32   // Space
    ];

    // I check also Enter and Space since if I hit one of them while the focus is on a button and this 
    // button will get disabled, then I have to find the next tabbable field and put the focus on it
    if (managedKey.indexOf(key) > -1) {
        var $target = $(event.target);
        setFocusToClosestTabbableField($target, !event.shiftKey);
    }
});

备注

如果有人想讨论我的解决方案或希望改进它,请不要犹豫!干杯!

答案 1 :(得分:0)

您可以使用clickfocus

$('.two').on('click', function(event) {
  $(event.target).attr('disabled', true);
  $(this).next().focus();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
  <input class="one" type="text" />
  <button class="two">If you hit me I will disabling myself...</button>
  <button class="three">...and focus should be moved to me!</button>
</div>

答案 2 :(得分:0)

你必须将焦点添加到下一个元素:

$('.two').on('keyup', function(event) {
	$(event.target).attr('disabled', true);
        $(event.target).next().focus();
});
.main * {
  display: block;
  margin: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
  <input  class="one" type="text" />
  <button class="two" >If you hit me I will disabling myself...</button>
  <button class="three">...and focus should be moved to me!</button>
</div>

答案 3 :(得分:0)

对不起,我无法评论,所以回答它。

小提琴正在为我工​​作,可能是浏览器在执行函数后不知道要执行什么。 如果你有焦点注入javascript。在函数执行结束时它工作。 但是为什么要触发焦点,没有答案,为什么它不是由浏览器处理的。

 $('.two').on('keyup', function(event) {     
    $(event.target).attr('disabled', true);                 
    $('.three').focus();                                                  
 });