繁体   English   中英

如何在 Angular 2 中打开模态元素后立即将焦点集中在模态元素上?

[英]How to set focus on the elements of the modal as soon as they are opened in Angular 2?

我是 Angular JS 的新手,并且有了新版本的 Angular 2,我在实现指令时遇到了麻烦,该指令可以处理单击按钮时打开的模态上的强制焦点。

过去曾问过几个类似的问题,答案在 Angular 1 中如下:

app.directive('focusMe',
    ['$timeout',
        function ($timeout) {
            return {
                link: {
                    pre: function preLink(scope, element, attr) {
                      // ...
                    },
                    post: function postLink(scope, element, attr) {
                        $timeout(function () {
                            element[0].focus();
                        }, 0);

                    }
                }
            }
        }]);
});

我正在尝试在 Angular 2 中转换同一段代码。但我不确定如何实现它。 任何人都可以通过向我提供有关如何实现这一目标的更多信息来指出我正确的方向。

编辑:

我尝试按如下方式实现该指令,当我调试代码时,我什至看到正在调用该指令,但我仍然无法将焦点放在模态对话框上的元素上:

import { Directive, ElementRef } from "@angular/core";

@Directive({
    selector: "[ModFocus]"
})

export class ModalFocus {

    constructor(private _el: ElementRef) {

        this._el.nativeElement.focus();
    }

}

我在这里做错了吗? 或者除了在 nativeElement 上调用 focus() 之外,我还必须做其他事情吗?

HTML 模态:

<div class="modal-dialog modal-sm" tabindex="-1">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Are you sure?</h4>
            </div>
            <div class="modal-body">
                Warning
            </div>
        <div class="modal-footer ok-cancel" ModFocus>
                <button type="button" class="btn btn-default" (click)="cancel()">Cancel</button>
                <button type="button" class="btn btn-primary" (click)="delete()" data-dismiss="modal">Delete</button>
            </div>
        </div>
    </div>

谢谢你。

使用Angular 2创建组件时,与AngularJS相比,使用不同的语法。 您的示例代码可能如下所示:

import { Component, ElementRef, ViewChild } from "@angular/core";

@Component({
    selector: "whatever",
    template: `<input #myControl type='input'/>`
})
export class MyComponent {
    @ViewChild("myControl") myCtrl: ElementRef;

    constructor () {
        // This is wrong. It should be done in ngOnInit not in the
        // constructor as the element might not yet be available.
        //this.myCtrl.nativeElement.focus();   
    }
}

我在没有检查的情况下从头脑中写出这个,但是这应该让你对你应该去的方向有个很好的了解。

更新:

当你更新问题时,我认为这是错误的。 在新代码中,您将在构造函数中设置焦点。 可能是您的视图仍然没有生成,因此您想要设置焦点的元素仍然不可用( 在我之前的示例中,当我想要OnInit时,我在构造函数中实例化它时误导了您。为此道歉。 我会做以下事情:

import { Directive, ElementRef, OnInit } from "@angular/core";

@Directive({
    selector: "[ModFocus]"
})

export class ModalFocus implements OnInit {

    constructor(private _el: ElementRef) {

    }

    ngOnInit(): any {
        // At this point, your element should be available.
        this._el.nativeElement.focus();
    }
}

OnInit是Angular 2发出的生命周期钩子之一。 我建议你通过它们来获得更好的理解。

更新2:

问题是Directives没有模板。 对添加它们的元素的行为。 创建指令时,其构造函数如下所示:

构造函数(private el:ElementRef,private renderer:Renderer){}

el应该可以访问this.el.nativeElement.focus()

看看关于Attribute Directives的 angular.io上的这篇文章

我在问题中执行指令实际上是正确的。 焦点没有进入模态的问题是因为tabindex = -1放置错误。

以下是我创建的指令。 我没有直接使用ElementRef 相反,我使用Renderer作为明确提到的Angular文档来避免标记有安全风险的类

import { Directive, ElementRef, Renderer} from "@angular/core";
@Directive({
    selector: "[ModFocus]"
})

export class modalFocus {
    constructor(private _el: ElementRef, private renderer: Renderer) {
        this.renderer.invokeElementMethod(this._el.nativeElement, 'focus');
    }

}

HTML:

<div class="modal fade" tabindex="-1"> 
<div class="modal-dialog modal-sm">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Are you sure?</h4>
            </div>
            <div class="modal-body">
                Warning
            </div>
        <div class="modal-footer ok-cancel">
                <button type="button" class="btn btn-default" (click)="cancel()" ModFocus>Cancel</button>
                <button type="button" class="btn btn-primary" (click)="delete()" data-dismiss="modal">Delete</button>
            </div>
        </div>
    </div>
</div>

在上面的html中,我实际上错过了使用类模态淡入淡出的主标签上的tabindex。 添加tabindex会在打开时将焦点集中在模态上的按钮上。

Husein提供了宝贵的意见,这些意见非常有用。 因此,我接受他的回答。 再次感谢Husein。

trapFocus(){
    // add all the elements inside modal which you want to make focusable
const  focusableElements = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
const modal:any = document.querySelector('#deactivate-modal'); // select the modal by it's id

const firstFocusableElement = modal.querySelectorAll(focusableElements)[0]; // get first element to be focused inside modal
const focusableContent = modal.querySelectorAll(focusableElements);
const lastFocusableElement = focusableContent[focusableContent.length - 1]; // get last element to be focused inside modal


document.addEventListener('keydown', function(e) {
let isTabPressed = e.key === 'Tab' || e.keyCode === 9;

if (!isTabPressed) {
return;
}

if (e.shiftKey) { // if shift key pressed for shift + tab combination
if (document.activeElement === firstFocusableElement) {
  lastFocusableElement.focus(); // add focus for the last focusable element
  e.preventDefault();
}
} else { // if tab key is pressed
if (document.activeElement === lastFocusableElement) { // if focused has reached to last focusable element then focus first focusable element after pressing tab
  firstFocusableElement.focus(); // add focus for the first focusable element
  e.preventDefault();
}
}
});

firstFocusableElement.focus();

  }

暂无
暂无

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

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