75

How can I load an external JavaScript file using a bookmarklet? This would overcome the URL length limitations of IE and generally keep things cleaner.

Zombo
  • 1
  • 62
  • 391
  • 407
Justin
  • 20,509
  • 6
  • 47
  • 58

5 Answers5

98

2015 Update

Content security policy will prevent this from working in many sites now. For example, the code below won't work on Facebook.

2008 answer

Use a bookmarklet that creates a script tag which includes your external JS.

As a sample:

javascript:(function(){document.body.appendChild(document.createElement('script')).src='** your external file URL here **';})();
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
Miguel Ventura
  • 10,344
  • 2
  • 31
  • 41
  • 2
    Just wondering, why is it wrapped in a function call, as opposed to just having: javascript:document.body.appendChild(document.createElement('script')).src='** your external file URL here **'; – Mark Dec 12 '10 at 18:34
  • 15
    Try and see! Leaving it as *javascript:a=b* will leave you with a page saying 'b'. This will happen unless you void your code either by placing it inside a function that returns nothing or by passing it to *void(...)*. – Miguel Ventura Dec 13 '10 at 12:37
  • 4
    Also, if the original page uses a global variable *a*, your *a=b* will not overwrite it, when you have it in a function – nico gawenda Jan 29 '13 at 08:02
  • No need to set up an onload function to let you know when you can call functions in the script??? – Michael Jan 14 '14 at 00:36
  • 4
    content security policy will prevent this from working in many sites now – Michael Dec 30 '14 at 23:21
  • @Michael: this method actually works in Chrome on this page, but doesn't work on Facebook. Here's some bookmarklet code: `javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://dandascalescu.com/static/bm.js';})();` – Dan Dascalescu May 07 '15 at 19:36
4

Firefox and perhaps others support multiline bookmarklets, no need for one liner. When you paste in the code it just replaces newlines with spaces.

javascript:
var q = document.createElement('script');
q.src = 'http://svnpenn.github.io/bm/yt.js';
document.body.appendChild(q);
void 0;

Example

Zombo
  • 1
  • 62
  • 391
  • 407
1

If I can add method tested in FF & Chrome (for readibility split to multiple lines):

javascript:var r = new XMLHttpRequest();
           r.open("GET", "https://...my.js", true);
           r.onloadend = function (oEvent) {
               new Function(r.responseText)();
               /* now you can use your code */
           };
           r.send();
           undefined
Jan
  • 2,178
  • 3
  • 14
  • 26
0

It is no longer recommended to do this as CSP on most website will make it fail. But if you still want to use it: 2022 example

(() => {
    const main = () => {
        // write your code here
        alert($('body')[0].innerHTML)
    }
    const scriptEle = document.createElement('script')
    scriptEle.onload = main
    scriptEle.src = 'https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.min.js'
    document.body.appendChild(scriptEle)
})();
xbtsw
  • 684
  • 5
  • 12
-2

I always prefer to use a popular open source project loadjs

it is cross browser tested and has more functionality/comfort features.

So the code will look like this:

loadjs=function(){function e(e,n){var t,r,i,c=[],o=(e=e.push?e:[e]).length,f=o;for(t=function(e,t){t.length&&c.push(e),--f||n(c)};o--;)r=e[o],(i=s[r])?t(r,i):(u[r]=u[r]||[]).push(t)}function n(e,n){if(e){var t=u[e];if(s[e]=n,t)for(;t.length;)t[0](e,n),t.splice(0,1)}}function t(e,n,r,i){var o,s,u=document,f=r.async,a=(r.numRetries||0)+1,h=r.before||c;i=i||0,/(^css!|\.css$)/.test(e)?(o=!0,(s=u.createElement("link")).rel="stylesheet",s.href=e.replace(/^css!/,"")):((s=u.createElement("script")).src=e,s.async=void 0===f||f),s.onload=s.onerror=s.onbeforeload=function(c){var u=c.type[0];if(o&&"hideFocus"in s)try{s.sheet.cssText.length||(u="e")}catch(e){u="e"}if("e"==u&&(i+=1)<a)return t(e,n,r,i);n(e,u,c.defaultPrevented)},!1!==h(e,s)&&u.head.appendChild(s)}function r(e,n,r){var i,c,o=(e=e.push?e:[e]).length,s=o,u=[];for(i=function(e,t,r){if("e"==t&&u.push(e),"b"==t){if(!r)return;u.push(e)}--o||n(u)},c=0;c<s;c++)t(e[c],i,r)}function i(e,t,i){var s,u;if(t&&t.trim&&(s=t),u=(s?i:t)||{},s){if(s in o)throw"LoadJS";o[s]=!0}r(e,function(e){e.length?(u.error||c)(e):(u.success||c)(),n(s,e)},u)}var c=function(){},o={},s={},u={};return i.ready=function(n,t){return e(n,function(e){e.length?(t.error||c)(e):(t.success||c)()}),i},i.done=function(e){n(e,[])},i.reset=function(){o={},s={},u={}},i.isDefined=function(e){return e in o},i}();
loadjs('//path/external/js', {
    success: function () {
        console.log('something to run after the script was loaded');
    });
naviram
  • 1,445
  • 1
  • 15
  • 26