2011-09-10 45 views
7

Mi bookmarklet consiste en una llamada a un script 'launcher' que se inserta en body. A medida que se ejecuta, inserta de manera similar más scripts (jQuery, la aplicación real) y un CSS.¿Cómo hacer que un bookmarklet se ejecute solo una vez?

bookmarklet

javascript:(function(){ 
    var l = document.createElement('script'); 
    l.setAttribute('type','text/javascript'); 
    l.setAttribute('src','launcher.js'); 
    document.body.appendChild(l); 
})(); 

Launcher.js

var s = document.createElement('script'); 
s.setAttribute('type','text/javascript'); 
s.setAttribute('src','my actual script'); 
document.body.appendChild(s); 

// I repeat a block like this once per script/css. 

El problema es que si se hace clic en el bookmarklet dos veces, todos los guiones se insertan de nuevo. ¿Cómo puedo prevenir este comportamiento?

Respuesta

4

Usted puede establecer una propiedad en el objeto window que curiosamente se nombra, por lo que es poco probable que cause colisiones de espacio de nombres, en la primera ejecución única . En ejecuciones posteriores, el código no se ejecutará si la propiedad está presente:

javascript:(function(){ 
     // Test for existence of your weird property 
     if (!window.hasOwnProperty('yourWeirdPropertyX774x9ZZYy4')) { 

      // Run all your existing code 
      var l = document.createElement('script'); 
      l.setAttribute('type','text/javascript'); 
      l.setAttribute('src','launcher.js'); 
      document.body.appendChild(l); 

     // Set the flag so this won't run again 
     window.yourWeirdPropertyX774x9ZZYy4 = true; 
     } 
    })(); 
+0

¡Uy! - editado para corregir la sintaxis wonky y colocar el bloque if desde la función anon en lugar de sin sentido alrededor de ella. –

+0

Perfecto: mis intentos anteriores fueron ciertamente en esta línea, pero estaba usando variables en lugar de accesorios de ventana, que no sabía nada. ¡Gracias! – vemv

+1

@vemv Una variable declarada dentro de una función como 'yourVar = 1234;' sin la palabra clave 'var' frente a ella se convierte de hecho en una propiedad del objeto' window' global, pero este método es mucho más explícito y deliberado. –

0

Simplest/Cleanest way to implement singleton in JavaScript?

Un ejemplo de una buena manera de poner en práctica Singleton en JS. No voy a copiar/pegar su respuesta, pero le dan una buena lectura :)

+0

Tal vez el uso de la palabra 'singleton' fue un error mío - No creo que adjuntar la aplicación en un objeto literal lo resuelva. – vemv

3

He encontrado la manera más limpia para que haga esto era a nombre de la función que carga el archivo JS externo, el mismo nombre que una función dentro del archivo externo que quiero que se ejecute cada vez que el usuario hace clic en el bookmarklet. De esta forma, cuando se hace clic en el bookmarklet la primera vez, carga el archivo externo y, en clics subsiguientes, se ejecuta una función en el archivo externo.

Aquí hay un código sudo:

Este sería el código en la URL del enlace bookmarklet

if(! bookmarklet){ 
    var bookmarklet = { 
    click: function(){ 
     js = document.createElement('SCRIPT'); 
     js.type = 'text/javascript'; 
     js.src = 'http://external.js?' + (Math.random()); 
     document.getElementsByTagName('head')[0].appendChild(js); 
    } 
    }; 
} 
bookmarklet.click(); // this will be called everytime the bookmarklet is clicked 

El archivo external.js contendría una función con el mismo nombre así:

var bookmarklet = { 
    click:function(){ 
     // insert logic you want to run every time the bookmarklet is clicked 
    } 
}; 
bookmarket.click(); // run once after file is loaded 

De esta forma, cuando se carga el archivo externo, su función (la función de ejemplo es bookmarklet.click) ahora ejecuta la función dentro del archivo cargado externamente y no lo hará ad el archivo js externo por segunda vez.

+0

Me tomó un tiempo entenderlo (el nombre de 'clic' me engaña) pero ahora lo hago. Buen enfoque, ¡salud! – vemv

Cuestiones relacionadas