Comandos Javascript para Rich-Text Editing de HTML 5

  • Por
Nos iniciamos en la ejecución de comandos Javascript con el método execCommand para edición de texto enriquecido, una de las capacidades del API HTML5 Rich-text editing.
En el pasado artículo estuvimos estudiando nuevos atributos del lenguaje HTML que podemos asignar a elementos de la página, como Contenteditable y Spellcheck. Ahora nos dedicaremos a usar esas nuevas características de HTML5 para hacer un sencillo script Javascript que permita edición de texto enriquecido, que usará el API HTML5 Rich-text editing.

En el presente artículo trataremos los siguientes puntos:

  • Ejecución de órdenes de edición sobre área de texto contenteditable
  • Implementar algunas acciones especiales, como ver el código HTML subyacente y trabajar en modo sólo lectura
  • Veremos cómo incluir secuencias de código HTML directamente
  • Trabajaremos con estilos dentro del código subyacente
  • Veremos cómo crear hiperenlaces
  • Comentaremos aspectos del trabajo con JavaScript en general

Ejecución de órdenes. Método execCommand

El método de JavaScript denominado execCommand es una de las piezas básicas del Rich-Text Editing de HTML 5- y nos dota de la capacidad de crear un verdadero editor de textos, como veremos-. En el presente artículo sentaremos las bases.

La sintaxis del método es:

object.execCommand (commandIdentifier, userInterface, value)

Devolverá "true" si se ejecutó correctamente y "false" de lo contrario. En los listados posteriores se muestran ejemplos de utilización.

Los parámetros que toma son:

  • El nombre del comando a ejecutar –véase la tabla de más adelante-
  • La interfaz de usuario que debería mostrarse. Hasta el presente no está implementado y siempre se pasa el parámetro "false"
  • Algunos comandos necesitan algún argumento adicional, que se pasará aquí. De no ser así, se pasará una cadena de caracteres vacía –‘’-
El listado 4 que sigue, hemos implementado un área de edición con tres botones de comando para formateo de texto:
  • El área de edición se ha programado a base de CSS
  • Los botones de comando llevan asociado código JavaScript, de manera que al ser pulsado –onClick- disparan las correspondientes órdenes execCommand
  • Obsérvese la sintaxis de dichas órdenes, de las más simples en éste caso, que ejecutan comandos sin parámetros adicionales y precisan de haber sido seleccionado texto previamente en el editor
Es, a su vez, la primera maqueta de nuestro editor de textos, continuando lo expuesto en nuestro anterior artículo: HTML5 Rich-text editing. Atributos "contenteditable" y "spellcheck".

Listado 4: Área de edición con botones de comando, programados mediante "execCommand".

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" lang="es-es">
<title>contenteditable</title>
<style>
#textBox {
width: 600px;
height: 300px;
border: 2px #000000 solid;
padding: 10px;
overflow: scroll;
background-color: yellow;
}
</style>
</head>
<body>
<menu>
<button onclick="document.execCommand('bold',false,'');">Negrilla</button>
<button onclick="document.execCommand('italic',false,'');">Itálica</button>
<button onclick="document.execCommand('underline',false,'');">Subrayado</button>
</menu>

<section id="textBox" contenteditable="true">
<h1 style="color:red">Título</h1>
<p>Escribir aquí...</p>
</section>

</body>
</html>

Tabla con los comandos disponibles para la edición mediante execCommand y su prestación en el área de edición. Nótese que muchas de las órdenes sólo se ejecutarán si previamente hay un texto seleccionado y otras abarcarán a toda una sección del documento, no sólo la selección o la palabra sobre la que se encuentre el cursor.

ComandoSignificado
backColorCambia el color de fondo.
boldPermuta el texto resaltado activo/desactivado.
copyCopia el texto seleccionado al portapapeles.
createLinkCrea un hiperenlace sobre el texto seleccionado.
cutCorta el texto seleccionado y lo copia al portapapeles.
deleteBorra el texto seleccionado.
fontNameCambia la fuente.
fontSizeCambia el tamaño de la fuente.
foreColorCambia el color del texto seleccionado.
formatBlockFormatea la selección en un nuevo bloque.
indentAdentra la selección.
insertHorizontalRuleInserta un elemento –etiqueta HTML- <hr />.
insertHTMLInserta etiquetas HTML personalizadas en forma de cadenas.
insertImageInserta una imagen referenciada por una dirección URL.
insertOrderedListInserta una lista ordenada –numerada-.
insertUnorderedListInserta una lista sin ordenar –boliches-.
insertParagraphInserta un nuevo párrafo.
italicPermuta entre texto seleccionado en itálica activo/desactivado.
justifyCenterCentra lo seleccionado.
justifyFullJustifica a ambos lados lo seleccionado.
justifyLeftJustifica a la izquierda lo seleccionado.
justifyRightSigniJustifica a la derecha lo seleccionado.ficado
outdentDesadentra lo seleccionado.
pastePega el contenido del portapapeles.
redoRehace la última operación.
removeFormatRetira el formato de lo seleccionado.
selectAllSelecciona todo el contenido editable de un elemento.
strikethroughPermuta entre tachado lo seleccionado activo/desactivado.
styleWithCSSAplica estilos CSS a lo seleccionado.
subscriptPermuta entre texto seleccionado en subíndice activo/desactivado.
superscriptPermuta entre texto seleccionado en superíndice activo/desactivado.
underlinePermuta entre texto seleccionado en subrayado activo/desactivado.
undoDeshace la última operación.
unlinkSignRetira el hiperenlace del lugar seleccionado.ificado

