Most time you need to set the value once and don't care about it. E.g. markup for error messages can contain aria-live="polite".
<div class="messages" aria-live="polite"> ... some messages ... </div>Every time when the content of the div container with class="messages" is updated, it will be spoken by screen readers. That's good, but sometimes you only would like to notify a sightless user when the new (after update) and old (before update) contents are not equal. Imagine a railway ticket shop where users can choose fare class, number of traveler, book places, etc. The total buy price is permanently updated. We can write
<span aria-live="polite"> <div id="pricetotal"> <span class="hiddenOfScreen">Total price </span> #{price} </div> </span>and update the div by AJAX. #{price} is a current price as EL expression calculated on the server-side (coming from the JSF world, but JavaScript templating has similar expressions). Whenever the div gets updated, screen readers speak the total price regardless if the amount was changed or not. A more clever approach sets aria-live dynamically at runtime. If the amount was changed, the aria-live on the div should have the value polite. If the old and new prices are equal, the div should have the value off. The off value prevents speaking by screen readers.
The idea is to save the last updated price in the data-price attribute of the parent element and compare the old and new prices on every AJAX update. In the code snippet below, the div with id="pricetotal" gets updated. The JavaScript block inside is being executed on every update. We read and compare old and new prices and manipulate the aria-live attribute at runtime. Whenever the aria-live is set to polite, screen readers speak "Total price" and the amount.
<span data-price="#{price}"> <div id="pricetotal"> <span class="hiddenOfScreen">Total price </span> <span class="priceoutput">#{price}</span> <script type="text/javascript"> $(document).ready(function () { $pricetotal = $('#pricetotal'); var oldPrice = $pricetotal.parent().data('price'); var newPrice = $pricetotal.find('.priceoutput').text(); if (oldPrice != newPrice) { $pricetotal.attr('aria-live', 'polite'); $pricetotal.parent().data('price', newPrice); } else { $pricetotal.attr('aria-live', 'off'); } }); </script> </div> </span>If prices are not equal, the new price is saved in the data-price to make it available in the next update.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.