Advertisement
  1. Web Design
  2. HTML5

Crea un editor WYSIWYG con el atributo contentEditable

Scroll to top
Read Time: 7 min

() translation by (you can also view the original English article)

Los editores WYSIWYG son bastante populares. Es posible que tú también hayas utilizado uno en algún momento. Hay muchas bibliotecas disponibles para ayudarte a configurar tu propio editor. Aunque son rápidas de configurar, también hay desventajas en el uso de estas. Para empezar, son excesivas. La mayoría de ellas tienen funciones extravagantes que tal vez no utilices. Además, personalizar la apariencia de esos editores puede ser un dolor de cabeza.

En este tutorial, construiremos nuestro propio editor WYSIWYG ligero. Al final de este tutorial, tendrás un editor con capacidades básicas de formato que es el estilo de acuerdo a tus preferencias.

Comencemos con la introducción de execCommand. Utilizaremos este comando para implementar ampliamente nuestro editor.

Document.execCommand()

execCommand es un método del objeto del documento. Nos permite manipular el contenido de una región editable. Cuando se utiliza junto a contentEditable, puede ayudarnos a crear un editor de texto enriquecido. Hay muchos comandos disponibles, como añadir un enlace, poner una selección en negrita o cursiva y cambiar el tamaño o el color de la fuente. Este método sigue la sintaxis:

1
document.execCommand(CommandName, ShowDefaultUI, ValueArgument);

CommandNamees una cadena que especifica el nombre del comando a ejecutar. ShowDefaultUIes un booleano que indica si la interfaz de apoyo debe mostrarse o no. Esta opción no está completamente implementada, y es mejor establecerla en falso. ValueArgument es una cadena para proporcionar información como la URL de la imagen o el color frontal. Este argumento se establece en null cuando un comando no requiere un valor para tener efecto.

Necesitaremos utilizar diferentes versiones de este método para implementar varias características. En los próximos párrafos, repasaré todas y cada una de ellas.

Comandos sin argumento de valor

Comandos como negrita, justificar, deshacer y rehacer no necesitan un ValueArgument. En estos casos utilizamos la siguiente sintaxis:

1
document.execCommand(commandName, false, null);

CommandName es simplemente el nombre de los comandos como: justificaciónalcentrojustificaciónaladerechanegrita, etc.

Comandos con un argumento de valor

Comandos como insertarimagen, crearlink y colorfrente necesitan un argumento para funcionar correctamente. Para estos comandos, se necesita la siguiente sintaxis:

1
document.execCommand(commandName, false, value);

En el caso de insertarmagen, el valor sería la URL de la imagen a insertar. En el caso de colorfrente, sería un valor de color como #FF9966 o un nombre como azul.

Comandos que añaden etiquetas de estilo de bloque

Para añadir etiquetas de estilo de bloque HTML es necesario utilizar formatBlock como commandName y el nombre de la etiqueta como valueArgument. La sintaxis sería similar a:

1
document.execCommand('formatBlock', false, tagName);

Este método añadirá una etiqueta de estilo de bloque HTML alrededor de la línea que contiene la selección actual. También reemplazará cualquier etiqueta que ya existiera allí. tagNamepuede ser cualquiera de las etiquetas de encabezado (h1-h6), p o blockquote.

Aquí he puesto los comandos más comunes. Puedes visitar Mozilla para ver una lista de todos los comandos disponibles.

Crea una barra de herramientas

Con lo básico fuera de nuestro camino, es el momento de crear la barra de herramientas. Voy a utilizar los iconos de Font Awesome para los botones. Habrás notado que, dejando de lado algunas diferencias, todos los execCommands tienen una estructura similar. Podemos usar esto a nuestro favor utilizando el siguiente marcado para los botones de la barra de herramientas:

1
<a href="#" data-command='commandName'><i class='fa fa-icon'></i></a>

De esta manera, cada vez que los usuarios hagan clic en un botón, podremos saber qué versión de execCommand utilizar en función del valor del atributo data-command. Aquí hay unos cuantos botones como referencia:

1
<a href="#" data-command='h2'>H2</a>
2
<a href="#" data-command='undo'><i class='fa fa-undo'></i></a>
3
<a href="#" data-command='createlink'><i class='fa fa-link'></i></a>
4
<a href="#" data-command='justifyLeft'><i class='fa fa-align-left'></i></a>
5
<a href="#" data-command='superscript'><i class='fa fa-superscript'></i></a>

El valor del atributo data-command del primer botón es h2. Después de comprobar este valor en JavaScript, utilizaremos la versión formatBlock del método execCommand. Del mismo modo, para el último botón, el superíndice sugiere que debemos utilizar la versión sin valueArgument de execCommand.

La creación de los botones foreColor y backColor es una historia diferente. Plantean dos problemas. Dependiendo de cuántos colores estemos proporcionando a los usuarios para que elijan, escribir tanto código puede ser tedioso y propenso a errores. Para solucionar este problema podemos utilizar el siguiente código JavaScript:

