Creando y modificando HTML

By dedalo534

Introducción

En este artículo explicaremos los conocimientos básicos de JavaScript para manipular el contenido de las páginas HTML, incluyendo mostrar y ocultar partes de una página, y añadir nuevo contenido HTML, y eliminarlo. Al final, habremos comprendido que la razón fundamental por la que usamos JavaScript es para cambiar el contenido de las páginas, y habremos entendido las mejores formas para hacer esto

Los contenidos de este artículo son los siguientes:

Ocultando y mostrando

La mejor forma de empezar es manipular el HTML que ya tenemos hecho, ocultando o mostrando elementos que ya están en la página. Para hacer esto, podemos usar JavaScript para cambiar los estilos de un elemento. Los estilos CSS son una forma elegante de describir como se muestra un elemento, y una parte de como se muestra un elemento es si se muestra totalmente o no. La propiedad CSS display es la llave para mostrar o ocultar un elemento: si la ponemos a display:none; oculta un elemento. Imaginemos un párrafo cómo este:

<p id="miparrafo" style="display: none">Yo soy un párrafo</p>

Este párrafo debería ser invisible en la página. JavaScript nos permite dinámicamente añadir ese estilo a ese elemento, y eliminarlo.

JavaScript está diseñado para permitirnos obtener una referencia a un elemento HTML. Por ejemplo, el código var el = document.getElementById("nav"); nos dará una referencia al elemento cuyo id="nav". Una vez hayamos obtenido la referencia de un elemento, podemos cambiar el estilo CSS asociado a él, mediante el uso del atributo style. Por ejemplo, el párrafo “miparrafo” está actualmente oculto (tiene establecido display: none). Para mostrarlo, actualizamos el atributo de estilos display a block:

var parrafo = document.getElementById('miparrafo');
parrafo.style.display = 'block';

Y ahora, el párrafo aparece. Establecer estilos CSS en un elemento a través del atributo style es exactamente la misma cosa que establecerlos en el atributo style en el propio HTML, así que, en el código anterior, parrafo.style.display = 'block' tiene el mismo efecto que poner style="display: block" directamente en nuestro HTML. Excepto que éste es dinámico. Y ocultar cualquier elemento es así de simple:

var parrafo = document.getElementById('miparrafo');
parrafo.style.display = 'none';

Ocultando y mostrando, un ejemplo

La teoría es buena, pero un ejemplo práctico en esta situación será bastante útil. Imaginemos una serie de pestañas, donde hacer click sobre una de ellas la muestra y oculta el resto de las otras.

A continuación un ejemplo de un conjunto de pestañas:

<ol class="tablinks">
  <li><a href="#tab1">Pestaña 1</a></li>
  <li><a href="#tab2">Pestaña 2</a></li>
  <li><a href="#tab3">Pestaña 3</a></li>
</ol>

<div class="tab" id="tab1">Esta es la pestaña 1</div>
<div class="tab" id="tab2">Esta es la pestaña 2</div>
<div class="tab" id="tab3">Esta es la pestaña 3</div>

En la elemento head del fichero de ejemplo (ver tabs.html para el ejemplo funcionando), encontraremos las siguientes definiciones CSS y el siguiente código JavaScript (normalmente se ponen en ficheros aparte, y son importados en el HTML, pero aquí lo dejaremos todo en un fichero para hacer las cosas más simples). Algunos trozos de código pueden parecer intimidantes, no hay problema, nos ocuparemos de ellos.

<style type="text/css">
ol.tablinks {
  margin: 0; padding: 0;
}
ol.tablinks li {
  float: left;
  border: 2px solid red;
  border-width: 2px 2px 0 2px;
  background: #eee;
  list-style: none;
  padding: 5px;
  margin: 0;
}
ol.tablinks li a {
  text-decoration: none;
  color: black;
}
div.tab {
  clear: left;
  border: 2px solid red;
  border-width: 1px 2px 2px 2px;
}
</style>