Nota: No todos los comandos son soportados por todos los navegadores y, además, no todos se comportan exactamente igual a la hora de manejar selecciones o áreas de edición completas.
Véase una lista complementaria en: www-archive.mozilla.org/editor/midas-spec.html

Ver el código HTML subyacente y modo sólo lectura

En el listado 5 que sigue hemos implementado cuatro funciones JavaScript, que nos permiten visualizar el contenido del código HTML subyacente y recuperar la visión normal del texto dentro del editor. La cuestión es poder realizar la tarea inversa y directa cuantas veces queramos y aprovechar para guardar el contenido del editor y poder recuperarlo –algo que también ilustramos cómo hacerlo para otras opciones además de ésta, como deshacer avanzado, guardar entre sesiones, …- Para ello, aprovechamos la funcionalidad de sessionStorage –del API de JavaScript para HTML y DOM, WebStorage- que puede consultarse en: developer.mozilla.org/en-US/docs/DOM/Storage

Esencialmente se trata de:

  1. Cuando se selecciona la casilla de verificación, se llama a la función permutar que sucesivamente:
    a. Guardará en sessionStorage el contenido HTML del editor
    b. Cargará el contenido de lo guardado y lo mostrará tal cual en el editor
  2. Cuando se deselecciona la casilla de verificación, se llama a la función "permutar" que cargará el contenido de lo guardado y lo mostrará como texto HTML formateado en el editor
  3. El control de la permutación se lleva a cabo viendo el estado de selección de la casilla de verificación y se pasa como parámetro en la función permutar
Respecto a poner el editor en modo de sólo lectura, el código adicional sería simplemente añadir una casilla de verificación que alternará entre edición y sólo lectura de la forma:

<p><input type="checkbox" name="setEditable" id="setEditable" onchange="document.execCommand('contentreadonly', false, this.checked);">Sólo lectura</p>

La tarea realizada se centra en:

  1. Existe una casilla de verificación para permutar el estado de edición activado o desactivado
  2. Cuando su estado cambia, "onChange" se activa o desactiva la edición según sea el estado de selección, this.checked, de la casilla de verificación, pasándolo como parámetro a execCommand
  3. El comando motriz de llamada es "contentreadonly", si su valor es "true", el área de edición será de sólo lectura –ocurre cuando la casilla de verificación está seleccionada-
Listado 5: Área de edición con botones de comando y casillas de verificación, programados/as mediante "execCommand". Aquí, además, ilustramos dos potentes opciones complementarias, el modo de sólo lectura y el modo de vista de código HTML.

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" lang="es-es">
<title>contenteditable</title>
<style>
#textBox {
width: 600px;
height: 300px;
border: 2px #000000 solid;
padding: 10px;
overflow: scroll;
background-color: yellow;
}
</style>
</head>

<script>

/*
function saveData() {
var sessionData = document.getElementById("textBox").textContent;

sessionStorage["sData"] = sessionData;
alert(sessionData);
}
*/

function loadData() {
var sessionDataHTML = sessionStorage["sDataHTML"];

if (sessionDataHTML != null) {
document.getElementById("textBox").textContent = sessionDataHTML;
}
}

function saveDataHTML() {
var sessionDataHTML = document.getElementById("textBox").innerHTML;

sessionStorage["sDataHTML"] = sessionDataHTML;
alert(sessionDataHTML);
}

function loadDataHTML() {
var sessionDataHTML = sessionStorage["sDataHTML"];

if (sessionDataHTML != null) {
document.getElementById("textBox").innerHTML = sessionDataHTML;
}
}

function permutar(marcado) {
if (marcado == true) {
saveDataHTML(); loadData();
}
else
loadDataHTML();
}

</script>

<body>
<menu>
<button onclick="document.execCommand('bold',false,'');">Negrilla</button>
<button onclick="document.execCommand('italic',false,'');">Itálica</button>
<button onclick="document.execCommand('underline',false,'');">Subrayado</button>
</menu>

<section id="textBox" contenteditable="true">
<h1 style="color:red">Título</h1>
<p>Escribir aquí...</p>
</section>
<p><input type="checkbox" name="setEditable" id="setEditable" onchange="document.execCommand('contentreadonly', false, this.checked);">Sólo lectura</p>
<p><input type="checkbox" name="setHTML" id="setHTML" onchange="permutar(this.checked);">Ver HTML</p>

</body>
</html>

Insertar código HTML directamente

Imaginemos que deseamos incluir directamente código con formato HTML –esto es, preformateado con etiquetas HTML- en el editor . Una posibilidad es insertar el siguiente código, que se incluirá en la sección del menú entre las etiquetas de apertura y cierre <menú>…</menú>:

