El objeto DOCUMENT (IV)

Manipulando el contenido de la página

Con la cobertura anterior sobre como interactuan scripts y eventos hemos completado lo básico para crea páginas atractivas e dinámicas con DHTML. Ahora veremos algunas técnicas avanzadas como manipulación de texto y otros contenidos en la página y tareas con tablas, formularios y bases de datos.

Manipulación de contenido: Propiedades y métodos

La forma más fácil de manipular el contenido de la página es usando las propiedades especiales que soportan la mayoría de los elementos que la componen.

Propiedades de los elementos

Hay cuatro propiedades que son soportadas por la mayoría de los elementos de la página:

Propiedad Descripción
innerText El contenido de texto de un elemento, incluyendo el texto de cualquier etiqueta contenida, pero excluyendo cualquier etiqueta HTML. Asignando un nuevo texto solo se reemplaza el contenido de la etiqueta referida. Si el nuevo texto asignado contiene etiquetas HTML, estas son presentadas como texto, no interpretadas.
outerText Funciona de forma similar a innerText pero cualquier texto asignado reemplazara el elemento completamente.
innerHTML Retorna el texto completo y también el código HTML del elemento. Asignando un nuevo texto se reemplazará completamente el anterior y cualquier referencia HTML contenida en el nuevo texto será interpretada y mostrada adecuadamente.
outerHTML Contiene el contenido completo del elemento incluyendo las etiquetas de comienzo y fin del elemento. Asignando un nuevo texto, se reemplaza enteramente el elemento y cualquier referencia HTML contenida en el nuevo texto será interpretada y mostrada adecuadamente.

Propiedad innerText

Por ejemplo, si tuviéramos en la página esta línea de código

<h3id="Tit1">Encabezado de la página</h3>

Usando la propiedad innerText podemos cambiar esto por Encabezado nuevo de la página

objTit1 = document.all["Tit1"];
objTit1.innerText = "Encabezado nuevo de la página";

Esto preserva las etiquetas originales <H3> y solamente reemplaza el contenido. Si embargo si tuviéramos en el interior de <H3> otra etiqueta esta se perdería

<h3 id= "Tit1">Encabezado de<i>la</i> página</h3>
objTit1 = document.all["Tit1"];
objTit1.innerText = "Encabezado nuevo de la página";

Resultaría en la siguiente etiqueta

<h3 id="Tit1"> Encabezado nuevo de la página</h3>

En cambio si a la etiqueta:

<h3id="Tit1">Encabezado de la página</h3>

le aplicáramos el siguiente código

objTit1 = document.all["Tit1"];
objTit1.innerText =  "Encabezado<b>nuevo</b> de la página";

resultaría la siguiente línea resuelta en la pantalla del usuario

Encabezado<b>nuevo</b> de la página

y no la interpretación de la etiqueta <B> (negritas).

Propiedad innerHTML

En la última parte del ejemplo anterior obtendríamos el resultado buscado utilizando innerHTML.
Si tenemos la etiqueta

<h3id="Tit1">Encabezado de la página</h3>
y le aplicáramos el siguiente código
objTit1 = document.all["Tit1"];
objTit1.innerHTML =  "Encabezado<i>nuevo</i> de la página";

resultaría la siguiente línea resuelta en la pantalla del usuario

Encabezado nuevo de la página

No todos los elementos visibles soportan las cuatro propiedades 'contenido'. Algunos solo soportan la propiedad texto, y otros solo soportan una de las propiedades. Por ejemplo, la etiqueta <TD> solo tiene la propiedad innerText.

Los métodos insertAdjacent

Son dos métodos que también son soportados por la mayoría de los elementos visibles.

Método Descripción
insertAdjacentText Inserta texto en las adyacencias del elemento referido. Cualquier etiqueta HTML es ignorada. El texto puede ser insertado al principio o al final del elemento referido dentro de él, o inmediatamente antes o después del elemento, fuera de sus etiquetas de inicio o cierre.
insertAdjacentHTML Inserta texto u código HTML en las adyacencias del elemento referido. Cualquier referencia HTML es correctamente interpretada y mostrada después de que se insertó. El texto y el código HTML puede ser insertado al principio o al final del elemento referido dentro de él, o inmediatamente antes o después del elemento, fuera de sus etiquetas de inicio o cierre.

La sintaxis de estos métodos es:

   insertAdjacentText( donde, texto_a_insertar )
   insertAdjacentHTML( donde, texto_y_HTML_a_insertar )

El argumento donde controla donde se ubicará el nuevo contenido. Debe ser uno de los siguientes textos