1
var colorPalette = ['000000', 'FF9966', '6699FF', '99FF66','CC0000', '00CC00', '0000CC', '333333', '0066FF', 'FFFFFF'];
2
                    
3
var forePalette = $('.fore-palette');
4
5
for (var i = 0; i < colorPalette.length; i++) {
6
  forePalette.append('<a href="#" data-command="forecolor" data-value="' + '#' + colorPalette[i] + '" style="background-color:' + '#' + colorPalette[i] + ';" class="palette-item"></a>');
7
}

Observa que también estoy estableciendo un atributo para el data-value para cada color. Esto se utilizará más tarde como valueArgument en el método execCommand.

El segundo problema es que no podemos mostrar tantos colores todo el tiempo, porque ocuparía mucho espacio y sería una experiencia terrible. Utilizando un poco de CSS, podemos asegurarnos de que la paleta de colores aparezca sólo cuando el usuario pase el mouse por encima de los botones respectivos. También hay que cambiar el marcado de estos botones por el siguiente:

1
<div class="fore-wrapper"><i class='fa fa-font'></i>
2
  <div class="fore-palette">
3
  </div>
4
</div>

Para mostrar las paletas sólo al pasar por encima, necesitamos el siguiente CSS:

1
.fore-palette,
2
.back-palette {
3
  display: none;
4
}
5
6
.fore-wrapper:hover .fore-palette,
7
.back-wrapper:hover .back-palette {
8
  display: block;
9
  float: left;
10
  position: absolute;
11
}

Hay muchas otras reglas CSS en la demo de CodePen para hacer la barra de herramientas más bonita, pero esto es todo lo que se necesitas para la funcionalidad principal.

Añada funcionalidad al editor

Ahora, es el momento de hacer que nuestro editor sea funcional. El código necesario para hacerlo es sorprendentemente pequeño.

1
$('.toolbar a').click(function(e) {
2
    
3
  var command = $(this).data('command');
4
  
5
  if (command == 'h1' || command == 'h2' || command == 'p') {
6
    document.execCommand('formatBlock', false, command);
7
  }
8
  
9
  if (command == 'forecolor' || command == 'backcolor') {
10
    document.execCommand($(this).data('command'), false, $(this).data('value'));
11
  }
12
  
13
  if (command == 'createlink' || command == 'insertimage') {
14
    url = prompt('Enter the link here: ','http:\/\/');
15
    document.execCommand($(this).data('command'), false, url);
16
  }
17
  
18
  else document.execCommand($(this).data('command'), false, null);
19
  
20
});

Comenzamos adjuntando un evento de clic a todos los botones de la barra de herramientas. Cada vez que se hace clic en un botón de la barra de herramientas, almacenamos el valor del atributo data-command del respectivo botón en la variable, command. Esto se utiliza posteriormente para llamar a la versión apropiada del método execCommand. Nos ayuda el escribir un código conciso y evitar las repeticiones.

Al establecer colorfrente y coloradetrás, estoy usando el atributo data-value como tercer argumento. crearlink e insertarimagen no tienen un valor url constante, así que usamos un prompt para obtener los valores del usuario. También puedes realizar comprobaciones adicionales para asegurarte de que la url es válido. Si la variable comando no satisface ninguno de los bloques If, ejecutamos la primera versión de execCommand.

Este es el aspecto de nuestro editor WYSIWYG.

WYSIWYG EditorWYSIWYG EditorWYSIWYG Editor

También puedes implementar la funcionalidad de auto-guardado usando localStorage  de eso hablé en mi último tutorial.

Diferencias entre navegadores

Los distintos navegadores tienen pequeñas diferencias de implementación. Por ejemplo, ten en cuenta que al utilizar formatBlock, Internet Explorer sólo admite las etiquetas de encabezamiento h1 - h6, dirección y pre. También es necesario incluir los delimitadores de la etiqueta al especificar el comandoName como h3.

No todos los comandos son compatibles con todos los navegadores. Internet Explorer no soporta comandos como insertHTML y hiliteColor. Del mismo modo, insertBrOnReturn sólo es compatible con Firefox. Puedes leer más sobre las inconsistencias de los navegadores en esta página de GitHub.

Reflexiones finales

Crear tu propio editor WYSIWYG puede ser una gran experiencia de aprendizaje. En este tutorial he cubierto un montón de comandos y he utilizado algo de CSS para el estilo básico. Como ejercicio, te sugiero que intentes implementar un botón de la barra de herramientas para establecer la fuente de una selección de texto. La implementación será similar a la del botón colorfrente.

Espero que te haya gustado este tutorial y hayas aprendido algo nuevo. Si has creado tu propio editor WYSIWYG desde cero, no dudes en poner el link en la sección de comentarios.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.