Bootstrap下拉菜单中的键盘导航

时间:2022-05-28 19:20:16

As you know using Boostrap drop-down components you are not able to select an element by pressing the Keyboard Letter. So i was using the following code which use a directive

如您所知,使用Boostrap下拉组件时,您无法通过按键盘字母选择元素。所以我使用以下代码使用指令

myApp.directive('keyLetterPressed', function ($timeout) {
   return function (scope, element, attrs) {
    element.bind("keydown keypress", function (event) {

            var target = $(event.target);
            $(target).trigger('focus');

    });
   };
});

but this is not complete, actually is not working, just you can tell me how do i go to the element which have the same letter of the list ? Also i have to put this directive in the Ul element ? Because actually I am using it on the li

但这不完整,实际上不起作用,只是你可以告诉我如何去列出具有相同字母的元素?另外我必须把这个指令放在UI元素中吗?因为实际上我在li上使用它

<li ng-repeat="v in values" keyLetterPressed>{{v.name}}</li>

2 个解决方案

#1


1  

another answer is this, adding the directive to the ul element

另一个答案就是这个,将指令添加到ul元素

 app.directive('booststrapDropdown',
 function () {
  return {
      restrict: 'A',
      link: function (scope, element, attr) {
          console.log('linked');
          element.parent().bind('keypress', function (e) {
              children = element.children();
              children.removeClass("active");
              for (var i = 0; i < children.length; i++) {
                  var letter = String.fromCharCode(e.which);
                  var charat = children[i].textContent.replace(/\s+/, '').charAt(0);
                  if (charat === letter) {
                      children[i].className += " active";
                      element[0].scrollTop = children[i].offsetTop;
                  }
              }
          });
      }
  };
  });



  <div class="btn-group" dropdown>
    <button type="button" class="btn btn-primary dropdown-toggle" 
            dropdown-toggle>
      Button dropdown <span class="caret"></span>
    </button>
    <ul booststrap-dropdown class="dropdown-menu scrollable-menu" role="menu" >
      <li ng-repeat="v in values">
        <a href="#">{{v.name}}</a>
      </li>
    </ul>
  </div>

#2


0  

This can be an a partial answer as you can see it worked just need a little adjustments.

这可能是一个部分答案,因为你可以看到它只需要一些调整。

Check this jsfiddle

检查这个jsfiddle

Here is the code :

这是代码:

    myApp.directive('keypressEvents',

    function ($document, $rootScope) {
    return {
    restrict: 'A',
    link: function (scope, element, attr) {
        console.log('linked');
        $document.bind('keypress', function (e) {
        $rootScope.$broadcast('keypress', e,  String.fromCharCode(e.which)); 
        var letter = String.fromCharCode(e.which);

        var target = e.target;

        var charat = element[0].textContent.charAt(0);

        if(charat === letter){ 
                element.addClass("red");
        }
        });
    }
}
});

Up there is the directive used, it simply is bound on the keypressed and in the end set the class for the element found with the same first letter just I need to set the focus on this and not just change the class

向上有使用的指令,它只是在keypressed上绑定,并且在最后设置了用相同的第一个字母找到的元素的类,我需要将焦点设置在此而不仅仅是更改类

  <div class="dropup">
  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
   Dropup
   <span class="caret"></span>
  </button>
      <ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
        <li keypress-events><a href="#">action</a></li> 
       <li keypress-events><a href="#">something else here</a></li> 
     </ul>
   </div>

I have bound the directive on the li elements. (rootscope and brodcast message was needed just for debugging)

我已经对li元素绑定了指令。 (只需进行调试就需要rootcope和brodcast消息)

#1


1  

another answer is this, adding the directive to the ul element

另一个答案就是这个,将指令添加到ul元素

 app.directive('booststrapDropdown',
 function () {
  return {
      restrict: 'A',
      link: function (scope, element, attr) {
          console.log('linked');
          element.parent().bind('keypress', function (e) {
              children = element.children();
              children.removeClass("active");
              for (var i = 0; i < children.length; i++) {
                  var letter = String.fromCharCode(e.which);
                  var charat = children[i].textContent.replace(/\s+/, '').charAt(0);
                  if (charat === letter) {
                      children[i].className += " active";
                      element[0].scrollTop = children[i].offsetTop;
                  }
              }
          });
      }
  };
  });



  <div class="btn-group" dropdown>
    <button type="button" class="btn btn-primary dropdown-toggle" 
            dropdown-toggle>
      Button dropdown <span class="caret"></span>
    </button>
    <ul booststrap-dropdown class="dropdown-menu scrollable-menu" role="menu" >
      <li ng-repeat="v in values">
        <a href="#">{{v.name}}</a>
      </li>
    </ul>
  </div>

#2


0  

This can be an a partial answer as you can see it worked just need a little adjustments.

这可能是一个部分答案,因为你可以看到它只需要一些调整。

Check this jsfiddle

检查这个jsfiddle

Here is the code :

这是代码:

    myApp.directive('keypressEvents',

    function ($document, $rootScope) {
    return {
    restrict: 'A',
    link: function (scope, element, attr) {
        console.log('linked');
        $document.bind('keypress', function (e) {
        $rootScope.$broadcast('keypress', e,  String.fromCharCode(e.which)); 
        var letter = String.fromCharCode(e.which);

        var target = e.target;

        var charat = element[0].textContent.charAt(0);

        if(charat === letter){ 
                element.addClass("red");
        }
        });
    }
}
});

Up there is the directive used, it simply is bound on the keypressed and in the end set the class for the element found with the same first letter just I need to set the focus on this and not just change the class

向上有使用的指令,它只是在keypressed上绑定,并且在最后设置了用相同的第一个字母找到的元素的类,我需要将焦点设置在此而不仅仅是更改类

  <div class="dropup">
  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
   Dropup
   <span class="caret"></span>
  </button>
      <ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
        <li keypress-events><a href="#">action</a></li> 
       <li keypress-events><a href="#">something else here</a></li> 
     </ul>
   </div>

I have bound the directive on the li elements. (rootscope and brodcast message was needed just for debugging)

我已经对li元素绑定了指令。 (只需进行调试就需要rootcope和brodcast消息)