"BeforeBegin" Inmediatamente antes de la etiqueta de apertura del elemento.
"AfterBegin" Inmediatamente después de la etiqueta de apertura del elemento.
"BeforeEnd" Inmediatamente antes de la etiqueta de cierre del elemento.
"AfterEnd" Inmediatamente después de la etiqueta de cierre del elemento.

Si tenemos la línea

<h3 id="Tit1">Encabezado de la página</h3>

y ejecutamos el código script

objTit1 = document.all["Tit1"];
objTit1.insertAdjacentHTML("BeforeBegin", "<font face= . Arial.>Texto</font>");

obtendremos la siguiente linea de código HTML

<font face= . Arial.>Texto</font>
<h3 id="Tit1">Encabezado de la página</h3>

Introducción al objeto TextRange

Al igual que las hojas de estilo globales (CSS) manipulan el estilo de los documento independientemente de su estructura, el objeto TextRange manipula el contenido de los documentos independientemente tanto de su estilo como de su estructura. Este objeto se concibió para complementar las propiedades inner u outer para elementos. Estas propiedades ofrecen resultados más sólidos y deben utilizarse en lugar del objeto TextRange siempre que sea posible.

El objeto TextRange proporciona el acceso al texto como un gran búfer de caracteres. Por ejemplo, considérese el texto de este documento sencillo:

<html>
<body>
   <h1>Bienvenidos</h1>
  <h2>Contenido</h2>
  <ul>
   <li>Capítulo 1</li>
   <li>Capítulo 2</li>
  </ul>
</body>
</html>

En la figura que sigue se muestra el texto de este documento, ubicado en la jerarquía del objeto del navegador:

El objeto TextRange puede ser creado por el método createTextRange, y solo pueden crearlo los elementos especiales que se consideren propietarios de la edición de texto. Actualmente solo dos tipos de elementos HTML pueden actuar como propietarios de la edición de texto en Dynamic HTML: el elemento BODY es el propietario de la edición de texto para todo el contenido representado; y los elementos INPUT, como input, button y textarea son propietarios de la edición de texto para su propio contenido. Por ejemplo, se puede crear un objeto TextRange para el documento anterior llamando al método createTextRange del objeto body:

var tr = document.body.createTextRange()

El objeto TextRange está diseñado para ser lo bastante sólido como para aceptar automáticamente elementos arbitrarios de HTML incrustados en el documento. Cuando se inserta texto nuevo en el objeto TextRange también se inserta en el documento elementos de HTML, igual que si el usuario ubiera escogido PEGAR en el menú EDICION y hubiera añadido un texto arbitrario.

Propiedades y métodos

Propiedad Descripción
htmlText Retorna el contenido de un rango de texto y código HTML
text Retorna el texto plano contenido dentro de un rango

La propiedad text representa el texto del documento sin ninguna marca HTML. Esta propiedad es de lectura/escritura y puede utilizarse para sustituir el contenido sin formato. Esta propiedad es parecida a la propiedad outerText de los objetos elemento.

La propiedad htmlText representa el texto junto con las marcas HTML. Esta propiedad representa los elementos HTML de la misma forma que lo hace la propiedad outerHTML, pero a diferencia de ésta, htmlText es sólo para lectura. Para asignar o reemplazar en un rango nuevos elementos HTML debe utilizarse el método pasteHTML.

El método pasteHTML esta diseñado para pegar etiquetas válidas de acuerdo con la definición de tipo de documento (Document Type Definition, DTD). El navegador intentará borrar cualquier elemento HTML que no cumpla esta definición.

Método Descripción
collapse Método inverso a expand. Coloca juntas como punto de inserción las marcas de comienzo y final del objeto TextRange.
compareEndPoints Compara dos rangos de texto y retorna un valor indicando el resultado
duplicate Retorna un duplicado del actual rango de texto
expand Extiende el objeto TextRange para que abarquen completamente un carácter, una palabra, una frase o todo el texto del propietario de edición.
findText Establece el punto de comienzo y finalización de un rango de texto para encontrar un texto, si lo ha encontrado en el actual documento.
getBookmark Retorna un marcador único para identificar la ubicación el el documento
inRange Indica si un texto especificado esta dentro del actual rango
isEqual Indica si un texto especificado es igual al actual rango
move Cambia el punto de comienzo y fin del actual rango de texto
moveEnd Mueve un texto al final del actual rango
moveStart Mueve un texto al comienzo del actual rango
moveToBookmark Mueve un rango de texto para englobar el rango referenciado en un marcador que previamente fuera definido con getBookmark
moveToElementText Mueve un rango de texto para englobar el texto en un elemento especificado.
moveToPoint Mueve y contrae un rango de texto a un punto especificado en las coordenadas X e Y.
parenteElement Retorna una referencia al elemento inmediatamente más externo que encierra el actual rango de texto.
pasteHTML Pega código HTML o texto plano en el actual rango.
scrollIntoView Desplaza el rango de texto dentro del navegador, opcionalmente al tope de la ventana.
select Realza una sección del documento igual al actual rango de texto
setEndPoint Establece el punto de inicio o de finalización del rango de texto basado en el comienzo o final de otro rango.

