简体   繁体   English

如何使 Ionic Toast 与屏幕阅读器更兼容

[英]How to make Ionic Toast more compatible with Screen Reader

I am trying to make my app more screen reader compatible.我正在尝试使我的应用程序更兼容屏幕阅读器。 I use Google TalkBack.我使用 Google TalkBack。 My current obstacle occured while working with Toasts.我目前的障碍是在使用 Toasts 时发生的。 I created a button that creates and presents a simple toast.我创建了一个按钮来创建和呈现一个简单的吐司。 Since the screen reader completely ignores them, I added the following attributes to the DOM:由于屏幕阅读器完全忽略了它们,我在 DOM 中添加了以下属性:

  • role='alert'角色='警报'
  • aria-live='root' aria-live='根'
  • aria-label='message' aria-label='消息'

Against my expectation the screen reader describes the button twice and the toast afterwards, when i click the button.出乎我的意料,当我单击按钮时,屏幕阅读器会两次描述按钮,然后是吐司。 This only happens once.这只会发生一次。 If I click the button again, the order of read elements is as I wanted it to be from the beginning.如果我再次单击该按钮,则读取元素的顺序是我希望它从头开始的顺序。 My guess is that the focus jumps back to the button (once) and is therefor read twice.我的猜测是焦点跳回按钮(一次),因此被读取两次。

Does anyone know how I can fix this?有谁知道我该如何解决这个问题? What causes the focus to return to the button?是什么导致焦点返回到按钮?

After testing a couple of solutions I was satisfied with the following:在测试了几个解决方案后,我对以下内容感到满意:

 private async createIosToast(message: string, duration: number) {
    const toast = await this.toastController.create({
      message,
      duration,
      color: 'primary'
    });

    toast.setAttribute('role', 'alert');
    toast.setAttribute('id', 'toast');

    const toastElement = document.getElementById('toast') as HTMLElement;
    const activeElement = this.correctActiveElement.getCorrectActiveElement();

    // set focus on toast
    toast.addEventListener('ionToastWillPresent', async () => {
      this.focusService.focus(toastElement);
    });

    // reset focus
    toast.onDidDismiss().then(async () => {
      console.log(activeElement);
      this.focusService.focus(activeElement);
    }, error => {
      console.log(error);
    });

    return toast;
  }

The following method is important when developing for android and iOS simultaneous.在同时开发 android 和 iOS 时,以下方法很重要。 Since the focus-method sets a tabindex, this method avoids applying it to the wrong element.由于 focus-method 设置了 tabindex,因此该方法避免将其应用于错误的元素。 Otherwise, if the element has a shadow-root, it will be focusable twice (only on android).否则,如果元素有一个 shadow-root,它会被聚焦两次(仅在 android 上)。

  getCorrectActiveElement(): HTMLElement {
    if (this.platform.is('android') && document.activeElement.shadowRoot != null) {
      return document.activeElement.shadowRoot.childNodes[0] as HTMLElement;
    } else {
      return document.activeElement as HTMLElement;
    }
  }

This method simply sets the focus and applies a tabindex:此方法只是设置焦点并应用 tabindex:

  public focus(element: HTMLElement): void {
    setTimeout(() => {
      element.setAttribute('tabindex', '0');
      element.focus();
    }, 0);
  }

Conclusion: Using this code I minimized my problems.结论:使用这段代码,我最小化了我的问题。 On android will be a couple of unnecessary vibrations I was not able to remove.在 android 上会有一些我无法消除的不必要的振动。 They are caused by the focus jumping back into the webview.它们是由焦点跳回 webview 引起的。 On iOS the toast will be read once, is then interrupted and then read completely.在 iOS 上,toast 将被读取一次,然后被中断,然后完全读取。

Tested on Google Pixel and iPhone X.在 Google Pixel 和 iPhone X 上测试。

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

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