Workaround for “embedding” external scripts in JavaScript bookmarklets (thanks @ben_alman).
Posted by jpluimers on 2025/03/25
Bookmarklets are basically URLs that execute a JavaScript function.
Sometimes you want to rely on external JavaScript files (for instance jQuery), but Bookmarklets themselves cannot do that.
Bookmarklets can modify the current page though, and use those to load a script, wait until it is loaded, then continue executing.
Often that is OK as you want to operate the Bookmarklet on that page anyway, but be careful though that you do not mess up the page by loading an incompatible script: test, test, test!
I mentioned Ben Alman (formerly [Wayback/Archive] Ben Alman (@cowboy), now [Wayback/Archive] “Cowboy” Ben Alman (@ben_alman)) in my blogs earlier, but did not detailed much. Time to do that now:
His old post is [Wayback/Archive] Ben Alman » jQuery Bookmarklet Generator which starts with
This would probably actually be better called “Run some arbitrary code that requires jQuery, loading a minimum required version of [Wayback/Archive] jQuery first (but only if necessary), affecting the host page as little as possible Bookmarklet Generator” but that wasn’t nearly as catchy as “jQuery Bookmarklet Generator” so I’m going to stick with that.
The source code is in [Wayback/Archive] benalman.com/code/javascript/jquery/jquery.ba-run-code-bookmarklet.js and uses the [Wayback/Archive] Window: load event – Web APIs | MDN (named onload) from [Wayback/Archive] HTMLScriptElement – Web APIs | MDN (named script).
A generator front-end is at [Wayback/Archive] Ben Alman » Run jQuery Code Bookmarklet » Generate and points to a few other interesting sites as well.
The cool thing about the front-end is that it is parameterised as demonstrated by [Wayback/Archive] Ben Alman » Run jQuery Code Bookmarklet » Generate (alert example) which generates the code to execute alert('existing: '+(window.jQuery?jQuery.fn.jquery:'N/A')+', loaded: '+(L?$.fn.jquery:'N/A'));, and then generates this:
javascript:(function(e,a,g,h,f,c,b,d){if(!(f=e.jQuery)||g>f.fn.jquery||h(f)){c=a.createElement("script");c.type="text/javascript";c.src="http://ajax.googleapis.com/ajax/libs/jquery/"+g+"/jquery.min.js";c.onload=c.onreadystatechange=function(){if(!b&&(!(d=this.readyState)||d=="loaded"||d=="complete")){h((f=e.jQuery).noConflict(1),b=1);f(c).remove()}};a.documentElement.childNodes[0].appendChild(c)}})(window,document,"1.3.2",function($,L){alert('existing: '+(window.jQuery?jQuery.fn.jquery:%27N/A%27)+%27,%20loaded:%20%27+(L?$.fn.jquery:%27N/A%27));});
Or expanded (thanks [Wayback/Archive] Online JavaScript beautifier!)
javascript: (function(e, a, g, h, f, c, b, d) { if (!(f = e.jQuery) || g > f.fn.jquery || h(f)) { c = a.createElement("script"); c.type = "text/javascript"; c.src = "http://ajax.googleapis.com/ajax/libs/jquery/" + g + "/jquery.min.js"; c.onload = c.onreadystatechange = function() { if (!b && (!(d = this.readyState) || d == "loaded" || d == "complete")) { h((f = e.jQuery).noConflict(1), b = 1); f(c).remove() } }; a.documentElement.childNodes[0].appendChild(c) } })(window, document, "1.3.2", function($, L) { alert('existing: ' + (window.jQuery ? jQuery.fn.jquery : % 27 N / A % 27) + % 27, % 20 loaded: % 20 % 27 + (L ? $.fn.jquery : % 27 N / A % 27)); });
Parameters:
e=windowa=documentg=required_versionh=callbackf=$c=script_urib=doned=readystate
I have made the most important lines bold to emphasise what they accomplish:
- create a new
scriptelement with atypeattribute oftext/javascriptand asrcattribute to the right javascript URI - pointing the
onloadandonreadystatechangeattributes to capture theloadandreadystatechangeevents so that thecallbackcan be called when the documentreadyStateisloadedorcomplete. - add the
scriptelement to the current document (which will then start try loading the script and eventually fire the above events upon success).
Via
- [Wayback/Archive] embed javascript file in bookmarklet – Google Search
- [Wayback/Archive] How to create a bookmarklet with an external js file. (2011-05) based on:
- [Wayback/Archive] Create Bookmarklets – The Right Way (2011-02)
The last two use this bit of code that does not wait for loading which means the Bookmarklet can continue while the script is not loaded yet, then fails:
javascript: (function() {varjsCode = document.createElement('script');document.body.appendChild(jsCode);}());
That’s a bummer as [Wayback/Archive] HTMLScriptElement: dynamically importing scripts – Web APIs | MDN has had the correct example for this for a very long time (at least 2013, but I think even earlier on prior links):
function loadError(oError) { throw new URIError(`The script ${oError.target.src} didn't load correctly.`); } function prefixScript(url, onloadFunction) { const newScript = document.createElement("script"); newScript.onerror = loadError; if (onloadFunction) { newScript.onload = onloadFunction; } document.currentScript.parentNode.insertBefore(newScript, document.currentScript); newScript.src = url; }
Related
My earlier blog posts:
- A Couple of Quick Bookmarklets For Viewing a Suspended / Deleted Twitter User – ResearchBuzz
- Side effect-free bookmarklets: wrap them in an IIFE (Immediately Invoked Function Expression)
Links mentioned by Ben Alman:
- [Wayback/Archive] jQuery
- [Wayback/Archive] Better, Stronger, Safer jQuerify Bookmarklet | Learning jQuery
- [Wayback/Archive] Better, Stronger, Safer jQuerify Bookmarklet | Learning jQuery
- [Wayback/Archive] benalman.com/code/javascript/jquery/jquery.ba-run-code-bookmarklet.js
- [Wayback/Archive] Ben Alman » Run jQuery Code Bookmarklet » Generate
- [Wayback/Archive] Ben Alman » Run jQuery Code Bookmarklet » Generate (with URL parameters to show an actual example)
--jeroen






Leave a comment