Tenía la intención de usar el método Document.execCommand() junto con el atributo contenteditable para construir mi editor WYSIWYG personalizado. Pero cuando revisé la documentación de Document.execCommand() , descubrí que ahora está obsoleto. ¿Cuál es la alternativa moderna (o existente) para ello?
Parece que la alternativa será Input Events Level 2 .
Si bien es muy tentador crear un editor WYSIWYG hecho a sí mismo, personalmente me quedaré con execCommand hasta que llegue el nuevo estándar. Porque todos programaremos un editor completo por nosotros mismos, en lugar de reutilizar las soluciones de trabajo actuales.
La documentación de referencia lo dice como advertencia.
Se prevé que en el futuro ambas especificaciones serán reemplazadas por Contenido editable y Eventos de entrada .
Y como toda predicción, solo espera para estar seguro.
Respuesta del año 2022: execCommand() está oficialmente obsoleto/obsoleto, pero no hay alternativa. Entonces, si debe tener soporte de texto enriquecido, debe seguir usando execCommand() y averiguar qué funciona realmente con los navegadores que desea admitir.
Tenga en cuenta que los agentes de usuario del mundo real (navegadores como Chrome, Firefox y Safari) no pueden eliminar la compatibilidad con execCommand() porque muchos servicios requieren compatibilidad. El triste estado de las cosas es que HTML5 no puede especificar ningún punto en común aquí porque los proveedores de navegadores no están de acuerdo en cómo debería funcionar execCommand() . Por lo tanto, no se puede especificar nada para HTML5, que tiene el objetivo general de especificar todas las cosas, y solo las cosas, que se necesitan para la interoperabilidad total de cualquier navegador nuevo que ingrese al mercado. Sin embargo, en mi opinión, HTML5 falla aquí porque la compatibilidad con execCommand() es realmente necesaria para que cualquier navegador nuevo ingrese al mercado, por lo que tendría sentido estandarizar al menos una de las implementaciones específicas del navegador como la oficial.
Todos los esfuerzos de estandarización actuales (Input Events 2, Clipboard API) ni siquiera intentan cubrir las funciones que execCommand() realmente hace (por ejemplo, deshacer/rehacer, cambiar el contenido dentro del rango de selección).
Esta situación ya lleva más de cinco años, así que tampoco esperes cambios rápidos.
Creé Rich Editor para fines de edición de XML (HTML5 + XHTML) de mi plataforma. No diría que document.execCommand() está completamente muerto porque algunas partes todavía funcionan bien. Desafortunadamente, el problema principal para mí fue que los navegadores usan muchos códigos diferentes para generar esos estilos que no son reconocidos por los lectores de pantalla usados por aquellos que son ciegos o casi ciegos.
Además, el error de tiempo más costoso que tuve que superar fue un error de Gecko/Presto en el que las selecciones visuales y técnicas (por qué no son lo mismo, no me pregunten) darían como resultado que parte del DOM se cambiara para que el el usuario no tenía la intención y esto se reduciría al hecho de que el recuento de píxeles por carácter es bajo, por lo que si Rich Editor no cumpliera con las selecciones visuales, el usuario se marcharía rápidamente. Eso requirió cuatro meses para conquistar y también hay otros errores.
En última instancia, es un esfuerzo difícil aunque alcanzable, aunque si tiene la intención de crear un editor HTML/XML como lo hice yo, debe planificar durante al menos seis meses si planea no solo hacerlo correctamente, sino probarlo hasta el punto de odiar el pastel solo para entonces haga que alguien venga y señale otro error.
Su enfoque principal en cuanto a JavaScript debe estar en lo siguiente:
window.createRange()window.createRange().surroundContents()Node.cloneNode()window.getSelection()window.getSelection().getRangeAt(0).commonAncestorContainerappendChildinsertBeforeinsertBefore + nextSiblingreplaceChild En lugar de un código inconsistente generado al usar execCommand() de diferentes navegadores (a menudo configurando un estilo en línea que complicaría el CSS de su sitio si no lo niega por completo), debe ceñirse al uso de los siguientes elementos sobre los que no solo puede tener control, sino que son compatibles con lectores de pantalla:
em para énfasis (o "cursiva", <i> está en desuso).strong para texto de lectura fuerte (o "negrita", <b> está en desuso).u para subrayar (asegúrese de que sus anclas tengan un estilo que se diferencie de los elementos u; u podría considerarse "obsoleto", aunque revertiré esto cuando corrija los estándares en los próximos diez años más o menos, utilícelo apropiadamente).sub para texto de sublínea que aparece verticalmente más bajo que el texto normal.sup para texto de línea superior que aparece verticalmente más alto que el texto normal.<span> para agregar específicamente estos estilos, ya que los lectores de pantalla no entenderán ni revelarán el comportamiento de errores; sigue siendo un elemento en línea genérico válido cuando se usa apropiadamente .De hecho, he tenido la intención de revisar mi editor enriquecido (ha sido parcheado, aunque aún no se ha reescrito correctamente), aunque le invitamos a ver el código fuente cuando se carga en una página de blog en el sitio vinculado en mi perfil. El proyecto original me tomó 11 meses, aunque con mi experiencia ahora creo que me tomaría entre tres y cuatro. Si habla en serio, le recomiendo que se mantenga alejado de los marcos y las bibliotecas. "Pero... pero, ¡hacen la vida más fácil!" ... hasta que quieras usar una nueva versión y tengas que reescribir todo el proyecto. Utilice JavaScript puro la primera vez y elimine el mantenimiento inútil. ¡Buena suerte!
2021-09-24: terminé reanudando el trabajo en Rich Editor II desde hace aproximadamente un año y logré convertir el código que cambiaba los estilos de 100,515 caracteres a ~ 6,000 y reduje la solicitud de archivo (ancho de banda efectivo después de la compresión) en un total tercera. Estas son las partes clave de ese éxito:
anchorNode y focusNode pueden cambiar dependiendo de si selecciona de izquierda a derecha o de derecha a izquierda. Como no pude encontrar ninguna justificación de por qué eso importaría (para mi plataforma), hice el objeto an (para anchorNode ) a la izquierda y el objeto fn (para focusNode ) siempre en el lado derecho.
Resolví el problema de Gecko/Presto usando ~1700 caracteres; primero puede encontrarlo en el sitio (visite una página que tenga un formulario enriquecido).
Para resolver el problema de seleccionar a través de numerosos intercambios por <s> , <sub> , <sup> , <u> etc. (debe probar ejemplos simples y muy intrincados) terminé usando window.getSelection().getRangeAt(0).commonAncestorContainer con cloneNode y luego, antes de procesar eso , eliminó lo que no estaba incluido en la selección. Luego simplemente usé window.getSelection().deleteFromDocument(); para eliminar la selección y reemplazarla con el nuevo elemento de estilo a través de document.createElement al que podría appendChild fácilmente la selección e insertarla en window.getSelection().getRangeAt(0).insertNode(id_('editor_rich_text').firstChild); .
Los navegadores Gecko como Waterfox, Pale Moon y Firefox, ahora completamente destruido, le permiten seleccionar múltiples instancias de texto. Para hacerlo, simplemente mantenga presionada la tecla Control para crear selecciones adicionales. Dado que realmente no ayuda de ninguna manera significativa (y estas cosas ya son lo suficientemente complicadas), no hice todo lo posible para apoyarlo en este momento.
Estaré actualizando mi plataforma hoy o este fin de semana (a partir de la edición de esta publicación) para reflejar los nuevos cambios. Mantengo gran parte del código anterior debido a numerosos problemas con los navegadores Gecko. He ampliado la funcionalidad y resuelto numerosos errores y no tuve que recurrir a ningún truco y, como de costumbre, no tuve garaje (marcos o bibliotecas).
2021-09-26: Para aquellos interesados en la funcionalidad de rehacer/deshacer, tendrán que recurrir básicamente a mantener versiones de texto de la parte del DOM que está editando. Claro, podría haber otras formas de implementarlo, aunque serían muy complicadas. Básicamente, solo hace una copia del elemento principal del editor usando .cloneNode y luego, mientras está en la memoria, usa algo como while (e.firstChild) {xml += new XMLSerializer().serializeToString(e.firstChild);} . Dado que lo almacenará como texto, no tendrá las enormes implicaciones de memoria que tiene el DOM. Literalmente, reemplazará todo el DOM en el editor y realizará un seguimiento de cada iteración de un cambio, por lo que seguirá siendo un proyecto considerable. Para mi plataforma no es necesario en este momento, aunque quería cubrir esto, ya que algunas personas lo mencionaron en los comentarios.
La alternativa a document.execCommand() es la API del portapapeles, a través de navigator.clipboard . Según MDN Web Docs ( https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API ):
Esta API está diseñada para reemplazar el acceso al portapapeles mediante document.execCommand().
EDITAR: Como se menciona en el comentario, así como en el texto citado anteriormente, esto solo cumple con un subconjunto de los requisitos (acceso al portapapeles).