在AngularJS中设置焦点到输入字段的“角度方式”是什么?
更具体的要求:
-
打开Modal时,将焦点设置在此模态内的预定义
<input>
上 . -
每次
<input>
变得可见(例如,通过单击某个按钮),将焦点设置在它上面 .
I tried to achieve the first requirement与 autofocus
,但这仅适用于第一次打开模态时,并且仅在某些浏览器中(例如在Firefox中不起作用) .
任何帮助将不胜感激 .
在AngularJS中设置焦点到输入字段的“角度方式”是什么?
更具体的要求:
打开Modal时,将焦点设置在此模态内的预定义 <input>
上 .
每次 <input>
变得可见(例如,通过单击某个按钮),将焦点设置在它上面 .
I tried to achieve the first requirement与 autofocus
,但这仅适用于第一次打开模态时,并且仅在某些浏览器中(例如在Firefox中不起作用) .
任何帮助将不胜感激 .
30 回答
这很简单..试试这个
HTML
JavaScript的
您还可以使用内置于angular的jqlite功能 .
angular.element('.selector').trigger('focus');
如果您正在使用modalInstance并拥有该对象,则可以在打开模态后使用“then”来执行操作 . 如果您没有使用modalInstance,并且硬编码打开模态,则可以使用该事件 . $ timeout不是一个好的解决方案 .
你可以做(Bootstrap3):
在modalInstance中,您可以查看库如何在打开模态后执行代码 .
不要像这样使用$ timeout,$ timeout可以是0,1,10,30,50,200或更多,这将取决于客户端计算机,以及打开模式的过程 .
不要使用$ timeout让方法告诉你何时可以集中注意力;)
我希望这有帮助! :)
我认为该指令是不必要的 . 使用HTML id和class属性选择所需的元素,并让服务使用document.getElementById或document.querySelector来应用焦点(或jQuery等价物) .
标记是标准的HTML /角度指令,添加了用于选择的id /类
控制器广播事件
在UI服务中使用querySelector - 如果有多个匹配(比如由于类),它将只返回第一个
您可能希望使用$ timeout()来强制摘要周期
这也可以使用
ngModelController
. 使用1.6(不知道旧版本) .HTML
JS
N.B . :根据上下文,您可能必须包含超时功能 .
N.B.²:当使用
controllerAs
时,这几乎是一样的 . 只需将name="myForm"
替换为name="vm.myForm"
并在JS中,vm.myForm.myText.$$element.focus();
.定义一个指令并让它$ watch一个属性/触发器,以便它知道何时聚焦元素:
Plunker
似乎需要$ timeout来给出模态时间来渲染 .
创建一个基本类似于上面的指令 . 观察一些scope属性,当它变为true时(在你的ng-click处理程序中设置它),执行
element[0].focus()
. 根据您的使用情况,您可能需要或不需要$ timeout超时:Plunker
Update 7/2013 :我见过一些人使用我原来的隔离范围指令,然后遇到嵌入式输入字段的问题(即模态中的输入字段) . 没有新范围(或可能是新的子范围)的指令应该可以缓解一些痛苦 . 所以上面我更新了不使用隔离范围的答案 . 以下是原始答案:
原始答案为1.,使用隔离范围:
Plunker .
2.使用隔离范围的原始答案:
Plunker .
由于我们需要重置指令中的trigger / focusInput属性,因此'='用于双向数据绑定 . 在第一个指令中,'@'就足够了 . 另请注意,使用'@'时,我们将触发值与“true”进行比较,因为@始终会生成一个字符串 .
我发现使用通用表达式很有用 . 通过这种方式,您可以在输入文本有效时执行自动移动焦点等操作
或者在用户完成固定长度字段时自动对焦
当然,重点是加载后
指令的代码:
以下指令为我做了诀窍 . 使用相同的autofocus html属性进行输入 .
一个适用于模态的简单方法:
例
不要复活僵尸或插入我自己的指令(好吧,这正是我正在做的):
https://github.com/hiebj/ng-focus-if
http://plnkr.co/edit/MJS3zRk079Mu72o5A9l6?p=preview
(编辑:我在此解释下添加了更新的解决方案)
Mark Rajcok是男人......他的答案是一个有效的答案,但它有一个缺陷(对不起Mark)......
...尝试使用布尔值聚焦输入,然后模糊输入,然后尝试使用它再次聚焦输入 . 除非您将布尔值重置为false,然后将$ digest重置,然后将其重置为true,否则它将无效 . 即使您在表达式中使用字符串比较,您也将被迫将字符串更改为其他内容,$ digest,然后将其更改回来 . (这已通过模糊事件处理程序解决 . )
所以我建议这个替代解决方案:
使用事件,Angular的遗忘功能 .
毕竟JavaScript喜欢事件 . 事件本质上是松散耦合的,甚至更好,你避免添加另一个$ watch到你的$消化 .
所以现在你可以像这样使用它:
然后在你的应用程序的任何地方
这很棒,因为你可以用这样的东西做各种各样的事情 . 首先,您可以绑定已经存在的事件 . 另一方面,您可以通过让应用的不同部分发布应用的其他部分可以订阅的事件来开始做一些聪明的事情 .
无论如何,这种类型的东西尖叫“事件驱动”给我 . 我认为作为Angular开发人员,我们非常努力地将范围形状的钉子敲入事件形状孔 .
这是最好的解决方案吗?我不知道 . 这是一个解决方案 .
更新了解决方案
在@ ShimonRachlenko的评论之后,我已经改变了我的方法 . 现在我使用服务和指令处理“幕后”事件的组合:
除此之外,它与上面概述的相同 .
Here is a quick demo Plunk
用法
来源
你可以创建一个强制关注postLinking上的装饰元素的指令:
然后在你的HTML中:
这适用于模态和ng-if切换元素,而不适用于ng-show,因为postLinking仅在HTML处理时发生 .
这是我原来的解决方案:
plunker
和HTML:
它的作用:
它通过ng-show变为可见的输入 . 这里不使用$ watch或$ .
这很有效,也是一种聚焦输入控制的角度方式
这虽然不是完成任务的纯粹角度方式,但语法遵循角度样式 . Jquery使用Angular(jQLite => JQuery Light)间接地扮演角色并直接访问DOM .
如果需要,可以很容易地将此代码放在一个简单的角度指令中,其中元素可以直接访问 .
我不认为$ timeout是将元素集中在创建上的好方法 . 这是一种使用内置角度功能的方法,从角度文档的阴暗深处挖掘出来 . 请注意,对于预链接和后链接功能,如何将“链接”属性拆分为“前”和“后” .
Working Example: http://plnkr.co/edit/Fj59GB
Full AngularJS Directive Docs: https://docs.angularjs.org/api/ng/service/$compile
如果在指令模板中注入了所需的焦点元素,则前面的所有答案都不起作用 . 以下指令适用于简单元素或指令注入元素(我在 typescript 中写了它) . 它接受内部可聚焦元素的选择器 . 如果你只需要关注self元素 - 不要向指令发送任何selector参数:
}
简单元素的用法示例:
内部元素的用法示例(通常用于动态注入元素,如带模板的指令):
你可以使用任何jQuery选择器而不是“输入”
我编辑Mark Rajcok的focusMe指令,以便在一个元素中实现多重焦点 .
HTML:
在AngularJs控制器中:
AngulaJS指令:
HTML具有
autofocus
属性 .http://www.w3schools.com/tags/att_input_autofocus.asp
我写了一个双向绑定焦点指令,就像最近的模型一样 .
你可以像这样使用focus指令:
如果在控制器的任何位置创建someFocusVariable范围变量
true
,则输入会得到集中 . 如果你想输入"blur",那么someFocusVariable可以设置为false . 它是_268671的第一个答案,但是双向绑定 .这是指令:
用法:
Here is the fiddle:
http://fiddle.jshell.net/ubenzer/9FSL4/8/
马克和布莱什有很好的答案;然而,Mark有一个Blesh指出的缺陷(除了实现起来很复杂)之外,我觉得Blesh的答案在创建服务时存在语义错误,该服务专门用于将焦点请求发送到前端,而真正他需要的只是一种方式延迟事件直到所有指令都在监听 .
所以这就是我最终做的事情,它从Blesh的答案中窃取了很多,但保持了控制器事件的语义和“后加载”服务的分离 .
这使得控制器事件可以轻松地用于除了仅关注特定元素之外的事物,并且还允许仅在需要时引起“后加载”功能的开销,这在许多情况下可能不是这样 .
用法
来源
只是扔一些咖啡 .
可能是ES6时代最简单的解决方案 .
添加以下一个衬垫指令可使HTML'自动对焦'属性对Angular.js有效 .
现在,您可以使用HTML5自动聚焦语法,如:
如果你只想要一个由ng-click控制的简单焦点 .
HTML:
指示:
对于那些将Angular与Bootstrap插件一起使用的人:
http://angular-ui.github.io/bootstrap/#/modal
您可以挂钩模态实例的
opened
promise:这里只是一个新手,但是我能够通过这个指令使它在_268719中工作:
在$ modal.open方法中,我使用了以下内容来表示应该重点关注的元素:
在模板上我有这个:
我想在寻找更好的解决方案而不是找到它之后为这个讨论做出贡献,而不得不创建它 .
标准:1 . 解决方案应独立于父控制器范围,以提高可重用性 . 2.避免使用$ watch来监视某些条件,这既缓慢又增加了摘要循环的大小并使测试更加困难 . 3.避免$ timeout或$ scope . $ apply()来触发摘要循环 . 4.输入元素存在于使用指令的元素中 .
这是我最喜欢的解决方案:
指示:
HTML:
我希望这能帮助那里的人!
您可以简单地使用javascript函数来完成焦点,而不是创建自己的指令 .
这是一个例子 .
在html文件中:
在文件javascript中,例如在控制器中,您要激活焦点:
不确定是否依赖超时是一个好主意,但这适用于ng-repeat,因为此代码运行后,angularjs更新DOM,因此您确保所有对象都在那里:
当你真正需要的是这个时,我发现其他一些答案过于复杂
用法是
我们使用超时来让dom渲染中的东西,即使它是零,它至少等待它 - 这种方式在模态中也适用
首先,关注的官方方式是roadmap for 1.1 . 同时,您可以编写指令来实现设置焦点 .
其次,在项目变得可见之后将焦点设置在当前需要一种解决方法 . 只需使用
$timeout
延迟对元素焦点()的调用 .因为对焦点,模糊和选择存在相同的controller-modifies-DOM问题,我建议使用
ng-target
指令:Angular线程在这里:http://goo.gl/ipsx4,更多细节在这里博客:http://goo.gl/4rdZa
以下指令将在
ng-target
属性指定的控制器内创建.focus()
函数 . (它也会创建.blur()
和.select()
. )演示:http://jsfiddle.net/bseib/WUcQX/