La propiedad parentEditText

Todos los elementos tienen la propiedad denominada parentEditText que devuelve una referencia al propietario de edición de texto responsable del contenido del elemento. El uso de esta propiedad puede dar al código compatibilidad con versiones futuras del modelo de objetos. Actualmente, esta propiedad hace referencia al objeto body en la mayoría de los elementos. De esta forma podríamos crear un objeto TextRange de la siguiente forma

// ele representa un elemento del documento
var tr;
if (!ele.isTextEdit) {
	tr = ele.parentTextEdit.createTextRange();
} else {
	tr = ele.createTextRange();
}

Cada elemento del cuerpo del documento muestra la propiedad isTextEdit, que indica si el elemento es un propietario de edición de texto. El código anterior utiliza el elemento ele para crear el objeto TextRange si es propietario de edición, de lo contrario utiliza el propietario de edición de texto padre de ele.

Algunos ejemplos

El siguiente código crea el objeto TextRange y cuenta las palabras incluidas

<HTML>
  <HEAD>
    <TITLE>Cuenta de palabras</TITLE>
    <style>
      BODY {margin: 5pt}
      H1 {font-family: verdana; color: navy}
    </style>
    <SCRIPT LANGUAGE="JavaScript">
      function countWords() {
       var tr = document.body.createTextRange();
       var intCount = 0;
       // Contrae el objeto TextRange al comienzo del documento.
       tr.collapse(true);
       while (tr.move("word", 1)) 
         intCount++;
       return intCount-1; // queda tras la última palabra al final del bucle.
      }
    </SCRIPT>
  </HEAD>
  <BODY ONLOAD="alert(countWords()+' palabras')">
    <H1>Cuenta de palabras</H1>
    <P>Una sencilla función que cuenta el número de palabras del documento.
  </BODY>
</HTML>

El siguiente, muestra cual es la primera palabra del texto al hacer clic sobre el navegador

<HTML>
  <HEAD>
    <TITLE>Primera palabra</TITLE>
    <style>
      BODY {margin: 5pt}
      H1 {font-family: verdana; color: navy}
     </style>
    <SCRIPT LANGUAGE="JavaScript">
      function firstWord(myElement) {
       // Obtiene un objeto TextRange.
       var tr = document.body.createTextRange();
       // Desplaza el objeto TextRange.
       // myElement representa un elemento del documento.
       tr.moveToElementText(myElement);
       // Contrae el objeto TextRange al comienzo del documento.
       tr.collapse();
       if (tr.moveEnd("word", 1))
        return tr.text;
       else
        return "";
      }
    </SCRIPT>
  </HEAD>
  <BODY ONCLICK="alert(firstWord(event.srcElement))">
    <H1>Primera palabra</H1>
    <P>Cuando pulse en una palabra, se mostrará la primera 
          palabra del elemento sobre el que haya pulsado.</P>
  </BODY>
</HTML>

Para concluir, el siguiente ejemplo muestra en la barra de estado que palabra está ubicada debajo del cursor del mouse:

<HTML>
  <HEAD>
    <TITLE>Ratón sobre palabra</TITLE>
    <style>
      BODY {margin: 5pt}
      H1 {font-family: verdana; color: navy}
    </style>
    <SCRIPT LANGUAGE="JavaScript">
      function doMouseMove() {
       var tr = document.body.createTextRange();
       tr.moveToPoint(event.clientX, event.clientY);
       // Expande a la palabra completa bajo el ratón.
       tr.expand("word");
       window.status = tr.text;
      }
      document.onmousemove = doMouseMove;
    </SCRIPT>
  </HEAD>
  <BODY>
    <H1>Ratón sobre palabra</H1>
    <P>Una función que muestra la palabra sobre la que se encuentra
       el ratón. La palabra actual se muestra en la barra de estado.

</BODY> </HTML>