开发者

How to enforce a bookmarklet to run only once?

My bookmarklet consist of a call to a 'launcher' script that is inserted into body. As it runs, it inserts in a similar way more scripts (jQuery, the actual application), and a CSS.

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.createElemen开发者_如何学JAVAt('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.

The problem is that if the bookmarklet is clicked twice, all the scripts will be inserted again. How can I prevent this behavior?


You can set a property on the window object which is oddly named, so it is unlikely to cause namespace collisions, on the first run only. On subsequent runs, the code will not execute if the property is present:

    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;
      }  
    })();


I found the cleanest way for me to do this was to name the function that loads the external js file, the same name as a function inside the external file that I want to be ran everytime the user clicks the bookmarklet. This way when the bookmarklet is clicked the first time, it loads the external file and on subsquent clicks a function in the external file is ran.

Here is some sudo code:

This would be the code in the url of the bookmarklet link

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

The external.js file would contain a function with the same name like this:

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

This way when the external file is loaded your function (example function is bookmarklet.click) now runs the function inside the externally loaded file and will not load the external js file a second time.


Simplest/Cleanest way to implement singleton in JavaScript?

An example on a good way to implement Singletons in JS. I won't copy/paste his answer, but give it a good read :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