2010-01-19 12 views
5

Estoy trabajando con IE7 y algunos cuadros de diálogo de jQuery y me estoy encontrando con una fuga de 6 megas por cuadro de diálogo abierto. Supongo que tiene que ver con cierres, pero hasta ahora todo lo que he hecho para eliminarlos no ha ayudado. En este punto, creo que me he ocupado de todos los cierres, excepto en el caso de una función de devolución de llamada que paso, pero sigue goteando 6 megas incluso después de que se cierra y elimina el diálogo. El código fuente pertinente es:jQuery-UI Dialog Memory Leaks

function DialogDestroyAndRemove(event) { 
    $(event.target).dialog("destroy").remove(); 
} 

function CallbackAndCloseDialog(event) { 
    if (event.data.callback != undefined) { 
     event.data.callback(event.data.callbackResponse); 
    } 
    $("#" + event.data.dialogId).unbind('dialogbeforeclose').dialog('close'); 
} 

// alert dialog modal with ok button 
function AlertDialog(dialogTitle, dialogText, callbackFunction) { 
    // dynamically generate and add a div so we can create the pop-up 
    $('body').append("<div id=\"alertDialog\" style=\"display:none;\" title=\"" + dialogTitle + "\">" + dialogText + "</div>"); 

    // define/configure the modal pop-up 
    $("#alertDialog").dialog({ 
     draggable: false, 
     resizable: false, 
     modal: true, 
     autoOpen: true, 
     open: function() { 
      $("#alertDialog").parents('.ui-dialog-buttonpane button:eq(0)') 
      .focus() //focus so the button is highlighted by default 
      .bind('click', { 
       callback: callbackFunction, 
       callbackResponse: 'OK', 
       dialogId: 'alertDialog' 
      }, CallbackAndCloseDialog); 
     }, 
     overlay: { backgroundColor: '#000', opacity: 0.5 }, 
     buttons: { 'OK': function() { } } 
    }).bind('dialogbeforeclose', function(event, ui) { 
     // Close (X) button was clicked; NOT the OK button 
     if (callbackFunction != undefined) { 
      callbackFunction('cancel'); 
     } 
     callbackFunction = null; 
    }).bind('dialogclose', DialogDestroyAndRemove); 
} 

Una cosa que hice anteriormente que no estoy seguro de si se necesitaba era en lugar de definir la devolución de llamada para el botón Aceptar cuando se define (y por lo tanto tiene un cierre, ya que es referencia a la devolución de llamada) para definirlo usando un .bind una vez que el diálogo está abierto. Esperaba que poder pasar la devolución de llamada como parte de los datos al evento de clic podría ayudar a eliminar el cierre.

¿Alguna idea de qué más puedo cambiar para eliminar esta fuga?

Respuesta

5

En realidad, fue causado por la forma en que el marco de la interfaz de usuario de jQuery trata de encapsular el fondo cuando se muestra un modal. Si elimino los atributos modal = true y overlay, la pérdida de memoria se reduce a ~ 100k.

Para evitar esto tuve que hacer el diálogo sin la opción modal, y luego agregar un div a la página (posición fija arriba, izquierda, abajo, derecha todos 0 con un píxel gris alterno y luego fondo de píxeles transparentes) y mostrando y escondiendo eso con un zindex justo debajo del diálogo.

Si bien no es ideal (la superposición modal predeterminada era agradable y de aspecto uniforme) es mejor que perder tanta memoria por cada diálogo que aparezca.

+1

Esto tiene que ver con cómo IE maneja la transparencia PNG, que es ... horriblemente. Si elige un filtro IE de color simple en lugar de una imagen, puede obtener algún efecto sin el golpe de memoria. En su jQuery.UI.css cambie la clase '.ui-widget-overlay' y elimine everythig de' url ('forward en la declaración' background: ', esto dará como resultado una superposición translúcida de un solo color. –

+0

Parece estar con cómo IE se ocupa de la transparencia en general. Eliminé el aspecto URL del fondo (dejando solo el color sólido) y aún lo hizo. No fue hasta que eliminé el filtro de opacidad que se fue. – Parrots

+0

En realidad, quitando modal: true de mi cuadro de diálogo se cortó el uso de la memoria IE 8 en un medio (de 150 MB a 70). – daschl

1

Espero que esto ayude, he creado una extensión para este problema donde utilizo las herramientas jQuery (flowplayer) expongo el plugin cuando modal = true para el diálogo de jQuery UI.

Incluiría el código siguiente: //jsfiddle.net/yZ56q/lowing en un archivo .js separado y asegúrese de incluir las herramientas jQuery exponer el complemento anterior, desde este sitio ... http://flowplayer.org/tools/download.html.

(function($) { 
    var _init = $.ui.dialog.prototype._init; 
    $.ui.dialog.prototype._init = function() { 
     var self = this; 
     _init.apply(this, arguments); 

     // Remove the default modal behavior and exhibit the new one 
     if (self.options.modal) { 
      self.options.modal = false; 
      self.options.isModal = true; 
     } 

     this.uiDialog.bind('dialogopen', function(event, ui) { 
      if (self.options.isModal) { 
       if ($(this).expose == null) 
        window.alert("Dialog box depends on the expose plugin to be modal. Please include the jquery tools Javascript include."); 
       else { 
        $(this).expose({ opacity: 0.3 
          , color: '#CCCCCC' 
          , loadSpeed: 0 
          , closeSpeed: 0 
          , closeOnClick: false 
          , closeOnEsc: false 
          , api: true 
        }).load(); 
       } 
      } 
     }); 

     this.uiDialog.bind('dialogfocus', function(event, ui) { 
      if (self.options.isModal) { 
       $(this).css('z-index', '9999'); 
      } 
     }); 

     this.uiDialog.bind('dialogclose', function(event, ui) { 
      if (self.options.isModal) { 
       if ($(this).expose != null) { 
        $(this).expose({ api: true }).close(); 
       } 
      } 
     }); 
    }; 

     $.ui.dialog.defaults.isModal = false; 
})(jQuery);