Manejo de la colisión de componentes de jQuery

4

En el desarrollo de complementos, ¿cuál es la mejor práctica para evitar la colisión de componentes jQuery en la parte frontal?

Por ejemplo, digamos que incluyo el cuadro de diálogo jQuery Apprise en un complemento que carga esto en la parte frontal para algo, pero otro complemento puede hacer lo mismo. Debido a que esto se carga y declara dos veces, o tal vez uno se bifurca y se personaliza mientras que el mío no lo está, obtenemos errores de Javascript en la interfaz (supongo).

(Tenga en cuenta que estoy haciendo la mejor práctica de usar la estrategia wp_register_script () y wp_enqueue_script () a través de un evento de acción wp_head () para cargar un componente jQuery en la interfaz).

    
pregunta Volomike 14.04.2012 - 18:45

3 respuestas

1

Mi sugerencia sería utilizar una combinación de aislamiento de código en una función anónima y verificar si jquery ya está presente.

Aquí hay un ejemplo:

(function() {

var jQuery;  // your jquery variable

// check if jquery is present and if it has the version you want
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.8.3') {

    // load jquery lib from google hosted libraries
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type","text/javascript");
    script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js");

    // wait for jquery lib to load
    if (script_tag.readyState) {
      script_tag.onreadystatechange = function () { // old versions of IE
          if (this.readyState == 'complete' || this.readyState == 'loaded') {
              jqueryLoadHandler();
          }
      };
    } else { // for other browsers
      script_tag.onload = jqueryLoadHandler;
    }

    // Try to find the head, otherwise default to the documentElement
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);

} else {

    // The current site is already using the jquery you want, so just point your variable to that jquery
    jQuery = window.jQuery;
    main();
}

// as soons as jquery is loaded
function jqueryLoadHandler() {
    // Restore $ and window.jQuery to their previous values and store the
    // new jQuery in our local jQuery variable
    jQuery = window.jQuery.noConflict(true);

    // Call plugin main function
    main(); 
}

// plugin main function
function main() { 
    jQuery(document).ready(function($) { 
        // Here you can use the $ without any problems
    });
}

})(); // We call our anonymous function immediately

De esta manera puede usar jQuery sin problemas en su complemento, incluso si otros complementos utilizan jquery sin wp_enqueue_script. Cada variable y función que use dentro de esta función anónima no interferirá con el resto de la página.

Tal vez esto podría funcionar incluso mejor si se integrara con wp_enqueue_script.

Puede leer más sobre este enfoque de cargar jquery dentro de una función anónima en enlace

    
respondido por el dbeja 14.12.2012 - 14:02
1

La mejor práctica para poner en cola o registrar scripts es utilizar wp_register_script y wp_enqueue_script . Los complementos y temas que no utilizan estas funciones para agregar sus scripts, no deben usarse.

El motivo es simple: con wp_register_script() podemos recuperar una gran cantidad de información sobre los scripts registrados. Especialmente si una fuente dada ya está registrada o no.

Escribí una clase simple para comprobar si una fuente ya está registrada. La clase puede desregistrar el script y registrar el nuevo script u omitir el nuevo script. Esta clase debe ser un punto de partida para su propio desarrollo. Es no para el entorno de producción!

¿Cómo funciona la clase?

La clase recupera una matriz con los scripts que deben registrarse. A continuación, compare los nombres de archivo (y solo los nombres de archivo) de cada script registrado con los nombres de archivo de los scripts que deben registrarse. Si el script / nombre de archivo aún no está registrado, su identificador se agregará a una matriz y se registrará en un momento posterior.

La clase se puede ampliar para comparar la ruta completa del script o la versión o lo que sea necesario para decidir si el script debe registrarse o no.

Un ejemplo simple

    $my_scripts = array(

            'foo' => array(
                    'src' => 'external/ressource/foo.js',
                    'deps' => array( 'jquery' ),
                    'version' => false,
                    'in_footer' => true
                    ),

            'bar' => array(
                    'src' => home_url( '/wp-admin/js/common.min.js' ),
                    'deps' => false,
                    'version' => false,
                    'in_footer' => true
                    ),

            'jquery' => array(
                    'src' => '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js',
                    'deps' => false,
                    'version' => '1.8.3',
                    'in_footer' => true
                    ),

    );

    $safe_register = new Safe_Registering_Scripts( $my_scripts, true );

    global $wp_scripts;

    var_dump( $wp_scripts->registered['jquery'] );

Al principio definimos una matriz con todos nuestros scripts para registrar. La clase recorrerá nuestros scripts y los comparará si la fuente ya está registrada.

  • el script foo siempre se registrará porque la fuente no está registrada.
  • el script bar nunca se registrará porque su fuente ya está registrada.
  • el script jquery es un caso especial. Ya existe un identificador llamado jquery pero el segundo parámetro en la llamada de clase dice que esta fuente de script debe reemplazarse con la nueva fuente.

Como puede ver en el var_dump() , la fuente del script jquery fue reemplazada por la clase. Entonces, si extiende la clase y ajusta la prueba (fuente, nombre de archivo js, versión, secuencias de comandos en cola, etc.), podría ayudar a minimizar las colisiones de js.

    
respondido por el Ralf912 16.12.2012 - 23:38
1

El problema con jQuery core es muy común y muchos complementos tienen muchas formas de evitarlo.

Cuando hablamos de complementos para jQuery hay otro problema, pero puedes eliminarlo de forma similar.

En su situación, prefiero una solución común para agregar include switch en la página de configuración de su complemento. Creo que esto es muy popular para los complementos con jQuery core, pero también puede usarlo para los complementos de jQuery.

Otra solución es escribir un script en js para verificar si está definido el método jQuery extra (desde el complemento), cuando no lo está, puede incluir el complemento en su script. Esta solución solo funcionará si agrega un gancho para scripts con una prioridad muy baja. Se ejecutará después de otros complementos y esta condición funcionará.

    
respondido por el Maciej Płusa 16.12.2012 - 16:35

Lea otras preguntas en las etiquetas