【问题标题】:How to set focus on the next input field generated by ng-repeat?如何将焦点设置在 ng-repeat 生成的下一个输入字段上?
【发布时间】:2016-12-24 11:37:12
【问题描述】:

我有一个使用 angularJS 和 ionic 的 iOS 应用程序。当按下“返回”按钮时,我试图将键盘焦点放在下一个输入字段上。这是存在 ng-repeat 的 HTML 代码:

            <div class="row item-list" ng-repeat="item in shoppingList">
                <div class="col col-10 col-check" ng-click="checkItem($index)">
                    <i class="icon ion-checkmark-round" ng-if="item.Action == 'check'"></i>
                </div>
                <div class="col col-memo" ng-click="updateMemo($index)">
                    <label class="item-list item-input">
                        <input id="inputText" type="text" placeholder="" ng-model="item.EventContent" on-return="nextLine($index)"/>
                    </label>
                </div>
            </div>

您可以在我的输入元素中看到“on-return="nextLine($index)"”。我正在使用我的自定义指令,该指令在按下返回按钮时使用:

.directive('onReturn', function () {
return function (scope, element, attrs) {
    element.bind("keydown keypress", function (event) {
        if (event.which === 13) {
            scope.$apply(function () {
                scope.$eval(attrs.onReturn);
            });
            event.preventDefault();
        }
    });
};
});

在我的控制器中调用我的 nextLine 函数:

myScope.nextLine = function (index) {
    //get next html input element and .setFocus()
}

其中 index 是当前输入框的索引。我需要一种方法来获取下一个 HTML 输入元素并在那里设置焦点。任何帮助表示赞赏。

【问题讨论】:

  • 不要直接使用scope.$apply,而是使用$timeout() - 它“聪明”地使用$apply - 而不是“残酷”的。

标签: javascript html ios angularjs


【解决方案1】:

根据我的经验,更多的事件驱动方法更适合焦点管理。将事件传递给 nextLine 方法。假设你只使用 jQuery light,你最终会得到这样的结果:

//add closest method to jQuery light
$.fn.closest = function (selector) {
  var el = this[0];
  while (el && self.matches(el, selector)) {
    el = el.parentElement;
  }
  return $(el);
};

myScope.nextLine = function (event) {
  var nextInput = $(event.target).closest("[ng-repeat]").find("input");
  if(nextInput[0]){
    nextInput[0].focus();
  }
}

【讨论】:

    【解决方案2】:

    首先,不建议在 DOM 事件监听器中使用多个指令实例。如果你有 1000 个指令监听同一个“keydown”事件怎么办?那会完全阻塞系统。

    也许你应该用旧的 jQuery 来解决这个问题:添加一个 容器元素的“keydown”事件侦听器,然后在每次“返回”按键时迭代输入字段:Working demo here

    模板的简化版本:

    <div class="items-lists" on-return>
        <input type="text" ng-repeat="item in shoppingList" class="item-list">
    </div>
    

    然后在你的指令中:

    angular.module('MyApp')
        .directive('onReturn', function() {
            return {
                restrict: 'A',
                link: function(scope, element, attr) {
                    $(element).on("keydown keypress", function(event) {
                        if (event.which === 13) {
                            scope.nextLine();
                            event.preventDefault();
                        }
                    });
    
                    //get next html input element and set focus()
                    scope.nextLine = function() {
                        var nextInput =  $(element).find('input:focus').next('input');
                        var firstInput = $(element).find('input')[0];
                        nextInput.length ? nextInput.focus() : firstInput.focus();
                    }
                }
            }
        });
    

    解决方案 #2:

    另一种方法是使用ng-focus 指令并将其绑定到布尔表达式。在此示例中,单击一个项目将通过将 item.selected 更改为 true 并取消选择其他项目以编程方式将其设置为焦点:

    <div class="items-lists">
        <input ng-repeat="item in shoppingList" ng-focus="item.selected" ng-click="selectItem(item)" class="item-list">
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 2018-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多