在 ng-repeat 中动态添加输入会导致最后一个元素在 safari 中窃取焦点
dynamic add input in ng-repeat causes last element to steal focus in safari
我希望用户能够为一个问题输入多个答案,所以我有一个 ng-repeat 的文本输入,随着用户添加更多答案而增加。
这在 chrome 中运行良好,但在 safari 中,最后一个元素一添加就抢走了焦点,将快速输入的用户答案分散到多个输入中。
在 iOS Safari 中,情况更糟,因为它会导致浏览器挂起。
这是表单的代码
<form class="form-horizontal sparse"
ng-controller="AssessmentController as assessment">
<fieldset>
<div class="form-group alt-uses-list" ng-repeat="response in answer.responses">
<label for="answer{{$index}}" class="col-xs-1 control-label">{{$index + 1}}.</label>
<div class="col-xs-10">
<input type="text" class="form-control"
id="response.uses{{$index}}"
autocomplete="off" tabIndex="{{$index + 1}}"
autofocus="{{$first}}" ng-model="response.value"
ng-change="assessment.addAnswerIfNeeded()">
</div>
</div>
</fieldset>
</form>
这是控制器
function AssessmentController($scope, $log) {
$scope.answer = {};
$scope.answer.responses = [{id:0, value:""},{id:1, value:""}];
this.addAnswerIfNeeded = addAnswerIfNeeded;
// Add answer if the last two answers are non-empty
function addAnswerIfNeeded() {
var answers = $scope.answer.responses;
if ((answers[answers.length - 1].value != '') ||
(answers[answers.length - 2].value != '')) {
addAnswer();
}
}
// Adds a new answer if this is the last element
// isLast is needed to prevent non-lazy evaluation bugs
function addAnswer() {
$scope.answer.responses.push({
id:$scope.answer.responses.length, value: ""
});
};
}
我创建了一个 jsfiddle。
autofocus
属性是 Boolean
类型。
根据this link:
The value passed as the first parameter is converted to a boolean value, if necessary. If value is omitted or is 0, -0, null, false, NaN, undefined, or the empty string (""), the object has an initial value of false. All other values, including any object or the string "false", create an object with an initial value of true.
Do not confuse the primitive Boolean values true and false with the true and false values of the Boolean object
autofocus="{{$first}}"
对任何不是 ng-repeat
中第一项的项目生成 autofocus="false"
。正如 link 所述
All other values, including any object or the string "false", create an object with an initial value of true.
如果您可以更新到包含 ng-attr
指令的 angular JS 版本,您可以将您的代码更新为以下代码,我已经更新了您 jsfiddle 以显示一个有效的例子
<form class="form-horizontal sparse" ng-controller="AssessmentController as assessment">
<fieldset>
<div class="form-group alt-uses-list" ng-repeat="response in answer.responses">
<label for="answer{{$index}}" class="col-xs-1 control-label">{{$index + 1}}.</label>
<div class="col-xs-10">
<input type="text" class="form-control" id="response.uses{{$index}}" autocomplete="off" tabIndex="{{$index + 1}}" ng-attr-autofocus="{{$first||undefined}}" ng-model="response.value" ng-change="assessment.addAnswerIfNeeded()">
</div>
</div>
</fieldset>
</form>
当 ng-attr-autofocus="{{$first||undefined}}"
的计算结果为 false 时,autofocus
属性获得 undefined
的值,因此 autofocus
从 dom 中移除。
我希望用户能够为一个问题输入多个答案,所以我有一个 ng-repeat 的文本输入,随着用户添加更多答案而增加。
这在 chrome 中运行良好,但在 safari 中,最后一个元素一添加就抢走了焦点,将快速输入的用户答案分散到多个输入中。
在 iOS Safari 中,情况更糟,因为它会导致浏览器挂起。
这是表单的代码
<form class="form-horizontal sparse"
ng-controller="AssessmentController as assessment">
<fieldset>
<div class="form-group alt-uses-list" ng-repeat="response in answer.responses">
<label for="answer{{$index}}" class="col-xs-1 control-label">{{$index + 1}}.</label>
<div class="col-xs-10">
<input type="text" class="form-control"
id="response.uses{{$index}}"
autocomplete="off" tabIndex="{{$index + 1}}"
autofocus="{{$first}}" ng-model="response.value"
ng-change="assessment.addAnswerIfNeeded()">
</div>
</div>
</fieldset>
</form>
这是控制器
function AssessmentController($scope, $log) {
$scope.answer = {};
$scope.answer.responses = [{id:0, value:""},{id:1, value:""}];
this.addAnswerIfNeeded = addAnswerIfNeeded;
// Add answer if the last two answers are non-empty
function addAnswerIfNeeded() {
var answers = $scope.answer.responses;
if ((answers[answers.length - 1].value != '') ||
(answers[answers.length - 2].value != '')) {
addAnswer();
}
}
// Adds a new answer if this is the last element
// isLast is needed to prevent non-lazy evaluation bugs
function addAnswer() {
$scope.answer.responses.push({
id:$scope.answer.responses.length, value: ""
});
};
}
我创建了一个 jsfiddle。
autofocus
属性是 Boolean
类型。
根据this link:
The value passed as the first parameter is converted to a boolean value, if necessary. If value is omitted or is 0, -0, null, false, NaN, undefined, or the empty string (""), the object has an initial value of false. All other values, including any object or the string "false", create an object with an initial value of true.
Do not confuse the primitive Boolean values true and false with the true and false values of the Boolean object
autofocus="{{$first}}"
对任何不是 ng-repeat
中第一项的项目生成 autofocus="false"
。正如 link 所述
All other values, including any object or the string "false", create an object with an initial value of true.
如果您可以更新到包含 ng-attr
指令的 angular JS 版本,您可以将您的代码更新为以下代码,我已经更新了您 jsfiddle 以显示一个有效的例子
<form class="form-horizontal sparse" ng-controller="AssessmentController as assessment">
<fieldset>
<div class="form-group alt-uses-list" ng-repeat="response in answer.responses">
<label for="answer{{$index}}" class="col-xs-1 control-label">{{$index + 1}}.</label>
<div class="col-xs-10">
<input type="text" class="form-control" id="response.uses{{$index}}" autocomplete="off" tabIndex="{{$index + 1}}" ng-attr-autofocus="{{$first||undefined}}" ng-model="response.value" ng-change="assessment.addAnswerIfNeeded()">
</div>
</div>
</fieldset>
</form>
当 ng-attr-autofocus="{{$first||undefined}}"
的计算结果为 false 时,autofocus
属性获得 undefined
的值,因此 autofocus
从 dom 中移除。