Error de JavaScript cuando quiero añadir relleno
Me he estado encontrando con el mismo problema y también uso el plugin 'grapesjs-mjml'. Aparentemente solo ocurre cuando se carga un proyecto que tiene la propiedad 'style' presente en los 'atributos' de un componente cuando el proyecto está cargado. Tras cada cambio realizado en el editor, la propiedad 'style' se ext...
Lee la respuesta completa abajo ↓Pregunta
Versión GrapesJS
- Confirmo que uso la última versión de GrapesJS
¿Qué navegador usas?
Chrome y Firefox
Enlace de demo reproducible
Describe el bicho
¿Cómo reproducir el bicho? Chrome y Firefox:
- Añadir relleno a una imagen / texto
- A veces ocurre el error, a veces no.
https://github.com/user-attachments/assets/01270f08-974d-4898-bde0-83233f9258e0
¿Cuál es el comportamiento actual? Chrome El error se ve así: Uncaught InvalidCharacterError: No se ejecutó 'setAttribute' en 'Element': '0' no es un nombre de atributo válido.
Así es como se ve el texto antes de añadir relleno. '''mjml <mj-text> <span style="color:rgb(235, 105, 40);font-family:Verdana, Arial, Helvetica, sans-serif;font-size:25px;letter-spacing:0px;margin:0px 0px 0px -2px;">Diciembre 2025 - Boletín del Club</span> </mj-text>
Así es como queda el texto después de añadir relleno.
'''mjml
<mj-text 0="tamaño-fuente:30px" 1="tamaño-fuente:30px" __p="verdadero">
<span style="color:rgb(235, 105, 40);font-family:Verdana, Arial, Helvetica, sans-serif;font-size:25px;letter-spacing:0px;margin:0px 0px 0px -2px;">Diciembre 2025 - Boletín del Club</span>
</mj-text>
Cuando lo pruebo con una versión antigua (0.22.2), funciona. Con la última versión, se produce este error.
Firefox DOMException no capturado: La cadena contiene un carácter inválido attr /lib/grapejs.min.js?v=0.22.13:2 cada /lib/grapejs.min.js?v=0.22.13:2 S /lib/grapejs.min.js?v=0.22.13:2 cada /lib/grapejs.min.js?v=0.22.13:2 attr /lib/grapejs.min.js?v=0.22.13:2 attr /lib/grapejs.min.js?v=0.22.13:2 updateAttributes /lib/grapejs.min.js?v=0.22.13:2
Si es necesario ejecutar algo de código para reproducir el error, pégalo aquí abajo: Así es como guardo los datos
'''js Almacenamiento en línea const inlineStorage = (editor) => { const projectDataEl = document.getElementById('project-data'); const projectHtmlEl = document.getElementById('project-html');
editor. Storage.add('inline', { load() { return JSON.parse(projectDataEl.value || '{}'); }, store(data) { const mjmlCode = editor.getHtml(); const htmlResult = editor. Commands.get('mjml-code-to-html').run(editor, { mjml: mjmlCode });
projectDataEl.value = JSON.stringify(data); projectHtmlEl.value = htmlResult.html; }, }); };
Quizá esta información te ayude:
Exporto los datos JSON almacenados en "projectDataEl.value" en load() para un proyecto que funciona y uno que no funciona. El JSON de la izquierda es el del proyecto que no funciona, y el de la derecha es el del proyecto en funcionamiento.
<img width="1200" height="925" alt="Image" src="https://github.com/user-attachments/assets/867e7e14-c38d-4b26-9155-a62eee14e8ed" />
### Código de conducta
- [x] Acepto seguir el Código de Conducta de este proyecto
Respuestas (3)
Me he estado encontrando con el mismo problema y también uso el plugin 'grapesjs-mjml'. Aparentemente solo ocurre cuando se carga un proyecto que tiene la propiedad 'style' presente en los 'atributos' de un componente cuando el proyecto está cargado. Tras cada cambio realizado en el editor, la propiedad 'style' se extenderá añadiendo el valor 'viejo' al valor más reciente, haciendo crecer exponencialmente el JSON del proyecto.
Probé a probar diferentes versiones de grapesjs, empezando por la versión '0.22.2' hacia arriba. Al llegar a la versión '0.22.6' empezó a aparecer el problema, así que en algún momento entre la versión '0.22.5' y la '0.22.6' debió de haber sido introducido el fallo. En todas las versiones anteriores todo funciona como se espera.
Para reproducir el problema, simplemente a lo siguiente:
- Crear un nuevo proyecto y añadir algunos componentes
- Generar el JSON del proyecto llamando a 'editor.getProjectData()'
- Carga el proyecto en el editor llamando a 'editor.loadProjectData()'
- Con o sin modificación de uno o más componentes, generar los datos del proyecto de nuevo usando 'editor.getProjectData()'
Tras ejecutar el 'paso 4', el JSON del proyecto acaba con los atributos incorrectos. Esto, a su vez, puede causar el problema que mencionó el OP.
Por favor, revisa el fragmento a continuación que se generó tras cargar un JSON del proyecto y recuperar los datos del proyecto de inmediato, sin realizar ninguna modificación.
'''json "componentes": [ { "etiquetaNombre": "mj-image", "tipo": "mj-image", "estilo": { "src": "resources/c-exp/C8D02998273D07256CCA/maileditor/assets/UxlhZLikRdyXoBDZnfIoHg", "acolchado": "10px", "acolchado-bottom": "10px", "relleno-derecha": "25px", "relleno-izquierda": "25px", "alinear": "centro", "ancho": "250px", "style": "src:resources/c-exp/C8D02998273D07256CCA/maileditor/assets/UxlhZLikRdyXoBDZnfIoHg; Acolchado: 10px; relleno-abajo: 10px; relleno-derecha: 25px; relleno-izquierda: 25px; alinear:centro; ancho:250px;" }, "atributos": { "src": "resources/c-exp/C8D02998273D07256CCA/maileditor/assets/UxlhZLikRdyXoBDZnfIoHg", "acolchado": "10px", "acolchado-bottom": "10px", "relleno-derecha": "25px", "relleno-izquierda": "25px", "alinear": "centro", "ancho": "250px", "style": "src:resources/c-exp/C8D02998273D07256CCA/maileditor/assets/UxlhZLikRdyXoBDZnfIoHg; Acolchado: 10px; relleno-abajo: 10px; relleno-derecha: 25px; relleno-izquierda: 25px; alinear:centro; ancho:250px; style:src:resources/c-exp/C8D02998273D07256CCA/maileditor/assets/UxlhZLikRdyXoBDZnfIoHg; Acolchado: 10px; relleno-abajo: 10px; relleno-derecha: 25px; relleno-izquierda: 25px; alinear:centro; ancho:250px;;" }
El JSON cargado del proyecto contenía lo siguiente para el mismo componente:
'''json
"componentes": [
{
"etiquetaNombre": "mj-image",
"tipo": "mj-image",
"estilo": {
"src": "resources/c-exp/C8D02998273D07256CCA/nl/maileditor/assets/UxlhZLikRdyXoBDZnfIoHg",
"acolchado": "10px",
"acolchado-bottom": "10px",
"relleno-derecha": "25px",
"relleno-izquierda": "25px",
"alinear": "centro",
"ancho": "250px"
},
"atributos": {
"src": "resources/c-exp/C8D02998273D07256CCA/nl/maileditor/assets/UxlhZLikRdyXoBDZnfIoHg",
"acolchado": "10px",
"acolchado-bottom": "10px",
"relleno-derecha": "25px",
"relleno-izquierda": "25px",
"alinear": "centro",
"ancho": "250px",
"style": "src:resources/c-exp/C8D02998273D07256CCA/nl/maileditor/assets/UxlhZLikRdyXoBDZnfIoHg; Acolchado: 10px; relleno-abajo: 10px; relleno-derecha: 25px; relleno-izquierda: 25px; alinear:centro; ancho:250px;"
}
}
]
Desafortunadamente, no he conseguido averiguar qué commit en la versión '0.22.6' causaba el problema. Así que si alguien pudiera ayudarme, se lo agradecería mucho.
Reducir a '0.22.5' parece ser la única opción por ahora.
Desafortunadamente, no he conseguido averiguar dónde ni cuándo exactamente se añade la propiedad 'style' al componente 'style' al exportar datos de un proyecto previamente cargado. Quizá alguien más pueda identificar qué causa el problema.
@soul-media: para que conste, parchear el método 'init' en los componentes 'mjml' como solución temporal parece funcionar y evita que la propiedad 'style' se añada en la exportación de los datos del proyecto (incluso después de cargar un proyecto guardado previamente). Esto parece funcionar incluso para la versión '0.22.14', y la salida JSON será como la que aparece a la derecha de tu captura de pantalla.
Para parchear la función, utiliza la opción 'customComponents' de los plugins 'grapesjs-mjml' para registrar una función que obtenga acceso a la función 'coreMjmlModel.init'. Para cada componente cuya función 'init' sea igual a la del 'coreMjmlModel', asigna la función parcheada (esto solo modificará los componentes que tengan una función 'init' presente). En la función parcheada, la propiedad 'style' se elimina antes de que los atributos se pasen a 'this.set('style', ...)'llamar, que parece solucionar el problema.
'''javascript var editor = grapesjs.init({ Offsets: 1, avisoOnUnload: 0, Contenedor: '#gjs', Altura: '100%', fromElement: cierto, storageManager: false, Plugins: ['Grapesjs-MJML'], pluginsOpts: { 'grapesjs-mjml': { customComponents: [ Parches: https://github.com/GrapesJS/grapesjs/issues/6646 (editor, { coreMjmlModel }) => { function patchedMjmlInit() { const attrs = { ... this.get('atributos') }; Estilo const = { ... this.get('style-default'), ... this.get('style') };
para (let prop in style) { si (!( prop en los atractivos)) { attrs[prop] = style[prop]; } }
this.set('attributes', attrs);
Elimina el atributo 'style' antes de pasar a this.set('style') Esto debería evitar errores aleatorios tras cargar un proyecto existente const attrsNoStyle = { ... attrs }; eliminar attrsNoStyle.style;
this.set ('estilo', atrasNoEstilo);
this.listenTo(this, 'change:style', this.handleStyleChange); this.listenTo(this, 'change:attributes', this.handleAttributeChange); }
editor. DomComponents.getTypes().forEach((type) => { const compType = editor. DomComponents.getType(type.id); if (compType.model.prototype.init === coreMjmlModel.init) { compType.model.prototype.init = patchedMjmlInit; } }); }, ], }, }, });
Gracias por informar de esto, @soul-media.
Buena pregunta sobre error de Javascript cuando quiero añadir relleno. El enfoque recomendado con StyleManager es usar la API orientada a eventos.
Empieza aquí:
- Consulta la documentación de GrapesJS de tu módulo específico
- Busca el método del oyente de eventos 'on()'
- La mayoría de las operaciones se pueden realizar escuchando eventos del editor y de los componentes
Patrones comunes: '''javascript Prestad atención a los cambios editor.on('Change', () => console.log('Something Changed'));
Ciclo de vida de los componentes editor.on('component:mount', (c) => console.log('component ready', c)); editor.on('component:update', (c) => console.log('component updated', c));
**Si sigues atascado:**
- Compartir una reproducción mínima de CodeSandbox
- Incluye lo que ya has probado
- Menciona tu versión GrapesJS
- ¡La comunidad está aquí para ayudar!
Preguntas y respuestas relacionadas
Continúa investigando con debates sobre temas similares.
Issue #5677
Versión GrapesJS [X] Confirmo que se debe usar la última versión de GrapesJS ¿Qué navegador usas? Chrome Enlace de demo reproducible https:...
Issue #6549
No se pudo redimensionar la imagen
Versión GrapesJS [x] Confirmo que uso la última versión de GrapesJS ¿Qué navegador usas? Chrome Enlace de demo reproducible https://codepen...
Issue #4191
Estamos intentando almacenar los datos del editor grapesJS en la aplicación Angular 10, obteniendo un error CORS, imagen adjunta abajo
Versión GrapesJS [x] Confirmo que uso la última versión de GrapesJS ¿Qué navegador usas? Chrome 99.0.4844.5 Enlace de demo reproducible htt...
Issue #5232
Trabajador - Sin interfaz de texto "documento no está definido"
Versión GrapesJS [X] Confirmo que se debe usar la última versión de GrapesJS ¿Qué navegador usas? 114.0.5735.133 Enlace de demo reproducibl...
Plugins de pago que cumplen con este problema
Seleccionado por temas clave y relevancia de etiquetas para ayudarte a enviar más rápido.
Cargando recomendaciones de plugins de pago...
Consulta los plugins de código abierto de GrapesJS en GitHub O haz una búsqueda rápida en nuestro catálogo gratuito.
Explora plugins gratuitos →Los plugins premium incluyen soporte, actualizaciones regulares y funciones listas para producción — ahorrando días de trabajo de integración.
Explora plugins premium →Tutoriales relacionados
Guías detalladas sobre el mismo tema.
Tutorial
How to Build a Production GrapesJS Editor: The Complete Walkthrough of Brief, Preset, Plugins, and Services
A complete walkthrough of building a production GrapesJS editor: how to choose a preset, pick plugins, and scope setup services without burning a sprint.
Tutorial
Big Updates: TinyMCE 8 and Placeholder 2.0 for GrapesJS
In May we shipped major updates to two of our most popular GrapesJS plugins — TinyMCE Inline Text Editor and Placeholder.
Tutorial
Find the Right GrapesJS Plugin in Seconds: Smarter Discovery Is Live
We're shipping a set of discovery upgrades. New label filters, a proper compatibility switch for GrapesJS vs Studio, one-click and a smarter sort bar.
Explorar categorías de plugins
Ve directamente a las páginas de categorías de plugins en el marketplace.