Addaw, ir a inicio Donar

Técnica Scripts de cliente WCAG 2.2 obsoleta

SCR21Añadir contenido a la página con las funciones del DOM (técnica obsoleta)

Nombre oficial en el W3C: Usar funciones del Document Object Model (DOM) para añadir contenido a una página

Técnica obsoleta: el W3C ya no la recomienda. |

En pocas palabras

Técnica obsoleta. Recomendaba crear el contenido nuevo con funciones del DOM, como createElement, en vez de document.write o innerHTML. Hoy los navegadores exponen igual el contenido añadido por cualquier vía. Lo importante es que el contenido nuevo tenga buena estructura y que la persona se entere de que ha aparecido.

Por qué es importante

El W3C la considera obsoleta y ya no la asocia a ningún criterio de las WCAG actuales. Cuando se escribió, algunos navegadores y lectores de pantalla no detectaban el contenido creado con innerHTML o document.write.

Ese problema ya no existe. Sin embargo, sigue siendo habitual que el contenido añadido con JavaScript pase desapercibido. Por ejemplo, un mensaje de error que aparece en otra parte de la página.

Cómo se hace

  1. Puede usar el método que prefiera para añadir contenido: createElement, innerHTML o un framework.
  2. Use HTML con significado: encabezados, listas, enlaces y botones reales.
  3. Añada el contenido nuevo en un lugar lógico del orden de lectura, normalmente cerca de lo que lo provoca.
  4. Si el cambio es importante, avise: lleve el foco al contenido nuevo o use una región viva (zona cuyos cambios lee el lector de pantalla).
  5. No ponga tabindex positivos en los elementos nuevos. Deje el orden de tabulación natural.
  6. Evite document.write, pero por motivos de rendimiento, no de accesibilidad.

Cómo comprobarlo

  1. Provoque la aparición de contenido nuevo, como un mensaje de error o un panel desplegable.
  2. Con un lector de pantalla, compruebe que el contenido se anuncia o que se llega a él de forma lógica.
  3. Inspeccione el código con F12 y verifique que usa elementos HTML con significado y sin tabindex positivos.
Ver el texto completo del W3C (traducción al español)

Esta es una traducción no oficial al español de la técnica SCR21 de Techniques for WCAG 2.2, del W3C. Puede contener errores. El único documento oficial y normativo es la versión original en inglés, publicada en el sitio web del W3C.

Aplicabilidad

ECMAScript utilizado dentro de HTML

Descripción

El objetivo de esta técnica es demostrar cómo usar funciones del Document Object Model (DOM) para añadir contenido a una página. Si se usan las funciones del DOM para añadir el contenido, los agentes de usuario pueden acceder al DOM para recuperarlo. La función createElement() puede usarse para crear elementos dentro del DOM. La función createTextNode() se usa para crear el texto asociado a los elementos. Las funciones appendChild(), removeChild(), insertBefore() y replaceChild() se usan para añadir y eliminar elementos y nodos. Otras funciones del DOM se usan para asignar atributos a los elementos creados.

Al añadir elementos que pueden recibir el foco en el documento, no añada atributos tabindex para fijar explícitamente el orden de tabulación, ya que esto puede causar problemas al insertar elementos que reciben el foco en mitad de un documento. Deje que al nuevo elemento se le asigne el orden de tabulación predeterminado, sin establecer explícitamente un atributo tabindex.

Ejemplos

Este ejemplo demuestra el uso de scripts en el lado del cliente para validar un formulario. Si se encuentran errores, se muestran los mensajes de error correspondientes. El ejemplo usa las funciones del DOM para añadir una notificación de error compuesta por un título, un párrafo breve que explica que se ha producido un error y una lista de errores en forma de lista ordenada. El contenido del título se escribe como un enlace, para poder usarlo con el método focus y llamar así la atención del usuario sobre el error. Cada elemento de la lista se escribe también como un enlace que, al seguirlo, sitúa el foco en el campo de formulario con error.

Por simplicidad, el ejemplo solo valida dos campos de texto, pero puede ampliarse fácilmente para convertirse en un manejador genérico de formularios. La validación en el lado del cliente no debe ser el único medio de validación, y debe respaldarse con una validación en el lado del servidor. La ventaja de la validación en el lado del cliente es que permite ofrecer al usuario una respuesta inmediata, evitándole esperar a que los errores vuelvan del servidor, y ayuda a reducir el tráfico innecesario hacia el servidor.

Este es el script que añade los manejadores de eventos al formulario. Si los scripts están activados, se llamará a la función validateNumbers() para realizar la validación en el lado del cliente antes de enviar el formulario al servidor. Si los scripts no están activados, el formulario se enviará inmediatamente al servidor, por lo que la validación también debe implementarse en el servidor.

window.onload = initialise;
function initialise() {
  // Add an event handler for the number form
  var objForm = document.getElementById('numberform');
  objForm.onsubmit= function(){return validateNumbers(this);};
}

Esta es la función de validación. Obsérvese el uso de las funciones del DOM createElement(), createTextNode() y appendChild() para crear los elementos del mensaje de error.

