简体   繁体   English

用角度捕获HTML容器中的焦点

[英]Trap focus in html container with angular

I'm building an accessible website and trying to manage focus. 我正在建立一个可访问的网站并尝试管理焦点。 I need to open a modal and then put focus on the first element in the modal then trap the focus until the modal is closed ("canceled" or "accepted"). 我需要打开一个模态,然后将焦点放在模态中的第一个元素上,然后捕获焦点直到模态关闭(“取消”或“接受”)。

HTML 的HTML

<a href="" ng-click="modalshow = !modalshow; modal.open();">Open Modal</a>
  <div ng-show="modalshow" id="modal">
    <h3 id="tofs" >Terms of Service</h3>
    <p>Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum </p>
    <span>Cancel</span> 
    <span>Accept/span> 
  </div>
  <h2>Seprate Content</h2>

Javascript Java脚本

angular.module('app')
    .controller('Controller', modalCtrl);

  function modalCtrl() {
     $scope.modal = {
       open: function() {
         angular.element('#tofs').focus();

       }
     }
  }
angular.element("html").on("focusin", "body", function (event) {
   if(angular.element("#modal:visible").length>0){
       event.preventDefault();
       event.stopPropagation();
       angular.element('#tofs').focus();
   }
});

you can add this code to trap all focus events to h3 tag when modal is visible. 您可以添加此代码以在可见模式时将所有焦点事件捕获到h3标签。

There's a directive called ngBlur, that fires an event when an element loses focus. 有一个名为ngBlur的指令,当元素失去焦点时会触发事件。 Try executing your focus function on ng-blur 尝试对ng-blur执行聚焦功能

Here: https://docs.angularjs.org/api/ng/directive/ngBlur 此处: https//docs.angularjs.org/api/ng/directive/ngBlur

An example: http://jsbin.com/hemaye/1/edit?html,js,output 示例: http : //jsbin.com/hemaye/1/edit?html,js,output

You cannot ever select the 2nd input box because of the ng-blur statement 由于ng-blur语句,您永远无法选择第二个输入框

There is multiple possibility to trap the focus. 捕获焦点有多种可能性。

One solution is to manually set tabindex="-1" temporarily on all the elements in the background of your modal when it is showed (and remove this tabindex, or revert to original tabindex when leaving modal). 一种解决方案是在模式显示时在其背景中的所有元素上临时手动设置tabindex="-1" (并删除此tabindex,或在离开模式时恢复为原始tabindex)。

Another solution is to look at how angular-bootstrap plan to fix this issue : https://github.com/angular-ui/bootstrap/issues/738 另一个解决方案是查看angular-bootstrap如何计划解决此问题: https : //github.com/angular-ui/bootstrap/issues/738

You can also look at the WAI ARIA page, they have a related content about it : http://www.w3.org/TR/wai-aria-practices/#trap_focus_div 您也可以查看WAI ARIA页面,它们具有相关的内容: http : //www.w3.org/TR/wai-aria-practices/#trap_focus_div

Okay after way too much searching, this is what I came up with. 好吧,经过太多的搜索,这就是我想出的。 Basically I created ng-focus functions on the last element in the modal and the next element following the modal. 基本上,我在模态的最后一个元素和模态之后的下一个元素上创建了ng-focus函数。 This way I could check if the focus existed within the modal and if not, I would loop the focus back to the top. 这样,我可以检查焦点是否存在于模态中,如果不存在,则可以将焦点循环回到顶部。

      <a href="" ng-click="modalshow = !modalshow; modal.open();">Open Modal</a>
      <div ng-show="modalshow" id="modal">
        <h3 id="tofs" >Terms of Service</h3>
        <p>Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum </p>
        <a href="" ng-focus="modalshow.onFocus($event)">Cancel</a> 
        <a href="" ng-focus="modalshow.onFocus($event)">Accept</a> 
      </div>
      <h2>Seprate Content</h2>
      <a href="" ng-focus="modalshow.onFocus($event)">next link<a>

Javascript Java脚本

angular.module('app')
    .controller('Controller', modalCtrl);

  function modalCtrl() {
     $scope.modal = {
       open: function() {
         angular.element('#tofs').focus();

       },
       onFocus: function(){
         var modal = angular.element('#modal')[0];

         if (!modal.contains( event.target ) && $scope.modalIsOpen) {
           event.stopPropagation();
           angular.element('#tofs').focus();
         }
       }
     }
  }

Don't use any solution requiring you to look up "tabbable" elements. 不要使用任何要求您查找“可粘贴”元素的解决方案。 Instead, use keydown and either click events or a backdrop in an effective manor. 而是使用keydown并在有效的庄园中click事件或背景

What you need to do is have a general window.keydown event with preventDefault() to stop all tabbing when the modal is displayed and a keydown.tab event with stopPropagation() to handle tabbing for the modal. 您需要做的是使用一个通用的window.keydown事件和一个preventDefault()来停止显示模式时的keydown.tab ,并使用一个keydown.tab事件和stopPropagation()来处理模式的制表keydown.tab

You can use click events in a similar manor or you can just use a backdrop to prevent clicking elements behind it. 您可以在类似的庄园中使用click事件,也可以仅使用背景来防止单击其背后的元素。

For Angular1, I'd imagine this would look similar to Asheesh Kumar's answer. 对于Angular1,我想这看起来与Asheesh Kumar的答案类似。 You can see my Angular2-x solution here: https://stackoverflow.com/a/46738489/1754995 您可以在这里查看我的Angular2-x解决方案: https ://stackoverflow.com/a/46738489/1754995

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM