5

I'm trying to write a bookmarklet which adds a JSONP call into a page like this:

javascript:(function(){
var myFunction = (window.function(data){alert('my function is firing with arg' + data)});
var j = 'http://localhost/jsonscript.js';
var s = document.createElement('script');
s.src = j;
document.getElementsByTagName('head')[0].appendChild(s);
})();

where the script src appended into the page contains

myFunction('foo');

But there's an error when I click the bookmarklet -- myFunction is not defined. How do I "export" that function outside the scope of my bookmarklet so that when called from the appended script tag it works?

Edit: I figured out that I can just pack the script element's innerHTML with raw JavaScript. This works but it's ugly. I would still like to figure out a better way.

AmbroseChapel
  • 11,957
  • 7
  • 46
  • 68
  • 3
    myFunction var scope is within the bookmarklet declaration, so you can declare it global if you want to access it outside the (function(){})() declaration. Change var myFunction = ... to window.myFunction = – elmasse Mar 31 '13 at 21:31
  • Working just fine. Put that as an answer and I'll mark it correct. – AmbroseChapel Apr 01 '13 at 03:23
  • @AmbroseChapel, could you please post your answer demonstrating "pack the script element's innerHTML with raw JavaScript" or perhaps a reference to a current better solution? it's more than 3 years later and I still can't find a better and DRYer method than defining the function on the window, which gets sloppy repetitive for common tasks. thanks! – Jeff Puckett May 04 '16 at 02:27
  • Wow, it's been so long. I guess I just meant something like: `var s = document.createElement('script'); s.innerHTML = 'alert("foo")';` literally using JavaScript to create JavaScript, but that's going to be just as annoying as the window method if not more soo. – AmbroseChapel May 20 '16 at 07:02

1 Answers1

5

Define the function on the window object:

window.myFunction = ...

With JSONP requests, you'll usually want some type of counter to increment, ie:

var counter = 1;
var myFuncName = "myFunction" + counter;
var j = 'http://localhost/jsonscript.js?callback=' + myFuncName;
window[myFuncName] = function (data) {...};

// remove function after timeout expires
setTimeout(function () { delete window[myFuncName] }, 5000);
Abdullah Jibaly
  • 53,220
  • 42
  • 124
  • 197