Addaw, ir a inicio Donar

Técnica Scripts de cliente WCAG 2.2 obsoleta

SCR21Usar funciones del Document Object Model (DOM) para añadir contenido a una página

Técnica obsoleta: el W3C ya no la recomienda. Se mantiene traducida como referencia histórica y porque sigue apareciendo en auditorías antiguas. |

En resumen

Esta técnica (hoy obsoleta) explica cómo añadir contenido dinámico a una página con las funciones del DOM (createElement, createTextNode, appendChild...) en lugar de document.write o innerHTML, de forma que los agentes de usuario y las tecnologías de asistencia puedan acceder al nuevo contenido. Se ilustra con una validación de formulario que genera una lista de errores enlazados a los campos afectados.

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 las auditorías de accesibilidad de ADDAW revisamos cada criterio de conformidad siguiendo este catálogo de técnicas: comprobamos si la web aplica una técnica suficiente y documentamos cada fallo común con capturas y el código afectado, para que el equipo de desarrollo sepa exactamente qué corregir. Los informes siguen la metodología del Observatorio de Accesibilidad y la norma UNE-EN 301 549.

Solicitar una auditoría

Fuente y licencia

Traducción al español, no oficial, realizada por ADDAW a partir de la técnica SCR21 del documento «Techniques for WCAG 2.2» del W3C (versión del repositorio público del W3C a 22/10/2026). Copyright © W3C® (MIT, ERCIM, Keio, Beihang). Se publica conforme a la licencia de documentos del W3C. El texto normativo de referencia es el original en inglés; si detecta un error en la traducción, escríbanos.

Financiado por la unión europea Gobierno de españa red.es Plan de recuperación transformación y resilencia kit digital