2010-09-08 8 views
22

Wenn eine Webseite geladen wird, lesen Bildschirmleseprogramme (wie der mit OS X oder JAWS unter Windows) den Inhalt der gesamten Seite. Aber sagen Sie, Ihre Seite ist dynamisch und wenn Benutzer eine Aktion ausführen, wird neuer Inhalt zur Seite hinzugefügt. Um der Einfachheit halber sagen Sie, dass Sie eine Nachricht irgendwo in einem <span> anzeigen. Wie kann der Bildschirmleser diese neue Nachricht lesen?Bildschirmleser zum Lesen von neuem mit JavaScript hinzugefügtem Inhalt

+0

Bildschirmleser lesen Formularfelder und Links, wenn sie den Fokus erhalten. Eine Möglichkeit besteht also darin, einen Anker um den Text zu legen und den Fokus auf diesen Anker zu legen. Mit CSS können Sie den Link nicht als Link für Benutzer anzeigen, die auf die Seite schauen. Aber diese Methode ist nicht sehr befriedigend, da Benutzer von Bildschirmleseprogrammen fälschlicherweise glauben, dass dies ein Link ist. – avernet

+2

Add tabindex zu jedem Element und es wird lesbar werden, glaube ich (tabindex = -1 macht es skriptfähig, aber nicht tabbable). Ich programmiere oft programmgesteuert den Fokus auf neue Inhalte, nachdem ein Link angeklickt wurde (wie ein Tab-Schalter oder Akkordeon) - aber es muss kein Link sein, um fokussierbar zu sein. Lesen Sie Tabindex. –

Antwort

25

Die Spezifikation WAI-ARIA definiert mehrere Möglichkeiten, wie Bildschirmleser ein DOM-Element "überwachen" können. Die am besten unterstützte Methode ist das aria-live Attribut. Es hat Modi off, polite, assertive und rude. Je höher das Durchsetzungsvermögen, desto wahrscheinlicher ist es, das zu unterbrechen, was der Bildschirmleser gerade spricht.

<!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> 

Das gleiche accomplished mit WAI-ARIA sein kann rolesrole="status" und role="alert":

Nachfolgend wurde mit NVDA unter Firefox 3 und Firefox 4.0b9 getestet. Ich hatte Berichte über Inkompatibilität, konnte sie aber nicht reproduzieren.

<div id="statusbar" role="status">...</div> 
+1

Nur um es klar zu sagen, die einzigen gültigen Werte für 'aria-live' sind" aus "," höflich "und" durchsetzungsfähig ". Wenn jemand neugierig auf die Standardeinstellungen für Rollen ist, die mit Live-Regionen verbunden sind, oder einfach nur sehen möchte, was sie tun, habe ich einen kleinen Spielplatz geschrieben, der Live-Regionen in Aktion zeigt: http://schnee324.github.io/live-region-playground/ – harris

+0

Das funktioniert nicht für mich in Mac mit Firefox 41.0.2 hast du keine Ahnung? Funktioniert gut mit Safari und Chrome –

+0

Nur um die gültigen Werte für Aria-Live hinzuzufügen, gibt es tatsächlich 4 Werte. ** off **, ** höflich **, ** durchsetzungsfähig ** und ** unhöflich ** wie in den Dokumenten hier beschrieben: https://msdn.microsoft.com/en-us/library/windows/apps /hh465711.aspx –

0

Hier ist eine angepasste realer Welt Beispiel - dieser up-Level-Markup wird bereits von einer ungeordneten Liste mit Links in ein Auswahlmenü über JS umgewandelt. Der echte Code ist sehr viel komplexer und kann offensichtlich nicht in seiner Gesamtheit enthalten sein, also denken Sie daran, dass dies für die Produktion neu gedacht werden muss. Damit das Select-Menü über die Tastatur erreichbar ist, haben wir die Tastenkombination & onchange-Ereignisse registriert und den AJAX-Aufruf ausgelöst, wenn Benutzer aus der Liste austraten (Vorsicht vor Browserunterschieden im Timing des onchange-Ereignisses). Dies war eine ernst zu nehmende PITA, aber es ist möglich.

// 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) 
    }); 
} 
Verwandte Themen