Reputation: 28513
I'm working on a plugin that allows to inject 3rd party code into a page (either as iframe
or directly into the DOM).
My problem is "direct injections", because I need to make sure, I don't add any <scripts> additional times, if they are needed in my main page and in a page I'm loading and injecting.
For example (and I can't use requireJS), my page.html
looks like this:
<html>
<head>
<script type="text/js" src="jquery.js"></script> // exports window.$
<script type="text/js" src="foo.js"></script> // exports window.foo
</head>
<body>
<!-- things that make foo load anotherPage.html and append its content here -->
</body>
</html>
with anotherPage.html
<html>
<head>
<script type="text/js" src="foo.js"></script> // exports window.foo
</head>
<body>
<!-- stuff that also runs on FOO -->
</body>
</html>
Page loading is done via Ajax and when I'm processing the data
returned by my request for anotherPage.html
I end up with a list of all elements after doing this:
cleanedString = ajaxResponseData
.replace(priv.removeJSComments, "")
.replace(priv.removeHTMLComments,"")
.replace(priv.removeLineBreaks, "")
.replace(priv.removeWhiteSpace, " ")
.replace(priv.removeWhiteSpaceBetweenElements, "><");
// this will return a list with head and body elements
// e.g. [meta, title, link, p, div, script.foo]
content = $.parseHTML(cleanedString, true);
// insert into DOM
someTarget.append(content);
This is where I'm stuck trying to detect whether a script I'm about to append to the document is already there.
I cannot go by the src
, because the filename may differ and a script may be hosted on a different domain (with Access-Control-Allow-Origin
correctly set). I also don't know, what and if the script I'm about to append returns a global I already have defined and I can't/don't want to use eval()
to find out.
Question:
Is there any way to identify whether a plugin or script that may return a global is already "on" a page, when I only have the "non-appended" <script> element available?
Thanks!
Upvotes: 0
Views: 280
Reputation: 16726
here is an example of my self-enclosed module pattern, i call it a "Sentinel":
(function wait(){
if(!self.$){
if(!wait.waitingJQ){
wait.waitingJQ=true;
addScriptTag(JQUERY_URL);
}
return setTimeout(wait, 44);
}
doStuffThatNeedsJquery();
}());
The sentinel pattern work from anywhere (internal or external), doesn't care about script loading order, and works with ANY script loading library. you can list additional depends below the jQuery fork in the same manner, just put your greedy code at the bottom of the sentinel wrapper function.
Upvotes: 1