Custom DomComponent & Block permite duplicar todos los elementos
@JulyanoF nunca deberías hacer esto, 'editor. DomComponents.render()' si sientes que necesitas esa función, probablemente estés haciendo algo mal... luego, en tu componente personalizado, no configuras el método 'isComponent', así que revisa esta guía: https://grapesjs.com/docs/modules/Components.html Para el resto, h...
Lee la respuesta completa abajo ↓Pregunta
He creado un bloque personalizado:
bm.add('imagemLink', {
etiqueta: 'Imagem Link',
Contenido: {
activeOnRender: 1,
Droppable: falso,
tipo: 'imagemLink',
Contenido: '<un título="" enlace=""><img src="img/model.png"></img></a>'
}
});
y un DomComponent Personalizado:
domComps.addType('imagemLink', {
Defina el modelo
model: defaultType.model.extend({
Predeterminados: {
etiquetaNombre: "div",
tipo: "",
Nombre: "",
removible: !0,
arrastrable: !0,
Droppable: !0,
Badgable: !0,
estilizado: !0,
"stylable-require": "",
no estilizado: "",
resaltable: !0,
copiable: 0,
redimensionable: !1,
Editable: !0,
capas: !0,
seleccionable: !0,
hoverable: !0,
vacío: !1,
Declara: "",
Estado: "",
Contenido: "",
icono: "",
estilo: "",
Atributos: "",
Clases: "",
guion: "",
Rasgos: ["Id", "Título"],
propagar: "",
barra de herramientas: null
},
}),
view: defaultType.view.extend({
eventos: {
'click': función(){
var openSmBtn = editor. Panels.getButton('vistas', 'optionsBlock');
openSmBtn.set('active', 1);
},
'dblclick': función(){
editor.select (este.modelo);
selecionado = this.model;
editor.runCommand("open-assets", {
onSelect: función (t) {
var newSrc = t.attributes.src;
conteudoImagemLink = $(editor.getSelected().toHTML());
var elConteudoImagem = $($(conteudoImagemLink[0]).children('a')).children('img');
$(elConteudoImagem)[0].src = newSrc;
editor.getSelected().set('content', conteudoImagemLink[0].innerHTML);
editor. DomComponents.render();
editor.select(null);
selecionado = null;
editor. Modal.close(), editor. AssetManager.setTarget(null);
}
});
},
'mouseenter': function(){
if(!selecionado){
editor.select (este.modelo);
var openSmBtn = editor. Panels.getButton ('vistas', 'bloques abiertos');
openSmBtn.set('active', 1);
}
},
'mouseleave': function(){
if(!selecionado){
editor.select(null);
var openSmBtn = editor. Panels.getButton ('vistas', 'bloques abiertos');
openSmBtn.set('active', 1);
}else{
editor.select(selecionado)
}
}
},
})
});
Y un comando personalizado (he encontrado donde ocurre el error):
editor. Commands.add('opcoesBloco', {
run: function(editor, sender){
const bm = editor. Jefe de bloque;
const pn = editor. Paneles;
var selectedBlock = editor.getSelected();
id de const = 'contenedor de vistas';
const mkeditorCustom = document.createElement('div');
const panels = pn.getPanel(id) || pn.addPanel({ id });
if(selectedBlock){
if(blocoSelecionado.attributes.type == "imagemLink"){
const divTotal = document.createElement('div');
divTotal.NombreclaseT= 'col-md-12';
const divUm = document.createElement('div');
divUm.NombreclaseNombre = 'col-md-4';
const divDois = document.createElement('div');
divDois.className = 'col-md-8';
var elLink = $(blocoSelecionado.attributes.content);
var elImagem = $(elLink).children('img');
var nomeArquivo = elImagem[0].src.split('/').slice(-1)[0];
const arquivo = document.createElement('span');
arquivo.innerHTML = nomeArquivo;
archivo.style = 'display: block; color: #000000';
const tamanho = document.createElement('span');
tamanho.style = 'visualización: bloqueo; color: #000000; Tamaño de fuente: 11px';
const imagem = document.createElement('img');
imagem.src = elImagem[0].src;
imagem.style = 'ancho máximo: 100%';
tamanho.innerHTML = imagem.naturalWidth + ' x ' + imagem.naturalHeight;
const botao = document.createElement('a');
botao.style = "margen-arriba:10px; color: #848080; cursor: puntero; Decoración de texto: subrayado; tamaño de fuente: 15px;";
botao.innerHTML = "Cambiar imagen";
conteudoImagemLink = $(blocoSelecionado.toHTML());
botao.onclick = function(){
editor.runCommand("open-assets", {
onSelect: función (t) {
var newSrc = t.attributes.src;
$($(divUm).children('img')[0])[0].src = newSrc;
var nomeNovaImagem = newSrc.split('/').slice(-1)[0];
$(divDois).children('span')[0].innerHTML = nomeNovaImagem;
var elConteudoImagem = $($(conteudoImagemLink[0]).children('a')).children('img');
$(elConteudoImagem)[0].src = newSrc;
ERROR AQUÍ ********************************
blocoSelecionado.set('content', conteudoImagemLink[0].innerHTML);
editor. DomComponents.render();
editor. Modal.close(), editor. AssetManager.setTarget(null)
}
});
};
mkeditorCustom.style = "margen-top: 30px; alineación de texto: izquierda; relleno-izquierda: 20px";
divUm.appendChild(imagen);
divDois.appendChild(archivo);
divDois.appendChild(tamaño);
divDois.appendChild(botao);
mkeditorCustom.appendChild(divUm);
mkeditorCustom.appendChild(divDois);
panels.set('appendContent', mkeditorCustom).trigger('change:appendContent');
this.mkeditorCustom = mkeditorCustom;
}else{
mkeditorCustom.append(editor. TraitManager.getTraitsViewer().el);
panels.set('appendContent', mkeditorCustom).trigger('change:appendContent');
this.mkeditorCustom = mkeditorCustom;
}
}
this.mkeditorCustom.style.display = 'bloque';
},
stop: function(editor, sender){
if(tinymce.editors.length > 0) tinymce.remove("#ckeditor");
const mkeditorCustom = this.mkeditorCustom;
mkeditorCustom & & (mkeditorCustom.style.display = 'ninguno');
}
});
Cuando establezco el nuevo enlace para la imagen hija, cualquier bloque que añado al editor se suma dos veces, y cuando selecciono este bloque duplicado, ambos se seleccionan y cambian: ! imagen
Respuestas (3)
@JulyanoF nunca deberías hacer esto, 'editor. DomComponents.render()' si sientes que necesitas esa función, probablemente estés haciendo algo mal... luego, en tu componente personalizado, no configuras el método 'isComponent', así que revisa esta guía: https://grapesjs.com/docs/modules/Components.html Para el resto, haz una demostración en directo con el número
estoy intentando obtener el html del elemento seleccionado (editor.getSelected().toHTML()), manipularlo y cambiar el contenido original
Esto está mal... Deberías usar API de Component, no toques la vista o, peor aún, es HTML. Si no entiendes este concepto (deberías EDITAR el MODELO del componente, no su VISTA) te enfrentarás a muchos problemas
@artf tienes razón. El problema es usar la función 'render()', es decir, duplicar los elementos... pero, si elimino esta función, el HTML del editor no cambia... Sigue mostrando contenido antiguo y no el nuevo. ¿Cómo puedo evitarlo? Proporcionaré una demo en directo
Preguntas y respuestas relacionadas
Continúa investigando con debates sobre temas similares.
Issue #852
[PREGUNTA] ¿Cómo cambiar <a> el contenido de los rasgos?
Estoy reafirmando un tipo de enlace así: Cuando se crea mi botón ('<a>'), se crea así: '<a class="btn botao-roxo">Botão</a>' Me gustaría sa...
Issue #1702
[Pregunta]Cómo obtener selección de RTE dentro de la función de resultados
Básicamente intento poner un campo de entrada dentro del RTE para que los usuarios puedan hacer enlaces más fácilmente. console.log('<a hre...
Issue #1819
[Pregunta]: Bloquear atributos de contenido (ngModel en mi caso) forzados a minúsculas
Estoy intentando usar la directiva angular. En cualquiera de los contenidos de bloque, por ejemplo ' bm.add('radio-block',{ etiqueta: 'Elem...
Issue #1572
Problema al añadir bloque de vídeo manualmente
Añadí Video Block manualmente así. <pre> blockManager.add('video', { etiqueta: 'Vídeo', categoría: 'Medios', Atributos: {clase: 'FA FA-YouT...
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.
Explorar categorías de plugins
Ve directamente a las páginas de categorías de plugins en el marketplace.