【问题标题】:Keep focus on dropdown list while writing in input text在输入文本中书写时保持关注下拉列表
【发布时间】:2016-11-06 09:05:42
【问题描述】:

我是 AngularJS 和 Bootstrap 的新手,希望得到一些帮助。

我正在尝试创建一个按输入文本过滤的动态下拉列表。 这是我的代码:

<input id="SelectedCountry" type="text" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="true" ng-model="Pass" autocomplete="off"  />
<ul class="dropdown-menu">
  <li data-ng-repeat="r in countrycodes | MyFilter *my filter in the app.filter. works fine*"><a href="#" data-ng-click="selectedcountry.value=r.value">{{r.name}}</a></li>
</ul>

我希望每次用户单击向下箭头键时,焦点都会放在下拉列表上(这不会自动发生,为什么?),所以我编写了以下代码:

$(document).on('shown.bs.dropdown', function (event) {
    var dropdown = $(event.target);
    $("input").keydown(function (e) {
        if ((e.which && e.which == 40) || (e.keyCode && e.keyCode == 40)) {
            // Set aria-expanded to true
            dropdown.find('.dropdown-menu').attr('aria-expanded', true);

            // Set focus on the first link in the dropdown
            dropdown.find('.dropdown-menu li:first-child a').focus();

            return false;
        } else {
            return true;
        }
    });
});

我的问题是当用户按下向下箭头键时,焦点不再在输入文本上,所以他不能继续写。

如何制作一个动态下拉列表,让用户可以在焦点位于菜单上时继续书写? 我已经尝试过使用 Jquery 过滤器,但它没有成功,因为我必须使用 AngularJs,所以我可以在用户选择他的选项时触发 data-ng-click,此外我还获得了 data-ng- 的选项重复,所以我不能在 html 中使用默认的“select”和“option”标签。 我到处寻找解决方案的地方都说不能同时关注元素。也许还有另一种选择?因为有很多网站都有这种情况?

感谢您的帮助

【问题讨论】:

    标签: javascript jquery html angularjs twitter-bootstrap-3


    【解决方案1】:

    是的,你是对的。不能同时聚焦 2 个元素。

    【讨论】:

      【解决方案2】:

      它不会自动关注下拉列表,因为不应该这样做。当用户在普通输入字段中向上或向下按下时(没有事件侦听器和类似的特殊内容),光标应该只移动到最左边或最右边,具体取决于按下的内容。

      此外,您无法同时让他们保持专注。只有一个元素可以成为焦点。您可以做的是保留一个变量,说明哪个下拉列表元素是“聚焦”的,并为用户按下回车键设置一个事件侦听器,该侦听器将执行有关该列表元素的任何操作。当按下向上或向下时,该变量将发生变化。此外,如果按下向上/向下,您应该使用 event.preventDefault() 来阻止光标向左/向右移动。希望这会有所帮助。

      更新

      还有一件事。为了模拟点击所需的下拉列表项,您可以使用jQuery's trigger function。

      更新 2

      我做了一个示例代码,因为我不知道如何表达我的意思。另外,我没有使用过 jQuery——一切都是 vanilla JS。因此我也没有使用触发功能。随意玩弄它或评判它(这也是我所做的):

      <html>
          <head>
              <style>
                  #content {
                      width: 500px;
                      margin-top: 30px;
                      margin: 0 auto;
                  }
      
                  #search-list {
      
                  }
      
                  #search-list li {
                      display: block;
                      width: 200px;
                      height: 40px;
                      line-height: 40px;
                      padding: 5px;
                      border: 1px solid #666;
                  }
      
      
                  #search-list li.focused {
                      background: #aaa;
                  }
              </style>
          </head>
          <body>
              <div id="content">
                  <input id="search-input" type="text" value="" placeholder="Type text here"  />
                  <ul id="search-list">
                      <li>Meow</li>
                      <li>Roar</li>
                      <li>Mewore</li>
                      <li>Foo</li>
                      <li>Bar</li>
                      <li>Bartender</li>
                  </ul>
                  <div id="log">
                  </div>
              </div>
      
              <script type="text/javascript">
                  var items = document.getElementById('search-list').getElementsByTagName('li');
      
                  document.getElementById('search-input').addEventListener("keydown", keyDownHandler);
      
                  for(var i=0; i<items.length; i++) {
                      items[i].addEventListener("mouseover", mouseOverHandler );
                      items[i].addEventListener("mouseout", mouseOutHandler );
                      items[i].addEventListener("click", clickHandler );
                  }
      
                  function getElementIndex(elem) {
                      var children = event.target.parentNode.childNodes;
                      var idx=-1;
                      for(var i=0; i<children.length; i++) {
                          if(children[i].nodeType == 1) {
                              idx++;
                              if(children[i] == elem) return idx;
                          }
                      }
                  }
      
                  function mouseOverHandler(event) {
                      var idx = getElementIndex(event.target);
      
                      if(currentItem != -1) items[currentItem].className = "";
      
                      event.target.className = "focused";
                      currentItem = idx;
                  }
      
                  function mouseOutHandler(event) {
                      var idx = getElementIndex(event.target);
                      event.target.className = "";
                      if(currentItem == idx) {
                          currentItem = -1;
                      }
                  }
      
                  function clickHandler(event) {
                      document.getElementById('log').innerHTML += '<p>' + event.target.innerText + '</p>';
                  }
      
                  var currentItem = -1;
      
                  function keyDownHandler(event) {
                      var keyPressed = event.which || event.keyCode;
                      if(keyPressed == 38) {
                          //up
                          event.preventDefault();
                          if(currentItem >= 0) {
                              items[currentItem].className = "";
                          }
                          currentItem = (currentItem == -1) ? (items.length-1) : (currentItem-1);
                          if(currentItem >= 0) {
                              items[currentItem].className = "focused";
                          }
                      } else if(keyPressed == 40) {
                          //down
                          event.preventDefault();
                          if(currentItem >= 0) {
                              items[currentItem].className = "";
                          }
                          currentItem = (currentItem == items.length - 1) ? -1 : (currentItem+1);
                          if(currentItem >= 0) {
                              items[currentItem].className = "focused";
                          }
                      } else if(keyPressed == 13) {
                          //enter
                          if(currentItem == -1) document.getElementById('log').innerHTML += '<p>' + event.target.value + '</p>';
                          else document.getElementById('log').innerHTML += '<p>' + items[currentItem].innerText + '</p>';
                      }
                  }
              </script>
          </body>
      </html>
      

      【讨论】:

      • 首先,感谢您的回答。其次,您说“您可以做的是保留一个变量,说明哪个下拉列表元素是“聚焦”的”。我怎么知道当时关注的是哪个下拉列表元素?我尝试了几件事,但没有成功。
      • 还有一件事,如果下拉列表和输入框不能同时聚焦,怎么有很多动态搜索框(最简单的例子是谷歌的搜索框或Facebook)可以让你聚焦继续输入输入文本时的选项?
      猜你喜欢
      • 2016-02-15
      • 1970-01-01
      • 2013-03-08
      • 2022-06-13
      • 1970-01-01
      • 2019-02-27
      • 2019-01-02
      • 1970-01-01
      • 2018-12-01
      相关资源
      最近更新 更多