簡體   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