<script type="text/javascript">
var tabify = {
  hasClass: function(el,c) {
    return el.className.match(new RegExp('(\\s|^)'+c+'(\\s|$)'));
  },
  addClass: function(el,c) {
    if (!tabify.hasClass(el,c)) el.className += " " + c;
  },
  removeClass: function(el,c) {
    if (tabify.hasClass(el,c)) {
      el.className=el.className.replace(new RegExp('(\\s|^)'+c+'(\\s|$)'),' ');
    }
  },
  hideAllTabs: function(ol) {
    var links = ol.getElementsByTagName("a");
    for (var i=0; i<links.length; i++) {
      tabify.setTabFromLink(links[i], "none");
   }
  },
  setTabFromLink: function(link, style) {
    var dest = link.href.match(/#(.*)$/)[1];
    document.getElementById(dest).style.display = style;
    if (style == "none") {
        tabify.removeClass(link, "active");
    } else {
        tabify.addClass(link, "active");
    }
  },
  addEvent: function(obj, type, fn) {
    if ( obj.attachEvent ) {
      obj['e'+type+fn] = fn;
      obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
      obj.attachEvent('on'+type, obj[type+fn] );
    } else {
      obj.addEventListener( type, fn, false );
    }
  },
  init: function() {
    var ols = document.getElementsByTagName("ol");
    for (var i=0; i<ols.length; i++) {
      var ol = ols[i];
      if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
      tabify.addEvent(ol, "click", function(e) {
        var target = window.event ? window.event.srcElement : e.target;
        if (target.nodeName.toLowerCase() === "a") {
          tabify.hideAllTabs(e.target.parentNode.parentNode);
          tabify.setTabFromLink(e.target, "block");
          if (e) e.preventDefault();
          if (window.event) window.event.returnValue = false;
          return false;
        }
      }, true);
      tabify.hideAllTabs(ol);
      tabify.setTabFromLink(ol.getElementsByTagName("a")[0], "block");
    }
  }
};
tabify.addEvent(window, "load", tabify.init);
</script>

Cada pestaña es un enlace. Cada enlace tiene un método gestor de eventos onclick asociado a él. Ese método gestor de eventos hace dos cosas: él oculta todos los divs (usando display: none como se hizo antes), y después muestra el div correspondiente a esa pestaña, estableciendo para ello la propiedad style del div a display: block.

Seguramente hayamos notado que el código HTML de más arriba está preparado para mantener el sentido incluso en la ausencia ó desactivación de JavaScript; si al pinchar sobre un enlace no se muestra ni se oculta ninguna pestaña, los enlaces nos llevan hacia la pestaña adecuada, así que la página sigue operando correctamente, y mantiene la semántica, incluso en navegadores sin JavaScript. Esto es importante: es una técnica de la que habremos oido hablar como “mejora progresiva - progressive enhancement” (ó como se denominaba hace unos 3 años, “degradación elegante - graceful degradation”, aunque ahora ya no se la llama así). Esto es importante no sólo para la gente que, usando un navegador moderno, tiene JavaScript desactivado, sino también para otros tipos de usuarios. Tecnologias de ayuda, como lectores de pantalla, para gente con discapacidad visual, soportan el peso de su estructura en que nuestro código HTML sea semántico y significativo; además su soporte de JavaScript no es todo lo bueno como el del resto de usuarios. Los navegadores sobre móviles tampoco tienden a tener mucho soporte de JavaScript. Los motores de búsqueda pueden leer nuestro HTML, pero no nuestros scripts; se puede decir que Google es el más voraz navegador de usuarios ciegos en el mundo. Este es el significado del término “mejora progresiva - progressive enhancement”: se empieza con una página que tiene sentido y que muestra su contenido en el entorno más simple, como un navegador web de sólo texto, y entonces, gradualmente, se la añade funcionalidad extra de tal forma que, a cada paso, nuestra página siga siendo funcional y usable.

Todo el código JavaScript se puede dividir en dos partes: la parte que actualmente hace el trabajo, y la parte en la se engancha con el código HTML. El código que actualmente hace el trabajo en este ejemplo es bastante sencillo: mostrar la pestaña correspondiente a cada enlace son dos líneas de JavaScript:

var dest = link.href.match(/#(.*)$/)[1];
document.getElementById(dest).style.display = "block";

Los enlaces, si recordamos, son como <a href="#tab1">Pestaña 1</a>, así que la primera línea usa una expresión regular (ver la nota más abajo) para extraer la parte del enlace que aparece después del símbolo # ; en este ejemplo sería la cadena tab1. Esa parte del enlace es la misma que el ID del correspondiente div (porque, como hemos mencionado, la página está construida para tener sentido semántico, así que un “tab” apunta a su div). Entonces nosotros buscamos una referencia a ese div mediante document.getElementById, y establecemos style.display a block como habíamos dicho antes.

Expresiones regulares

Las expresiones regulares son una especie de mini-lenguaje de programación, diseñado para ayudar con los problemas de “parseo” de texto—por ejemplo, responder a cuestiones como “ ¿aparece esta cadena dentro de esta otra cadena?“ y “en la cadena ‘abc123def’, ¿cuáles son los números entre ‘c’ y ‘d’?”. Son una herramienta muy potente, pero a la vez son elegantemente complicadas. A continuación se describe esta expresión regular; por ahora sintámonos libres para confiar en cómo trabaja, ya volveremos a ella más tarde.

La expresión regular, “regex”, usada en este ejemplo es /#(.*)$/. Cada carácter en una expresión regular está diseñado para coincidir con una secuencia de caracteres en la cadena que se está analizando; la idea es expresar como la cadena que se está analizando está construida, en secciones.

  • / … / — las barras son justo el inicio y el final de una expresion regular, como las comillas simples ó dobles para una “cadena”
  • # — el símbolo almohadilla (#) significa “el carácter tiene que ser una almohadilla”
  • ( … ) — los paréntesis significan que “aquí hay una sección en la que estaré interesado más adelante.”
  • .* — significa “cualquier secuencia de caracteres que haya”; es un punto (.), significando “un único carácter”, seguido de un asterisco (*) significando “repetido tantas veces como queramos”
  • $ — el dólar significa “el final de la cadena”

Así que nuestra expresión regular describe un “patrón de coincidencias” para una cadena compuesta de “una almohadilla, seguida de los caracteres que queramos”. link.href es el destino del enlace que nosotros estamos buscando (por ejemplo, #tab1, y como esta cadena es una cadena descrita mediante “una almohadilla seguida de los caracteres que queramos”), el “patrón de coincidencias” se aplica a esta cadena.

link.href.match(expresionRegular), de ese modo, nos devolverá tanto un verdadero como un falso; lo que actualmente devuelve es un array de dos valores, ["#tab1", "tab1"]. Lo primero es el texto que coincide con la expresion regular completa, y lo segundo es el texto que coincide dentro de los paréntesis; esto es el porqué los paréntesis están ahí—para marcar esa parte de la cadena como “esta es la parte que nosotros necesitamos”. La cadena tab1 es lo que nosotros necesitamos, asi que podemos sacarla de ese array (es el segundo elemento, así que [1] la seleccionará — los arrays empiezan en cero.)

Conectando el código escrito con una página

Como ya se ha dicho más arriba, hay dos partes en el código: la parte que hace el trabajo, y la parte que engancha eso al HTML. Enganchar el código que hace el trabajo al HTML es decidir que eventos son para qué. En este ejemplo particular, nos toca preocuparnos de dos eventos, el evento load del objeto window, que se utiliza para decir “empezar todo ”, y el evento click de la lista de pestañas, que se dispara cuando un usuario pincha en una pestaña. Cuando la página carga, necesitamos hacer funcionar el código que crea las conexiones, y el código que crea las conexiones debería conectar el evento click de las pestañas al código de más arriba, que muestra la pestaña más apropiada.

El hacer funcionar código en respuesta a un evento se hace mediante la function addEventListener en la mayoría de navegadores, y con la función attachEvent en Internet Explorer. Aquí nosotros estamos creando una función “envoltura”, que hace lo adecuado en función de lo que está soportado;

addEvent: function(obj, type, fn) {
  if ( obj.attachEvent ) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
    obj.attachEvent('on'+type, obj[type+fn] );
  } else {
    obj.addEventListener( type, fn, false );
  }
}

(No nos preocupemos mucho el porqué esto funciona; tomemos como cierto el que lo hace—lo entenderemos cuando estemos más experimentados en JavaScript.) Esta función toma tres parámetros, obj, type, y fn, que son “el objeto que dispara el evento”, “ el evento del que estamos interesados”, y “la función que hay que ejecutar cuando el evento se dispara”. Nosotros necesitamos ejecutar nuestra función llamadatabify.init cuando la página carga; la función tabify.init tendrá cuidado de manejar cada evento click de las pestañas.

addEvent(window, "load", tabify.init);

Como podemos observar de la estructura del HTML de más arriba, un conjunto de pestañas con expresadas como una lista ordenada con class="tablinks". Así que la función tabify.init necesita hacer lo siguiente:

  1. Encontrar todos los <ol> en la página con una clase de tablinks
  2. Añadir a cada evento click de los <ol> código que haga lo siguiente:
    1. Funcionar exactamente como cualquier enlace en el que usuario pincha
    2. Hacer que la pestaña actual se corresponda con ese enlace
    3. Mostrar esa pestaña
    4. Ocultar el resto de pestañas

La función init que hace todo eso es la siguiente:

init: function() {
  var ols = document.getElementsByTagName("ol");
  for (var i=0; i<ols.length; i++) {
    var ol = ols[i];
    if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
    tabify.addEvent(ol, "click", function(e) {
      var target = window.event ? window.event.srcElement : e.target;
      if (target.nodeName.toLowerCase() === "a") {
        tabify.hideAllTabs(e.target.parentNode.parentNode);
        tabify.setTabFromLink(e.target, "block");
        if (e) e.preventDefault();
        if (window.event) window.event.returnValue = false;
        return false;
      }
    }, true);
    tabify.hideAllTabs(ol);
    tabify.setTabFromLink(ol.getElementsByTagName("a")[0], "block");
  }
}

Vayamos paso a paso dentro de esta función, mirando que hace exactamente cada parte:

var ols = document.getElementsByTagName("ol");
  for (var i=0; i<ols.length; i++) {
    var ol = ols[i];
    if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
  }

Esto encuentra todos los <ol> en la página que tengan una clase de tablinks— esto construye una lista de todos los <ol> y por cada uno, pregunta “si este no tiene una clase de ‘tablinks’, entonces pasa de él”. (Chequear la clase se hace mediante una expresión regular; continue significa “pasa de este elemento y vete al siguiente”.)

tabify.addEvent(ol, "click", function(e) {
  ...
});

Esto conecta código a cada evento click de los <ol>.

var target = window.event ? window.event.srcElement : e.target;

Esto funciona exactamente como un enlace cuando el usuario pincha sobre él…

tabify.setTabFromLink(e.target, "block");

…entonces esto muestra una pestaña simple…

tabify.hideAllTabs(e.target.parentNode.parentNode);

…y finalmente, esta línea oculta el resto de pestañas.

Las funciones setTabFromLink y hideAllTabs están también en el código; utilizan las técnicas de más arriba para ocultar una pestaña ó para mostrarla. Se puede echar un vistazo en ellas para ver como trabajan — son funciones separadas porque a menudo es útil tener un trozo de código que se pueda llamar desde más de un sitio y ponerlo en nuestras propias funciones. (Esto hace nuestro código más facilmente entendible y reutilizable en más sitios. La gente se refiere en ocasiones a esto como “partir” o “factorizar” codigo en funciones.)

Además, existe un trabajo extra, que muestra hábilmente mas cosas que añadir o quitar atributos. La función setTabFromLink no solamente muestra la pestaña adecuada, sino que tambien establece class="active" en la pestaña "activa". Esto lo hace con la ayuda de tres funciones de utilidades, hasClass, removeClass, y addClass. De la misma forma que nosotros ocultamos todas las pestañas, y mostramos la activa, utilizamos removeClass para quitar "active" del className de todos los enlaces, y entonces utilizar addClass para añadir "active" al enlace que está actualmente activo. Añadir una clase a un enlace puede parece sin sentido — despues de todo; las clases son invisibles — pero es una ayuda para la creación de estilos. Nosotros podemos (y debemos) hacer que los enlaces con class="active" aparezcan diferentes, simplemente añadiendo CSS extra:

ol.tablinks li a {
  background-color: red;
}

ol.tablinks li a.active {
  background-color: white;
}

Así que ahora, la pestaña "activa" aparece en blanco, mientras las otras aparecen en rojo. Utilizar JavaScript para añadir y quitar clases es una técnica muy común, y que debemos utilizar allá donde nos sea posible; CSS es bueno para controlar el layout y la posición y apariencia de nuestros elementos HTML; y utilizar JavaScript para alterar las clases de aquellos elementos significa que pueden adquirir diferentes estilos CSS. Es una unificación ideal; JavaScript hace a nuestros elementos dinámicos pero sin hacer muchos cambios sobre ellos. Justo añadir una clase y dejar que CSS se encargue del trabajo duro.

Creando HTML

Los scripts que manejan el árbol DOM son mucho mas potentes que alterar simplemente las propiedades CSS de nuestro HTML existente, que también. Además, podemos crear dinámicamente HTML nuevo que nunca estuvo en nuestra página cuando ésta empezó. Por ejemplo, en el sitio de noticias técnicas Slashdot, un enlace en un comentario muestra el destino del enlace entre corchetes, así que un enlace como <a href="http://opera.com">A web browser</a> se mostrará como <a href="http://opera.com">A web browser</a> [opera.com]. (Ellos hicieron esto para que no se pudiera engañar a la gente, ó peor aún.) Añadir esta información extra al HTML, mostrando el dominio destino de cada enlace en la página, es bastante sencillo de hacer con JavaScript.

Crear nuevos elementos HTML se hace con la función document.createElement. Para este ejemplo, solamente vamos a añadir una cosa: después de cada enlace, añadiremos un span conteniendo texto que muestra el dominio de un enlace (comprobar linkify.html para un ejemplo en vivo). El HTML para este ejemplo es tal como sigue:

<p id="start">Esto es un texto que contiene
<a href="http://www.w3.org/TR/html4/struct/links.html">enlaces</a> en él a varios
sitios, inclyendo <a href="http://www.opera.com">Opera</a>,
<a href="http://www.bbc.co.uk/">la BBC</a> y un enlace interno a
<a href="#start">el inicio de esta sección</a>. Todos los enlaces
externos deberían tener <span>[domain]</span> después de ellos.</p>

Y el código JavaScript es el siguiente:

<script type="text/javascript">
var linksuffix = {
  addEvent: function(obj, type, fn) {
    if ( obj.attachEvent ) {
      obj['e'+type+fn] = fn;
      obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
      obj.attachEvent('on'+type, obj[type+fn] );
    } else {
      obj.addEventListener( type, fn, false );
    }
  },
  init: function() {
    var links = document.getElementById("linksuffixtext").getElementsByTagName("a");
    for (var i=0; i<links.length; i++) {
      var matches = links[i].href.match(/^http:\/\/(.*?)\//);
      if (matches) {
        var linkdomain = matches[1];
        var span = document.createElement("span");
        var spantext = document.createTextNode(" ["+linkdomain+"]");
        span.appendChild(spantext);
        links[i].parentNode.insertBefore(span, links[i].nextSibling);
      }
    }
  }
};
linksuffix.addEvent(window, "load", linksuffix.init);
</script>

La parte del script que hace el trabajo aquí es la siguiente:

var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
  var matches = links[i].href.match(/^http:\/\/(.*?)\//);
  if (matches) {
    var linkdomain = matches[1];
    var span = document.createElement("span");
    var spantext = document.createTextNode(" ["+linkdomain+"]");
    span.appendChild(spantext);
    links[i].parentNode.insertBefore(span, links[i].nextSibling);
  }
}

Esto se descompone en:

var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
  ...
}

Primero, encuentra todos los enlaces (getElementsByTagName("a")) en el documento

var matches = links[i].href.match(/^http:\/\/(.*?)\//);
if (matches) {
  ...
}

Esta línea utiliza una expresión regular en cada enlace para encontrar si el destino del enlace empieza con http://something/. Si lo hace…

var linkdomain = matches[1];
var span = document.createElement("span");
var spantext = document.createTextNode(" ["+linkdomain+"]");
span.appendChild(spantext);

…esta parte primero obtiene el “linkdomain”, la parte www.opera.com del enlace. Lo siguiente es crear un elemento <span> utilizando document.createElement. Lo siguiente, crea un “textNode”. Mientras los elementos HTML en sí son creados con document.createElement, todos los textos en un documento HTML se crean con “textNode”s, y hay que crearlos separadamente. No hay porqué preocuparnos sobre esto cuando creamos HTML normal, pero tenemos que conocerlo si creamos elementos mediante scripts que modifican el árbol DOM. El texto en el textNode es en realidad “ [domain]”, creado mediante la concatenación (añadirse a si mismo) de cadenas. Finalmente, se usa el método appendChild del elemento <span> para poner el textNode dentro del span.

links[i].parentNode.insertBefore(span, links[i].nextSibling);

Esta línea añade el elemento span en el documento. En este punto, el elemento span es una referencia a un elemento HTML que se muestra como sigue:

<span> [example.com]</span>

Este elemento, obviamente, no es parte del documento. No es parte de ningún documento todavía; es simplemente un elemento flotando en el limbo. Añadir el elemento al documento se puede hacer de dos formas: usando appendChild como más arriba, ó utilizar insertBefore. La función appendChild añade nuestro nuevo elemento al final de un elemento existente (esto es por lo que se llama append). Como nosotros tenemos que añadirlo justo en medio de un elemento existente, utilizaremos insertBefore. Recuerda que nuestro trozo de HTML es algo como lo que sigue:

<p>... texto que tiene
<a href="http://www.w3.org/TR/html4/struct/links.html">enlaces</a> en él
a ...

Esto es igual que el árbol DOM que aparecía en la Figura 1:

El &aacute;rbol DOM antes de la adicci&oacute;n del elemento span despu&eacute;s del enlace

Figura 1: El árbol DOM antes de la adicción del elemento span después del enlace

Queremos insertar nuestro elemento span entre el <a> y el textNode “en él a”, asi que tiene que aparecer después del <a>. Esto dejará nuestro árbol DOM como el que aparece en la Figura 2:

&Aacute;rbol DOM despu&eacute;s de la adicci&oacute;n del elemento span

Figura 2: Árbol DOM después de la adicción del elemento span

ó mas simple, HTML como el siguiente

<p>... texto que tiene
<a href="http://www.w3.org/TR/html4/struct/links.html">enlaces</a>
<span> [domain]</span> en él a...

Lo que puede ser práctico aquí es poder decir “inserta nuestro nuevo elemento span despues del enlace”. Qué pena, no existe la función insertAfter. En su lugar, tenemos que insertarlo antes que el elemento después del enlace (confuso, pero pensemos acerca de ello y todo tendrá sentido). Una manera rápida de llegar al “elemento después de un elemento llamado el” es el.nextSibling. La función insertBefore necesita ser llamada sobre el elemento en el que nosotros estamos insertando, que es el elemento <p> padre del enlace, rapidamente accesible via link.parentNode. Así que la llamada completa es como sigue:

links[i].parentNode.insertBefore(span, links[i].nextSibling);

Esto es, encuentra el padre del enlace <p> que nosotros estamos procesando (links[i]), e inserta nuestro elemento recién creado span antes que el elemento después del enlace (links[i].nextSibling). Tratar el código HTML como un árbol DOM en este caso e insertar nuevos elementos en él puede ser confuso al principio, pero empieza a estar muy claro en cuanto se gana práctica con ello.

Resumen

HTML nos provee con la estructura para nuestras páginas, y CSS nos proveen de la descripción sobre como se muestran. Lo que JavaScript nos permite es la flexibilidad; nuestra estructura HTML y nuestros estilos CSS pasan a ser dinámicos. Podemos cambiar cómo nuestras páginas se muestran y aparecen y trabajar de momento en momento, basados en lo que los usuarios hacen. Este es el siguiente paso: basados en información y daots bien pensados y bien estructurados, hacer que cambien dependiendo de lo que nuestros usuarios necesiten. Además, podemos mostrar y ocultar elementos, hacer cambios de estilos y apariencias, y añadir nuevo HTML o quitar el viejo de la forma que necesitemos.

Ejercicios

  • ¿Cómo podemos modificar la propiedad display del CSS de un elemento para ocultarlo?
  • ¿Cúal es la diferencia entre un elemento y un nodo de texto?
  • Da dos razones por las que mejoras progresivas es importante.
  • ¿Cúal es la diferencia entre appendChild e insertBefore?
  • ¿Porqué utilizamos la función addClass en vez de concatenar el nuevo nombre de clase con el atributo className de un elemento?
  • En la siguiente estrutura HTML, ¿que puede ser document.getElementById("marker").nextSibling?

    <p>Este es un <strong>bloque de HTML con
      <span id="marker">varios enlaces<span> en él</strong>.</p>

Acerca del autor

Foto del autor del art&iacute;culo, Stuart Langridge

Stuart Langridge es posiblemente la única persona en el mundo en tener un BSc en Informática y Filosofía. Cuando él no esta trasteando con ordenadores, él es un hacker de JavaScript, Django y Python en Canonical, autor de DHTML Utopia en SitePoint, y un bebedor de cervezas decentes. Además, es una cuarta parte del equipo en LugRadio, un programa de radio de estreno mundial sobre temas de software "Free and Open Source". Sus divagaciones sobre la web, scripts, software open source, y cualesquiera otras muchas cosas, se pueden encontrar en kryogenix.org; Stuart puede ser encontrado fuera buscando en el área de fumadores.

This article is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported license.

Comments

The forum archive of this article is still available on My Opera.

No new comments accepted.