<button onclick="firma();">Firma</button>

Lo que hace, sin más, es una llamada a una función que ejecuta el correspondiente comando de execCommand. La función encargada de insertar el código HTML en el documento la programamos mediante JavaScript, de la siguiente forma:

function firma() {
var mensaje = '<h2>Jaime</h2>';

document.execCommand('insertHTML', false, mensaje);
}

Lo hemos hecho así, dado que el texto podrá ser modificado con mayor comodidad y ser de unas mayores dimensiones, sin interferir con el resto del código de la barra de menú.

Aplicar estilos CSS

Para la inserción de estilos CSS programaremos el siguiente fragmento de código, que se incluirá en la sección del menú entre las etiquetas de apertura y cierre <menu>…</menu>:

<button onclick="document.execCommand('styleWithCSS',false,true);">Aplicar CSS</button>

El sistema trabaja de la siguiente forma:

  1. Se selecciona un área de texto
  2. Se hace clic sobre el botón correspondiente a aplicar CSS
  3. Todas las opciones de maquetación, en lo sucesivo, se realizarán aplicando estilos en vez de etiquetas HTML, como se aprecia en las figuras adjuntas
Mozilla Firefox y Google Chrome aplican los estilos, MSIE y Opera los ignoran, ya que estos últimos emplearán aún etiquetas diferentes a la hora de maquetar los documentos, como por ejemplo <strong> en vez de <b> para negrilla.

Creación de hiperenlaces

Para la inserción de un hiperenlace, programaremos el siguiente fragmento de código, que se incluirá en la sección del menú entre las etiquetas de apertura y cierre <menu>…</menu>:

<button onclick="if (document.getElementById('szURL').checkValidity()) {
document.execCommand('createLink',false,document.getElementById('szURL').value);}">Hiperenlace</button>
<input type="url" id="szURL" required>

Como se puede observar, consta de un botón de comando estándar, nada nuevo de lo visto hasta el presente, que hace la llamada correspondiente a execCommand, pero lleva asociado un elemento input para que se escriba la cadena de texto correspondiente a la dirección URL del hiperenlace.

El sistema funciona de la siguiente manera:

  1. Escribiremos la dirección URL en el área correspondiente
  2. Deberemos posteriormente seleccionar el texto a hiperenlazar el el área de edición
  3. Finalmente, haremos clic sobre el botón de creación del hiperenlace

Qué hay de JavaScript en general

Aquí ilustramos un ejemplo de uso de estilos sobre el área de edición, mediante funciones generales de JavaScript, una alternativa al uso de execCommand para algunas de las opciones disponibles.

En la siguiente porción de código, se cambiará el color de fondo del área de texto enriquecido –contentEditable- mediante un simple botón de comando:

<button onclick="document.getElementById('textBox').style.backgroundColor = 'white'">Fondo blanco</button>

Todo esto es algo que se escapa –intencionadamente- del objeto de este artículo y es, a nuestro entender, menos versátil y funcional que el empleo del más directamente enfocado uso de execCommand; que está definido explícitamente para éstas tareas de edición sobre contentEditable.

Con todo, recomendamos un uso compartido de ambas visiones, dado que execCommand aún no goza de un soporte pleno en todos los navegadores –aunque sí lo tiene teóricamente, no así en cuanto al modo de implementarlo de forma unificada- y, sobre todo, en las versiones que no sean las últimas.

Ejemplo funcionando

Autor

Jaime Peña Tresancos

Escritor. Colaborador habitual de revistas de tecnología y experto en nuevas tecnologías y programas Microsoft

Compartir

Comentarios

Gustavo

12/8/2013
b ó strong?
En muchos sitios desaconsejan la utilización de <b> e <i> y se aconseja la utilizacion de <strong> y <em>.
Parece que con execCommand se manejan las etiquetas <b< e <i>.
¿Podrían aclarar este tema?

Irving de leon

03/3/2014
Duda
Gracias por dar esta información, es muy buena pero no podrías hacer un ejemplo mas completo? , he buscado ejemplos en otras paginas pero no he encontrado el uso de el comando copy, gracias.

Miguel Peláez

04/7/2014
funcionamiento de contenteditable
Hola a todos, excelente articulo sobre como poder trabajar con texto enriquecido, pero tengo una pregunta y perdonen si es muy obvia pero ando en el aprendizaje de como hacer el editor de texto para mi blog. Bueno la cosa es así, al crear ya todo mi contenido en mi espacio editable como hago el proceso de publicarlo, ya sea como si fuera una entrada de algún articulo o como si fuera una sección de comentarios; no se si se guarda en una base de datos y luego se recupera desde la pagina principal y si es así como guardo el contenido de por ejemplo un <section> editable en donde trabajo todo el contenido. Por favor si puedes colaborarme te agradecería.

SAUL

10/11/2016
COMO GUARDAR LOS CAMBIOS
DESPUES DE HACER TODOS LOS CAMBIOS COMO LOS GUARDO?
DE MANERA LOCAL?