簡體   English   中英

Ionic/Angular:無法使用屏幕閱讀器關注 HTMLElement

[英]Ionic/Angular: Can't Focus on HTMLElement with Screen Reader

我試圖強制 Ionic 5 中的屏幕閱讀器專注於並宣布一個元素。

我的模板元素:

    <ion-title tabindex="-1" #title id="title" role="heading" aria-level="1" class="title">My Title</ion-title>

我試圖通過文檔和 Viewchild 訪問該元素:

    @ViewChild('title', { read: ElementRef }) title: ElementRef;
    const title: any = document.getElementById('title');

我嘗試在此測試延遲后集中注意力:


    ionViewWillEnter(): void {
        setTimeout(() => {
          const title: any = document.getElementById('title');
          if (title) {
            title.focus();
          }
        }, 3000);
    
        setTimeout(() => {
          this.title.nativeElement.focus();
        }, 5000);
      }

然而,這些都不是重點。 屏幕閱讀器不會在 Android 和 iOS 中讀出標題。

更新

澄清一下,我需要屏幕閱讀器 position 移動到指定元素。 如前所述,將焦點放在某個元素上不會移動屏幕閱讀器 position。

任何幫助將不勝感激,這是我的 Ionic 信息:

 Ionic CLI                     : 5.4.16
   Ionic Framework               : @ionic/angular 5.5.3
   @angular-devkit/build-angular : 0.901.15
   @angular-devkit/schematics    : 9.1.15
   @angular/cli                  : 9.1.15
   @ionic/angular-toolkit        : 2.3.3

Capacitor:

   Capacitor CLI   : 2.4.2
   @capacitor/core : 2.4.0

我為所有要擴展的 Ionic 頁面創建了一個 BasePage。 它捕獲點擊和焦點事件的活動元素,並在頁面再次進入時聚焦於該元素。

如果沒有以前的活動元素要關注,它還會自動嘗試查找 ion-title 並關注它。

這應該涵蓋基本需求。 您可以調整將超時添加到焦點方法

import { Component, ElementRef, HostListener } from '@angular/core';
import { ViewDidEnter } from '@ionic/angular';
import { isNullOrUndefined } from 'util';

@Component({
  template: ''
})
export class BasePage implements ViewDidEnter {
  private _previouslyActiveElement: HTMLElement;

  constructor(protected elementRef: ElementRef) {}

  ionViewDidEnter() {
    if (!isNullOrUndefined(this._previouslyActiveElement)) {
      this.focusOnElement(this._previouslyActiveElement);
    } else {
      if (
        !isNullOrUndefined(this.elementRef.nativeElement) &&
        this.elementRef.nativeElement.querySelectorAll('[autofocus]').length === 0) {
        const initialFocusElement: HTMLElement = <HTMLElement>this.elementRef.nativeElement.getElementsByTagName('ion-title')[0];

        if (!isNullOrUndefined(initialFocusElement)) {
          this.focusOnElement(initialFocusElement);
        }
      }
    }
  }

  @HostListener('focusin', ['$event.target'])
  @HostListener('click', ['$event.target'])
  capturePreviouslyActiveElement(element: HTMLElement) {
    this._previouslyActiveElement = element;
  }

  focusOnElement(element: HTMLElement): void {
    if (isNullOrUndefined(element)) {
      return;
    }

    try {
      // Make sure it's focusable
      if (isNullOrUndefined(element.getAttribute('tabindex'))) {
        element.setAttribute('tabindex', '-1');
      }

      element.focus();
    } catch (err) {
      console.log('error handling aria focus ' + err);
    }
  }
}

我創建了stackblitz 這一切都按預期工作。 為了使它更明顯,我添加了樣式

:focus {
  outline: 3px solid orange;
}

另外,我建議您添加aria-label ,因為ion-title是內部帶有 div 的元素,我不確定是否所有讀者都在處理它

  <ion-title tabindex="-1" #title id="title" role="heading" aria-level="1" class="title" role="heading"
      aria-label="What you want to read">My Title
    </ion-title>

最后,由於您將 angular 與您的 ionic 應用程序一起使用,您可以查看具有實時播音員的材料庫

@Component({...})
export class MyComponent {

 constructor(liveAnnouncer: LiveAnnouncer) {
   liveAnnouncer.announce("Hey Google");
 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM