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.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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With