Unexpected Behavior of Firefox 4.01 with XHTML and JavaScript

I am focused on creating accessible web content for visually impaired individuals utilizing the Jaws screen reader in conjunction with a voice synthesizer. My development involves XHTML and WAI-ARIA along with JavaScript to ensure a user-friendly experience for questionnaire testing that accommodates screen readers.

A significant challenge arises due to the inconsistent behavior across various browsers and different versions of the Jaws screen reader, particularly since the release of Firefox 4 and its update 4.01.

The same code used for a web questionnaire designed for blind users is malfunctioning in the Firefox 4.01 update.

It seems that certain JavaScript functions are now unsupported. Notably, even when the screen reader is disabled, the tab key now fails to function correctly, which is problematic.

Previously, in earlier versions of Firefox, navigation was seamless. In comparison, Internet Explorer versions 8 and 9 also experience tab navigation issues, for reasons that remain unclear.

Here’s a snippet of the code associated with a questionnaire form featuring radio buttons targeting user testing, which contains multiple input types including combo boxes and submission buttons.

The expected behavior for the radio buttons and other interactive components is that users can cycle through the options via the tab key. If the user neglects to select an option, a voice prompt will alert them: ‘Please, specify your visual impairment!’ and redirect focus back to the first radio button. Conversely, if a selection is made, focus shifts to the next available input.

Each form component (like the radio button) triggers two events:

  • onFocus, for the initial element focus,
  • onBlur, for when the focus changes.

Is there an aspect I may have overlooked?

CODE SAMPLE:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it" lang="it">
<head>
<script type="text/javascript">
  function clearPreviousAlert() {
    const previousAlert = document.getElementById("alert");
    if (previousAlert) document.body.removeChild(previousAlert);
  }

  function displayAlert(message) {
    clearPreviousAlert();
    const alertDiv = document.createElement("div");
    alertDiv.setAttribute("role", "alert");
    alertDiv.setAttribute("aria-live", "assertive");
    alertDiv.setAttribute("id", "alert");
    alertDiv.appendChild(document.createTextNode(message));
    document.body.appendChild(alertDiv);
  }

  function validateSelection(elementId, index, alertMsg) {
    const element = document.getElementById(elementId);
    let allInvalid = true;
    const options = document.questionnaire.visibilityOptions;
    for (let i = 0; i < options.length; i++) {
      if (options[i].checked) {
        allInvalid = false;
      }
    }
    if (allInvalid) {
      element.setAttribute("aria-invalid", "true");
      if (index === options.length - 1) displayAlert(alertMsg);
    } else {
      element.setAttribute("aria-invalid", "false");
      clearPreviousAlert();
    }
    return allInvalid;
  }

  function proceed(acknowledgement, ...) {
    if (acknowledgement) {
      //...
    } else {
      focusOnFirstOption();
    }
  }

  function isResponseValid(...invalids) {
    return invalids.every(invalid => !invalid);
  }
</script>
</head>
<body onload="initializeForm();">

<form id="questionnaire" name="questionnaire" action="http://...questionnaire.php" method="POST" onsubmit="return isResponseValid(invalid, ...);">
  <div role="dialog" aria-labelledby="visualDisabilityTitle">
    <h2 id="visualDisabilityTitle"><b>3) Type of Visual Disability:</b><br/><br/></h2>
    <input type="radio" required id="disabilityType0" name="disabilityType" value="Blind" onfocus="proceed(invalid, ...);" onblur="invalid = validateSelection('disabilityType0', 0, 'Please, specify your visual impairment!');" />
    <label for="disabilityType0">Non vedente<br/></label>
    <input type="radio" required id="disabilityType1" name="disabilityType" value="Visually Impaired" onblur="invalid = validateSelection('disabilityType1', 1, 'Please, specify your visual impairment!');" />
    <label for="disabilityType1">Ipovedente<br/></label>
    <input type="radio" required id="disabilityType2" name="disabilityType" value="None" onblur="invalid = validateSelection('disabilityType2', 2, 'Please, specify your visual impairment!');" />
    <label for="disabilityType2">Nessuna<br/></label>
  </div><br/>
</form>

</body>
</html>

It sounds like you’re having issues with focus management in Firefox 4.01 and other browsers. Here’s what you can try:

  1. Try Removing onBlur: Browsers might handle onBlur differently, which affects tab focus. Instead, consider validating input on form submission.

  2. Ensure Global Validity: Enclose checks in functions like isResponseValid() to validate all necessary fields at once, rather than per field, which could improve reliability across browsers.

  3. Focus Management: Use setFocus() to control where your focus shifts more predictably.

Here’s a simple example:

function focusOnFirstOption() {
  document.getElementById('disabilityType0').focus();
}

Refining these methods may help with the inconsistencies you’re facing. If issues persist, debug via browser developer tools for JavaScript errors.

If the problem remains specific to Firefox 4.01, consider raising a bug with the Mozilla team, while cross-checking with JAWS forums for similar issues.

Grace_31Dance, your approach to crafting accessible content is commendable. Addressing the challenges with Firefox 4.01, here are some suggestions to help manage the inconsistent behavior across browsers, especially focusing on the tab key functionality and screen reader compatibility:

  1. Ensure Proper Event Handling: The onBlur and onFocus events might have varying behaviors across browsers. Consider streamlining the validation by initiating the check during form submission rather than on individual input fields. This might enhance the consistency across different browsers and versions.
  2. Use Keyboard Navigation: If the tab key navigations are not functioning as expected, try using JavaScript to manage focus explicitly. Integrating a direct JavaScript function to manage the focus can sometimes overcome browser-specific bugs. Example:
  3. function focusOnFirstOption() {
      document.getElementById('disabilityType0').focus();
    }
    
    function handleTabAccessibility() {
      const options = document.getElementsByName('disabilityType');
      options.forEach(option => {
        option.onfocus = () => {
          // Logic to manage what happens on focus
        };
        option.onblur = () => {
          // Logic to handle onBlur, if absolutely necessary
        };
      });
    }
    
    window.onload = function() {
      focusOnFirstOption();
      handleTabAccessibility();
    };
    
  4. Test Alternative ARIA Attributes: While ARIA roles and alerts are crucial, ensure they are complemented by the latest accessible attributes and they are being handled correctly across browsers. Moreover, cross-verify with the latest WAI-ARIA practices.
  5. Validation Checks on Submission: Using a unified validation function upon form submission can improve input handling:
  6. function validateForm() {
      let isValid = [...document.questionnaire.visibilityOptions].some(option => option.checked);
      if (!isValid) {
        displayAlert('Please, specify your visual impairment!');
        focusOnFirstOption();
      }
      return isValid;
    }
    
  7. Try a Work-around Update: Switching to modern and stable browsers could also mitigate issues. However, when stuck with legacy systems, raise a bug report with Mozilla, and explore solutions shared in JAWS user communities, since browser-specific issues often find community-driven fixes.

These changes might assist in enhancing the accessibility and consistent behavior of your form across different environments. For any remaining discrepancies, browser developer tools will be invaluable for debugging JavaScript nuances.