funciona - javascript pdf
Conseguir que el lector de pantalla lea el nuevo contenido agregado con JavaScript (2)
Cuando se carga una página web, los lectores de pantalla (como el que viene con OS X o JAWS en Windows) leerán el contenido de toda la página. Pero digamos que su página es dinámica, y como usuarios que realizan una acción, se agrega nuevo contenido a la página. En aras de la simplicidad, supongamos que muestra un mensaje en algún lugar en un <span>
. ¿Cómo puedes hacer que el lector de pantalla lea ese nuevo mensaje?
Este es un ejemplo del mundo real adaptado: este marcado de nivel superior ya se ha convertido de una lista desordenada con enlaces a un menú de selección a través de JS. El código real es mucho más complejo y, obviamente, no se puede incluir en su totalidad, así que recuerde que esto tendrá que replantearse para su uso en producción. Para que se pueda acceder al teclado desde el menú de selección, registramos los eventos de pulsación y cambio de tecla y activamos la llamada AJAX cuando los usuarios salieron de la lista (tenga cuidado con las diferencias del navegador en el momento del evento de cambio). Este fue un PITA serio para hacer accesible, pero ES posible.
// HTML
<!-- select element with content URL -->
<label for="select_element">State</label>
<select id="select_element">
<option value="#URL_TO_CONTENT_PAGE#" rel="alabama">Alabama</option>
</select>
<p id="loading_element">Content Loading</p>
<!-- AJAX content loads into this container -->
<div id="results_container"></div>
// JAVASCRIPT (abstracted from a Prototype class, DO NOT use as-is)
var selectMenu = $(''select_element'');
var loadingElement = $(''loading_element'');
var resultsContainer = $(''results_container'');
// listen for keypress event (omitted other listeners and support test logic)
this.selectMenu.addEventListener(''keypress'', this.__keyPressDetector, false);
/* event callbacks */
// Keypress listener
__keyPressDetector:function(e){
// if we are arrowing through the select, enable the loading element
if(e.keyCode === 40 || e.keyCode === 38){
if(e.target.id === ''select_element''){
this.loadingElement.setAttribute(''tabIndex'',''0'');
}
}
// if we tab off of the select, send focus to the loading element
// while it is fetching data
else if(e.keyCode === 9){
if(targ.id === ''select_element'' && targ.options[targ.selectedIndex].value !== ''''){
this.__changeStateDetector(e);
this.loadingElement.focus();
}
}
}
// content changer (also used for clicks)
__changeStateDetector:function(e){
// only execute if there is a state change
if(this.selectedState !== e.target.options[e.target.selectedIndex].rel){
// get state name and file path
var stateName = e.target.options[e.target.selectedIndex].rel;
var stateFile = e.target.options[e.target.selectedIndex].value;
// get the state file
this.getStateFile(stateFile);
this.selectedState = stateName;
}
}
getStateFile:function(stateFile){
new Ajax.Request(stateFile, {
method: ''get'',
onSuccess:function(transport){
// insert markup into container
var markup = transport.responseText;
// NOTE: select which part of the fetched page you want to insert,
// this code was written to grab the whole page and sort later
this.resultsContainer.update(markup);
var timeout = setTimeout(function(){
// focus on new content
this.resultsContainer.focus();
}.bind(this), 150);
}.bind(this)
});
}
La especificación WAI-ARIA define varias formas mediante las cuales los lectores de pantalla pueden "ver" un elemento DOM. El mejor método soportado es el atributo aria-live
. Tiene modos off
, polite
, assertive
y rude
. Cuanto más alto sea el nivel de asertividad, más probable es que interrumpa lo que el lector de pantalla habla actualmente.
Lo siguiente ha sido probado con NVDA en Firefox 3 y Firefox 4.0b9:
<!DOCTYPE html>
<html>
<head>
<script src="js/jquery-1.4.2.min.js"></script>
</head>
<body>
<button onclick="$(''#statusbar'').html(new Date().toString())">Update</button>
<div id="statusbar" aria-live="assertive"></div>
</body>
Lo mismo se puede accomplished con los roles WAI-ARIA role="status"
y role="alert"
. He recibido informes de incompatibilidad, pero no he podido reproducirlos.
<div id="statusbar" role="status">...</div>