function validateNumbers(objForm) {
  // Test whether fields are valid
  var bFirst = isNumber(document.getElementById('num1').value);
  var bSecond = isNumber(document.getElementById('num2').value);
  // If not valid, display errors
  if (!bFirst || !bSecond) {
    var objExisting = document.getElementById('validationerrors');
    var objNew = document.createElement('div');
    var objTitle = document.createElement('h2');
    var objParagraph = document.createElement('p');
    var objList = document.createElement('ol');
    var objAnchor = document.createElement('a');
    var strID = 'firsterror';
    var strError;
    // The heading element will contain a link so that screen readers
    // can use it to place focus - the destination for the link is 
    // the first error contained in a list
    objAnchor.appendChild(document.createTextNode('Errors in Submission'));
    objAnchor.setAttribute('href', '#firsterror');
    objTitle.appendChild(objAnchor);
    objParagraph.appendChild(document.createTextNode('Please review the following'));
    objNew.setAttribute('id', 'validationerrors');
    objNew.appendChild(objTitle);
    objNew.appendChild(objParagraph);
    // Add each error found to the list of errors
    if (!bFirst) {
      strError = 'Please provide a numeric value for the first number';
      objList.appendChild(addError(strError, '#num1', objForm, strID));
      strID = '';
    }
    if (!bSecond) {
      strError = 'Please provide a numeric value for the second number';
      objList.appendChild(addError(strError, '#num2', objForm, strID));
      strID = '';
    }
    // Add the list to the error information
    objNew.appendChild(objList);
    // If there were existing errors, replace them with the new lot,
    // otherwise add the new errors to the start of the form
    if (objExisting) {
      objExisting.parentNode.replaceChild(objNew, objExisting);
    }
    else {
      var objPosition = objForm.firstChild;
      objForm.insertBefore(objNew, objPosition);
    }
    // Place focus on the anchor in the heading to alert
    // screen readers that the submission is in error
    objAnchor.focus();
    // Do not submit the form
    objForm.submitAllowed = false;
    return false;
  }
  return true;
}
// Function to validate a number
function isNumber(strValue) {
  return (!isNaN(strValue) && strValue.replace(/^\s+|\s+$/, '') !== '');
}

A continuación figuran las funciones auxiliares para crear el mensaje de error y para situar el foco en el campo de formulario asociado.

// Function to create a list item containing a link describing the error
// that points to the appropriate form field
function addError(strError, strFragment, objForm, strID) {
  var objAnchor = document.createElement('a');
  var objListItem = document.createElement('li');
  objAnchor.appendChild(document.createTextNode(strError));
  objAnchor.setAttribute('href', strFragment);
  objAnchor.onclick = function(event){return focusFormField(this, event, objForm);};
  objAnchor.onkeypress = function(event){return focusFormField(this, event, objForm);};
  // If strID has a value, this is the first error in the list
  if (strID.length > 0){
    objAnchor.setAttribute('id', strID);
  }
  objListItem.appendChild(objAnchor);
  return objListItem;
}
// Function to place focus to the form field in error
function focusFormField(objAnchor, objEvent, objForm) {
  // Allow keyboard navigation over links
  if (objEvent && objEvent.type == 'keypress') {
    if (objEvent.keyCode != 13 && objEvent.keyCode != 32){
      return true;
    }
  }
  // set focus to the form control
  var strFormField = objAnchor.href.match(/[^#]\w*$/);
  objForm[strFormField].focus();
  return false;
}

Este es el HTML del formulario de ejemplo.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>ECMAScript Form Validation</title>
  <script src="validate.js"></script>
</head>
<body>
  <h1>Form Validation</h1>
  <form id="numberform">
    <fieldset>
      <legend>Numeric Fields</legend>
      <div>
        <label for="num1">Enter first number</label>
        <input type="text" size="20" name="num1" id="num1">
      </div>
      <div>
        <label for="num2">Enter second number</label>
        <input type="text" size="20" name="num2" id="num2">
      </div>
    </fieldset>
    <div>
      <input type="submit" name="submit" value="Submit Form">
    </div>
  </form>
</body>
</html>

Este ejemplo se limita a los scripts en el lado del cliente y debe respaldarse con una validación en el lado del servidor. El ejemplo se limita a la creación de mensajes de error cuando los scripts en el lado del cliente están disponibles.

Aquí hay un enlace a un ejemplo práctico: Form Validation (validación de formulario)

Pruebas

Procedimiento

Para las páginas que crean contenido nuevo de forma dinámica:

  1. Examinar el código fuente y comprobar que el contenido nuevo no se crea mediante document.write(), innerHTML, outerHTML, innerText ni outerText.

Resultados esperados

  • La comprobación n.º 1 es verdadera.

Recursos

Cómo lo comprobamos en ADDAW

En cada auditoría de ADDAW revisamos esta técnica página a página y le entregamos los errores con capturas y la forma de corregirlos.

Solicitar una auditoría

Basado en la técnica SCR21 del W3C (WCAG 2.2). Explicación y ejemplos: ADDAW. Traducción no oficial del texto del W3C © W3C, licencia de documentos del W3C. ¿Ha visto un error? Escríbanos.