Объявление информации для программы чтения с экрана в vue.js с использованием aria-live - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь заставить компонент vue динамически объявлять информацию для программы чтения с экрана, когда на моем сайте происходят различные события.

У меня она работает там, где при нажатии кнопки будет отображаться промежуток, равный aria-live="assertive" и role="alert" с текстом.Это работает прилично в первый раз, однако нажатие других кнопок с похожим поведением заставляет NVDA дважды прочитать предыдущий текст, прежде чем читать новый.Кажется, это происходит в vue, но не в аналогичной установке с использованием jquery, поэтому я предполагаю, что это как-то связано с тем, как vue рендерится в DOM.

Я надеюсь, что есть какой-то способчтобы обойти эту проблему или, возможно, лучший способ прочитать текст для пользователя, который не будет иметь этой проблемы.Любая помощь очень ценится.

Вот простой компонент Я установил в изолированной программной среде рабочего кода, чтобы показать мою проблему (перейдите к компонентам / HelloWorld.vue для кода)- Примечание: эта песочница изменилась в соответствии с ответом ниже .Полный код для компонента ниже:

export default {
  name: "HelloWorld",
  data() {
    return {
      ariaText: ""
    };
  },
  methods: {
    button1() {
      this.ariaText = "This is a bunch of cool text to read to screen readers.";
    },
    button2() {
      this.ariaText = "This is more cool text to read to screen readers.";
    },
    button3() {
      this.ariaText = "This text is not cool.";
    }
  }
};
<template>
  <div>
    <button @click="button1">1</button>
    <button @click="button2">2</button>
    <button @click="button3">3</button><br/>
    <span role="alert" aria-live="assertive">{{ariaText}}</span>
  </div>
</template>

1 Ответ

0 голосов
/ 12 июня 2018

Хорошо, так что я обнаружил, что работает более последовательно - вместо того, чтобы заменить текст в элементе новым текстом, чтобы добавить новый элемент в родительский контейнер с новым текстом для чтения.Вместо того, чтобы хранить текст как одну строку, я храню его в массиве строк, которые будут v-for на странице в контейнере aria-live.

Я создал полный компонент, который будет делать это различными способами в качестве примера для тех, кто хочет сделать то же самое:

export default {
    props: {
        value: String,
        ariaLive: {
            type: String,
            default: "assertive",
            validator: value => {
                return ['assertive', 'polite', 'off'].indexOf(value) !== -1;
            }
        }
    },
    data() {
        return {
            textToRead: []
        }
    },
    methods: {
        say(text) {
            if(text) {
                this.textToRead.push(text);
            }
        }
    },
    mounted() {
        this.say(this.value);
    },
    watch: {
        value(val) {
            this.say(val);
        }
    }
}
.assistive-text {
    position: absolute;
    margin: -1px;
    border: 0;
    padding: 0;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
}
<template>
    <div class="assistive-text" :aria-live="ariaLive" aria-relevant="additions">
        <slot></slot>
        <div v-for="(text, index) in textToRead" :key="index">{{text}}</div>
    </div>
</template>

Это можно использовать, установив переменную в родительском элементе для v-model компонента, и любые изменения этой переменной будут считанысчитывателю экрана один раз (как и в любое время, когда родительский контейнер становится ориентированным на вкладки).

Это также может быть вызвано this.$refs.component.say(textToSay); - обратите внимание, что это также будет запущено снова, если родительский контейнер становится ориентированным на табуляции.Этого поведения можно избежать, поместив элемент в контейнер, который не получит фокус.

Он также включает в себя слот, поэтому текст можно добавить следующим образом: <assistive-text>Text to speak</assistive-text> однако это не должно быть динамическим / усамипеременной или вы столкнетесь с проблемой в исходном вопросе при изменении текста.

Я также обновил песочницу, размещенную в вопросе , с рабочим примером этого компонента.

...