Tengo muchas tablas, en diferentes pestañas, con un enlace de " Actions " para cada fila. Al hacer clic en " Actions " se abre un menú desplegable, y funciona como debería hacerlo un menú desplegable: al hacer clic en el exterior se cierra el menú desplegable, al hacer clic en el interior se mantiene abierto el menú desplegable. Hasta ahora todo bien, una versión simplificada está aquí https://jsfiddle.net/ivanhalen/nya69pd2/30/
La parte relevante de JS es esta:
$('.show_actions').on('click', function(){ var el = $(this); el.closest('tbody').find('.actions').hide(); el.closest('td').find('.actions').show(); }); $(document).on('mouseup', function(e){ var el = $(document).find('.actions').off('click'); if (!el.is(e.target) && el.has(e.target).length === 0) { el.hide(); } });Ahora otro actor entra en escena.
En otras pestañas tengo algunos divs editables por contenido. Al hacer clic en ellos, se llama a una instancia de CKEditor y se abre un menú desplegable personalizado (yo llamo "paleta") con cosas de CKE: botones, campos, etc.
Bueno, aquí debería pasar lo mismo: al hacer clic fuera de la "paleta" debería cerrarse (y destruir la instancia de CKEditor), al hacer clic dentro debería mantenerse abierto
El código que escribí no funciona bien y lucho por encontrar una solución que funcione: aquí hay un violín: https://jsfiddle.net/ivanhalen/nya69pd2/32/
El código relevante es:
$('.show_actions').on('click', function(){ var el = $(this); el.closest('tbody').find('.actions').hide(); el.closest('td').find('.actions').show(); $(document).find('.palette').hide(); }); $('.editor').on('click', function(){ var el = $(this); $(document).find('.actions').hide(); el.closest('.editor_container').find('.palette').show(); // here call a function to instantiate CKeditor }); $(document).on('mouseup', function(e){ var el = $(document).find('.actions, .palette').off('click'); if (!el.is(e.target) && el.has(e.target).length === 0) { el.hide(); if (el.hasClass('palette')){ console.log('here destroy CKeditor instance too'); } } }); El 'here destroy CKeditor instance too' siempre se activa, incluso haciendo clic en content-editable-div donde debería crear en su lugar
Por favor, ¿alguna ayuda?
Me parece que hay alguna trampa sutil en tu lógica.
Como asignas el así:
var el = $(document).find('.actions, .palette').off('click'); entonces esta comprobación if() siempre será verdadera :
if (el.hasClass('palette')){ console.log('here destroy CKeditor instance too'); } Además, no puedo averiguar si su if() anidado dentro del evento mouseup hará el trabajo correctamente.
Traté de cambiar un poco el código del evento mouseup y me parece, si entendí bien tu objetivo, que hace el trabajo:
$(document).on("mouseup", function (e) { var el = $(document).find(".actions, .palette").off("click"); // first if() check to close the dropdowns if (!el.is(e.target) && el.has(e.target).length === 0) { el.hide(); } // separate if() check, to decide if destroy the instance // check if my target is NOT the editor if (!$(e.target).hasClass("editor")) { console.log("here destroy CKeditor instance too"); } });