Mis*_*hko 753 angularjs angularjs-directive
在AngularJS中设置焦点到输入字段的"角度方式"是什么?
更具体的要求:
<input>此模态中.<input>变得可见(例如,通过单击某个按钮),将焦点设置在它上面.我试图达到第一个要求有autofocus,但只有当模态被打开的第一次,只有在特定的浏览器(如Firefox中这是行不通的)这个作品.
任何帮助将不胜感激.
Mar*_*cok 575
- 打开模态时,将焦点设置在此模态内的预定义<input>上.
定义一个指令并让它$ watch一个属性/触发器,以便知道何时聚焦元素:
Name: <input type="text" focus-me="shouldBeOpen">
Run Code Online (Sandbox Code Playgroud)
app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
return {
//scope: true, // optionally create a child scope
link: function (scope, element, attrs) {
var model = $parse(attrs.focusMe);
scope.$watch(model, function (value) {
console.log('value=', value);
if (value === true) {
$timeout(function () {
element[0].focus();
});
}
});
// to address @blesh's comment, set attribute value to 'false'
// on blur event:
element.bind('blur', function () {
console.log('blur');
scope.$apply(model.assign(scope, false));
});
}
};
}]);
Run Code Online (Sandbox Code Playgroud)
似乎需要$ timeout来给出模态时间来渲染.
"2".每次<input>变得可见(例如,通过单击某个按钮),将焦点设置在它上面.
创建一个基本上与上面相似的指令.观察一些范围属性,当它变为真时(在你的ng-click处理程序中设置它),执行element[0].focus().根据您的使用情况,您可能需要或不需要$ timeout超时:
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
Run Code Online (Sandbox Code Playgroud)
app.directive('focusMe', function($timeout) {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.focusMe, function(value) {
if(value === true) {
console.log('value=',value);
//$timeout(function() {
element[0].focus();
scope[attrs.focusMe] = false;
//});
}
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
2013年7月更新:我见过一些人使用我原来的隔离范围指令,然后遇到嵌入式输入字段的问题(即模态中的输入字段).没有新范围(或可能是新的子范围)的指令应该可以缓解一些痛苦.所以上面我更新了不使用隔离范围的答案.以下是原始答案:
原始答案为1.,使用隔离范围:
Name: <input type="text" focus-me="{{shouldBeOpen}}">
Run Code Online (Sandbox Code Playgroud)
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '@focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === "true") {
$timeout(function() {
element[0].focus();
});
}
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
2.使用隔离范围的原始答案:
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" focus-me="focusInput">
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
Run Code Online (Sandbox Code Playgroud)
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '=focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === true) {
//console.log('trigger',value);
//$timeout(function() {
element[0].focus();
scope.trigger = false;
//});
}
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
由于我们需要重置指令中的trigger/focusInput属性,因此'='用于双向数据绑定.在第一个指令中,'@'就足够了.另请注意,使用'@'时,我们将触发值与"true"进行比较,因为@始终会生成一个字符串.
Ben*_*esh 262
Mark Rajcok是男人......他的答案是一个有效的答案,但它有一个缺陷(对不起Mark)......
...尝试使用布尔值来聚焦输入,然后模糊输入,然后尝试使用它再次聚焦输入.除非您将布尔值重置为false,然后将$ digest重置,然后将其重置为true,否则它将无效.即使您在表达式中使用字符串比较,您也将被迫将字符串更改为其他内容,$ digest,然后将其更改回来.(这已通过模糊事件处理程序解决.)
所以我建议这个替代解决方案:
毕竟JavaScript喜欢事件.事件本质上是松耦合的,甚至更好,你避免在$ digest中添加另一个$ watch.
app.directive('focusOn', function() {
return function(scope, elem, attr) {
scope.$on(attr.focusOn, function(e) {
elem[0].focus();
});
};
});
Run Code Online (Sandbox Code Playgroud)
所以现在你可以像这样使用它:
<input type="text" focus-on="newItemAdded" />
Run Code Online (Sandbox Code Playgroud)
然后在你的应用程序的任何地方
$scope.addNewItem = function () {
/* stuff here to add a new item... */
$scope.$broadcast('newItemAdded');
};
Run Code Online (Sandbox Code Playgroud)
这很棒,因为你可以用这样的东西做各种各样的事情.首先,您可以绑定已经存在的事件.另一方面,您可以通过让应用的不同部分发布应用的其他部分可以订阅的事件来开始做一些聪明的事情.
无论如何,这种类型的东西尖叫着"事件驱动"给我.我认为,作为Angular开发人员,我们非常努力地将范围形状的钉子敲入事件形状孔.
这是最好的解决方案吗?我不知道.这是一个解决方案.
在@ ShimonRachlenko的评论之后,我已经改变了我的方法.现在我使用服务和处理"幕后"事件的指令的组合:
除此之外,它与上面概述的相同.
<input type="text" focus-on="focusMe"/>
Run Code Online (Sandbox Code Playgroud)
app.controller('MyCtrl', function($scope, focus) {
focus('focusMe');
});
Run Code Online (Sandbox Code Playgroud)
app.directive('focusOn', function() {
return function(scope, elem, attr) {
scope.$on('focusOn', function(e, name) {
if(name === attr.focusOn) {
elem[0].focus();
}
});
};
});
app.factory('focus', function ($rootScope, $timeout) {
return function(name) {
$timeout(function (){
$rootScope.$broadcast('focusOn', name);
});
}
});
Run Code Online (Sandbox Code Playgroud)
小智 241
当你真正需要的是这个时,我发现其他一些答案过于复杂
app.directive('autoFocus', function($timeout) {
return {
restrict: 'AC',
link: function(_scope, _element) {
$timeout(function(){
_element[0].focus();
}, 0);
}
};
});
Run Code Online (Sandbox Code Playgroud)
用法是
<input name="theInput" auto-focus>
Run Code Online (Sandbox Code Playgroud)
我们使用超时来让dom渲染中的东西,即使它是零,它至少等待它 - 这种方式适用于模态和其他什么
Ray*_*tor 90
HTML有一个属性autofocus.
<input type="text" name="fname" autofocus>
Run Code Online (Sandbox Code Playgroud)
http://www.w3schools.com/tags/att_input_autofocus.asp
Jor*_*anC 62
您还可以使用内置于angular中的jqlite功能.
angular.element('.selector').trigger('focus');
San*_*ngh 55
这很有效,也是一种聚焦输入控制的角度方式
angular.element('#elementId').focus()
Run Code Online (Sandbox Code Playgroud)
这虽然不是完成任务的纯粹角度方式,但语法遵循角度样式.Jquery使用Angular(jQLite => JQuery Light)间接地扮演角色并直接访问DOM.
如果需要,可以很容易地将此代码放在一个简单的角度指令中,其中元素可以直接访问.
Cod*_*niz 31
我不认为$ timeout是将元素集中在创建上的好方法.这是一种使用内置角度功能的方法,从角度文档的阴暗深处挖掘出来.请注意,对于预链接和后链接功能,如何将"链接"属性拆分为"前"和"后".
工作示例:http://plnkr.co/edit/Fj59GB
// this is the directive you add to any element you want to highlight after creation
Guest.directive('autoFocus', function() {
return {
link: {
pre: function preLink(scope, element, attr) {
console.debug('prelink called');
// this fails since the element hasn't rendered
//element[0].focus();
},
post: function postLink(scope, element, attr) {
console.debug('postlink called');
// this succeeds since the element has been rendered
element[0].focus();
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
<input value="hello" />
<!-- this input automatically gets focus on creation -->
<input value="world" auto-focus />
Run Code Online (Sandbox Code Playgroud)
完整的AngularJS指令文档:https://docs.angularjs.org/api/ng/service/$compile
Umu*_*zer 17
我写了一个双向绑定焦点指令,就像最近的模型一样.
您可以像这样使用focus指令:
<input focus="someFocusVariable">
Run Code Online (Sandbox Code Playgroud)
如果true在控制器的任何位置创建someFocusVariable范围变量,输入将得到集中.如果你想"模糊"输入,那么someFocusVariable可以设置为false.这就像Mark Rajcok的第一个答案,但具有双向绑定.
这是指令:
function Ctrl($scope) {
$scope.model = "ahaha"
$scope.someFocusVariable = true; // If you want to focus initially, set this to true. Else you don't need to define this at all.
}
angular.module('experiement', [])
.directive('focus', function($timeout, $parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(attrs.focus, function(newValue, oldValue) {
if (newValue) { element[0].focus(); }
});
element.bind("blur", function(e) {
$timeout(function() {
scope.$apply(attrs.focus + "=false");
}, 0);
});
element.bind("focus", function(e) {
$timeout(function() {
scope.$apply(attrs.focus + "=true");
}, 0);
})
}
}
});
Run Code Online (Sandbox Code Playgroud)
用法:
<div ng-app="experiement">
<div ng-controller="Ctrl">
An Input: <input ng-model="model" focus="someFocusVariable">
<hr>
<div ng-click="someFocusVariable=true">Focus!</div>
<pre>someFocusVariable: {{ someFocusVariable }}</pre>
<pre>content: {{ model }}</pre>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
这是小提琴:
http://fiddle.jshell.net/ubenzer/9FSL4/8/
Edh*_*ler 17
这是我原来的解决方案:
var app = angular.module('plunker', []);
app.directive('autoFocus', function($timeout) {
return {
link: function (scope, element, attrs) {
attrs.$observe("autoFocus", function(newValue){
if (newValue === "true")
$timeout(function(){element[0].focus()});
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
和HTML:
<button ng-click="isVisible = !isVisible">Toggle input</button>
<input ng-show="isVisible" auto-focus="{{ isVisible }}" value="auto-focus on" />
Run Code Online (Sandbox Code Playgroud)
它通过ng-show变为可见的输入.这里没有使用$ watch或$.
BPH*_*BPH 11
对于那些将Angular与Bootstrap插件一起使用的人:
http://angular-ui.github.io/bootstrap/#/modal
你可以挂钩opened模态实例的承诺:
modalInstance.opened.then(function() {
$timeout(function() {
angular.element('#title_input').trigger('focus');
});
});
modalInstance.result.then(function ( etc...
Run Code Online (Sandbox Code Playgroud)
我发现使用通用表达式很有用.通过这种方式,您可以在输入文本有效时执行自动移动焦点等操作
<button type="button" moo-focus-expression="form.phone.$valid">
Run Code Online (Sandbox Code Playgroud)
或者在用户完成固定长度字段时自动对焦
<button type="submit" moo-focus-expression="smsconfirm.length == 6">
Run Code Online (Sandbox Code Playgroud)
当然,重点是加载后
<input type="text" moo-focus-expression="true">
Run Code Online (Sandbox Code Playgroud)
指令的代码:
.directive('mooFocusExpression', function ($timeout) {
return {
restrict: 'A',
link: {
post: function postLink(scope, element, attrs) {
scope.$watch(attrs.mooFocusExpression, function (value) {
if (attrs.mooFocusExpression) {
if (scope.$eval(attrs.mooFocusExpression)) {
$timeout(function () {
element[0].focus();
}, 100); //need some delay to work with ng-disabled
}
}
});
}
}
};
});
Run Code Online (Sandbox Code Playgroud)
小智 7
您可以简单地使用javascript函数来完成焦点,而不是创建自己的指令.
这是一个例子.
在html文件中:
<input type="text" id="myInputId" />
Run Code Online (Sandbox Code Playgroud)
在文件javascript中,例如在控制器中,您要激活焦点:
document.getElementById("myInputId").focus();
Run Code Online (Sandbox Code Playgroud)
不要复活僵尸或插入我自己的指令(好吧,这正是我正在做的):
https://github.com/hiebj/ng-focus-if
http://plnkr.co/edit/MJS3zRk079Mu72o5A9l6?p=preview
<input focus-if />
(function() {
'use strict';
angular
.module('focus-if', [])
.directive('focusIf', focusIf);
function focusIf($timeout) {
function link($scope, $element, $attrs) {
var dom = $element[0];
if ($attrs.focusIf) {
$scope.$watch($attrs.focusIf, focus);
} else {
focus(true);
}
function focus(condition) {
if (condition) {
$timeout(function() {
dom.focus();
}, $scope.$eval($attrs.focusDelay) || 0);
}
}
}
return {
restrict: 'A',
link: link
};
}
})();
Run Code Online (Sandbox Code Playgroud)
首先,关注的官方方法是1.1的路线图.同时,您可以编写指令来实现设置焦点.
其次,在项目变得可见之后将焦点设置在当前需要一种解决方法.只需使用a延迟对元素焦点()的调用$timeout.
因为对焦点,模糊和选择存在相同的controller-modifies-DOM问题,我建议有一个ng-target指令:
<input type="text" x-ng-model="form.color" x-ng-target="form.colorTarget">
<button class="btn" x-ng-click="form.colorTarget.focus()">do focus</button>
Run Code Online (Sandbox Code Playgroud)
Angular线程在这里:http://goo.gl/ipsx4,更多细节在这里博客:http://goo.gl/4rdZa
以下指令将.focus()在您的控制器内创建一个由您的ng-target属性指定的函数.(它创建了一个.blur()和一个.select().)演示:http://jsfiddle.net/bseib/WUcQX/
如果您只是想要一个由 ng-click 控制的简单焦点。
网址:
<input ut-focus="focusTigger">
<button ng-click="focusTrigger=!focusTrigger" ng-init="focusTrigger=false"></button>
Run Code Online (Sandbox Code Playgroud)
指示:
'use strict'
angular.module('focus',['ng'])
.directive('utFocus',function($timeout){
return {
link:function(scope,elem,attr){
var focusTarget = attr['utFocus'];
scope.$watch(focusTarget,function(value){
$timeout(function(){
elem[0].focus();
});
});
}
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
580019 次 |
| 最近记录: |