gpt4 book ai didi

javascript - 如何通过添加/删除 Angular 输入来管理焦点/光标位置?

转载 作者:行者123 更新时间:2023-11-28 00:41:20 25 4
gpt4 key购买 nike

我正在制定一个指令,当所有输入字段都被填充时,该指令应该自动创建另一个输入字段。因此,在这个示例中,当我停止输入第三个输入时,将出现第四个输入,但我的光标应保留在第三个输入中。

问题是在我的代码中,最终输入始终存在,因此当我更新数据并将其值移动到倒数第二个输入时,它保留焦点,并且我无法聚焦倒数第二个输入当用户在去抖间隔结束后快速开始打字时,速度足够快,可以防止闪烁和字符丢失。

如何才能使其正常工作?

这个问题的 XY 版本是:在 ng-repeat 向 DOM 添加新元素后如何同步执行操作?

ui example

plunk

scope: {
// String[]
items: '=',

// 'input' or 'textarea'
type: '@',

// 'text', 'email', 'url', etc.
inputType: '@'
},

link: function (scope, element) {
scope._inputType = scope.inputType || 'text';
scope.temp = {
item: ""
};

var $el = jQuery(element.get(0));

// add another input when the user stops typing in the last input
scope.$watch('temp.item', (debounce)(function(){
if (scope.temp.item) {
scope.items.push(scope.temp.item);
scope.temp.item = "";
var elLast = $el.find('.item-last');
elLast.blur();

var currentInput = elLast.prev('.item-input').find('input').get(0);
var tries = 100;

// use nextTick to reduce time-to-update
// this often fires a few times before angular actually updates anything
nextTick(function again(){
var target = elLast.prev('.item-input').find('input');

// has angular updated? if not: retry
if (target.get(0) === currentInput && (--tries) > 0) {
return nextTick(again);
}

// focus and move cursor to end
target.focus();
var len = target.val().length;
target.get(0).setSelectionRange(len, len);
}, 0, false);
}
}, 500));

// remove empty items after a few seconds
scope.$watch('items', debounce(function(){
var items = scope.items;
var inputs = $el.find('.item-input > *');
var emptyBeforeFocused = 0;
var focusedIndex = null;

for (var i=0; i<inputs.length-1; i++) {
if (inputs.eq(i).is(':focus')) {
focusedIndex = i;
break;
}
if(!items[i]) {
emptyBeforeFocused++;
}
}

var originalLength = scope.items.length;
scope.items = scope.items.filter(x => x.length);

// we need to fix focus if a previous element was removed
if (scope.items.length !== originalLength && emptyBeforeFocused > 0 && focusedIndex) {
scope.$evalAsync(function(){
// grab the index of the focused input, minus the preceding removed inputs
// i.e. the input's new index
var target = $el.find('.item-input > *').eq(focusedIndex - emptyBeforeFocused);

// focus and move cursor to end
target.focus();
var val = scope.type === 'textarea' ? target.text() : target.val();
var len = val.length;
target.get(0).setSelectionRange(len, len);
}, 0, false);
}
}, 5000));
}
<div>
<div ng-if="type === 'input'">
<div class="item-input item-type-input" ng-repeat="item in items track by $index">
<input type="text" ng-model="items[$index]" class="form-control" />
</div>

<div class="item-input item-type-input item-last">
<input type="text" ng-model="temp.item" class="form-control" />
</div>
</div>
<div ng-if="type === 'textarea'">
<div class="item-input item-type-textarea" ng-repeat="item in items track by $index">
<textarea ng-model="items[$index]" class="form-control" ></textarea>
</div>
<div class="item-input item-type-textarea item-last">
<textarea ng-model="temp.item" class="form-control" ></textarea>
</div>
</div>
</div>

最佳答案

plnkr

.directive('resetFocus', [function(){
return function(scope, element, attr, ctrl) {
if(scope.$last){
element.find('input').focus();
}
};
}])

<div class="item-input item-type-input" ng-repeat="item in items track by $index" reset-focus>
<input type="text" ng-model="items[$index]" class="form-control" />
</div>

由于您也在进行删除,因此您可能需要 $watch('$last')

.directive('resetFocus', [function(){
return function(scope, element, attr, ctrl) {
if(scope.$last){
element.find('input').focus();
}
scope.$watch('$last', function(){
if(scope.$last){
element.find('input').focus();
}
});
};
}])

该指令在创建时将焦点设置在 ng-repeat 中的最后一个输入元素上。它利用了 ng-repeat 会将 $last 添加到作用域这一事实。

关于javascript - 如何通过添加/删除 Angular 输入来管理焦点/光标位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27884063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com