Suppose there is a site that includes an external .js file in an html script tag like so:
<script src="somescript.js">
I want greasemonkey to intercept each of such scripts, and alter some of the values in them before they execute. For example, I want to change all occurrences of the value "400" to "300" within them, then continue to load the page as if the scripts used those values instead of the original ones. Currently I'm using the following code in greasemonkey:
function replaceTargetJavascript (scriptNode) {
var scriptSrc = scriptNode.textContent;
scriptSrc = scriptSrc.replace (
/'400'/,
"'300'"
);
addJS_Node (scriptSrc);
}
document.addEventListener("beforescriptexecute", function(e) {
checkForBadJavascripts ( [
[false, /'400'/, replaceTargetJavascript]
] );
}, true);
Which according to my sources is the right way to do it, but it is not working. Can anyone please help me figure this out?
Old question, but I needed to do this recently.
Here's how I did it using GreaseMonkey.
You add the beforescriptexecute listener, and wait for your target script to be loaded, checking the src tag to identify the correct script.
Then you stop that script from loading and get the script source yourself using GM_xmlhttpRequest.
Then you are free to modify the script as you please and insert it back into the DOM.
// ==UserScript==
// #name Test
// #namespace Test
// #description TEST
// #include http://the.website.com/*
// #version 1
// #grant GM_xmlhttpRequest
// #run-at document-start
// ==/UserScript==
function addScript(text) {
text = text.replace(/replaceThis();/g, "");
var newScript = document.createElement('script');
newScript.type = "text/javascript";
newScript.textContent = text;
var head = document.getElementsByTagName('head')[0];
head.appendChild(newScript);
}
window.addEventListener('beforescriptexecute', function(e) {
src = e.target.src;
if (src.search(/script_to_modify\.js/) != -1) {
e.preventDefault();
e.stopPropagation();
GM_xmlhttpRequest({
method: "GET",
url: e.target.src,
onload: function(response) {
addScript(response.responseText);
}
});
}
});
Related
I'm creating a jquery plugin and I want to verify an external script is loaded. This is for an internal web app and I can keep the script name/location consistent(mysscript.js). This is also an ajaxy plugin that can be called on many times on the page.
If I can verify the script is not loaded I'll load it using:
jQuery.getScript()
How can I verify the script is loaded because I don't want the same script loaded on the page more than once? Is this something that I shouldn't need to worry about due to caching of the script?
Update:
I may not have control over who uses this plugin in our organization and may not be able to enforce that the script is not already on the page with or without a specific ID, but the script name will always be in the same place with the same name. I'm hoping I can use the name of the script to verify it's actually loaded.
If the script creates any variables or functions in the global space you can check for their existance:
External JS (in global scope) --
var myCustomFlag = true;
And to check if this has run:
if (typeof window.myCustomFlag == 'undefined') {
//the flag was not found, so the code has not run
$.getScript('<external JS>');
}
Update
You can check for the existence of the <script> tag in question by selecting all of the <script> elements and checking their src attributes:
//get the number of `<script>` elements that have the correct `src` attribute
var len = $('script').filter(function () {
return ($(this).attr('src') == '<external JS>');
}).length;
//if there are no scripts that match, the load it
if (len === 0) {
$.getScript('<external JS>');
}
Or you can just bake this .filter() functionality right into the selector:
var len = $('script[src="<external JS>"]').length;
Few too many answers on this one, but I feel it's worth adding this solution. It combines a few different answers.
Key points for me were
add an #id tag, so it's easy to find, and not duplicate
Use .onload() to wait until the script has finished loading before using it
mounted() {
// First check if the script already exists on the dom
// by searching for an id
let id = 'googleMaps'
if(document.getElementById(id) === null) {
let script = document.createElement('script')
script.setAttribute('src', 'https://maps.googleapis.com/maps/api/js?key=' + apiKey)
script.setAttribute('id', id)
document.body.appendChild(script)
// now wait for it to load...
script.onload = () => {
// script has loaded, you can now use it safely
alert('thank me later')
// ... do something with the newly loaded script
}
}
}
#jasper's answer is totally correct but with modern browsers, a standard Javascript solution could be:
function isScriptLoaded(src)
{
return Boolean(document.querySelector('script[src="' + src + '"]'));
}
UPDATE July 2021:
The accepted solutions above have changed & improved much over time. The scope of my previous answer above was only to detect if the script was inserted in the document to load (and not whether the script has actually finished loading).
To detect if the script has already loaded, I use the following method (in general):
Create a common library function to dynamically load all scripts.
Before loading, it uses the isScriptLoaded(src) function above to check whether the script has already been added (say, by another module).
I use something like the following loadScript() function to load the script that uses callback functions to inform the calling modules if the script finished loading successfully.
I also use additional logic to retry when script loading fails (in case of temporary network issues).
Retry is done by removing the <script> tag from the body and adding it again.
If it still fails to load after configured number of retries, the <script> tag is removed from the body.
I have removed that logic from the following code for simplicity. It should be easy to add.
/**
* Mark/store the script as fully loaded in a global variable.
* #param src URL of the script
*/
function markScriptFullyLoaded(src) {
window.scriptLoadMap[src] = true;
}
/**
* Returns true if the script has been added to the page
* #param src URL of the script
*/
function isScriptAdded(src) {
return Boolean(document.querySelector('script[src="' + src + '"]'));
}
/**
* Returns true if the script has been fully loaded
* #param src URL of the script
*/
function isScriptFullyLoaded(src) {
return src in window.scriptLoadMap && window.scriptLoadMap[src];
}
/**
* Load a script.
* #param src URL of the script
* #param onLoadCallback Callback function when the script is fully loaded
* #param onLoadErrorCallback Callback function when the script fails to load
* #param retryCount How many times retry laoding the script? (Not implimented here. Logic goes into js.onerror function)
*/
function loadScript(src, onLoadCallback, onLoadErrorCallback, retryCount) {
if (!src) return;
// Check if the script is already loaded
if ( isScriptAdded(src) )
{
// If script already loaded successfully, trigger the callback function
if (isScriptFullyLoaded(src)) onLoadCallback();
console.warn("Script already loaded. Skipping: ", src);
return;
}
// Loading the script...
const js = document.createElement('script');
js.setAttribute("async", "");
js.src = src;
js.onload = () => {
markScriptFullyLoaded(src)
// Optional callback on script load
if (onLoadCallback) onLoadCallback();
};
js.onerror = () => {
// Remove the script node (to be able to try again later)
const js2 = document.querySelector('script[src="' + src +'"]');
js2.parentNode.removeChild(js2);
// Optional callback on script load failure
if (onLoadErrorCallback) onLoadErrorCallback();
};
document.head.appendChild(js);
}
This was very simple now that I realize how to do it, thanks to all the answers for leading me to the solution. I had to abandon $.getScript() in order to specify the source of the script...sometimes doing things manually is best.
Solution
//great suggestion #Jasper
var len = $('script[src*="Javascript/MyScript.js"]').length;
if (len === 0) {
alert('script not loaded');
loadScript('Javascript/MyScript.js');
if ($('script[src*="Javascript/MyScript.js"]').length === 0) {
alert('still not loaded');
}
else {
alert('loaded now');
}
}
else {
alert('script loaded');
}
function loadScript(scriptLocationAndName) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scriptLocationAndName;
head.appendChild(script);
}
Create the script tag with a specific ID and then check if that ID exists?
Alternatively, loop through script tags checking for the script 'src' and make sure those are not already loaded with the same value as the one you want to avoid ?
Edit: following feedback that a code example would be useful:
(function(){
var desiredSource = 'https://sitename.com/js/script.js';
var scripts = document.getElementsByTagName('script');
var alreadyLoaded = false;
if(scripts.length){
for(var scriptIndex in scripts) {
if(!alreadyLoaded && desiredSource === scripts[scriptIndex].src) {
alreadyLoaded = true;
}
}
}
if(!alreadyLoaded){
// Run your code in this block?
}
})();
As mentioned in the comments (https://stackoverflow.com/users/1358777/alwin-kesler), this may be an alternative (not benchmarked):
(function(){
var desiredSource = 'https://sitename.com/js/script.js';
var scripts = document.getElementsByTagName('script');
var alreadyLoaded = false;
for(var scriptIndex in document.scripts) {
if(!alreadyLoaded && desiredSource === scripts[scriptIndex].src) {
alreadyLoaded = true;
}
}
if(!alreadyLoaded){
// Run your code in this block?
}
})();
Simply check if the global variable is available, if not check again. In order to prevent the maximum callstack being exceeded set a 100ms timeout on the check:
function check_script_loaded(glob_var) {
if(typeof(glob_var) !== 'undefined') {
// do your thing
} else {
setTimeout(function() {
check_script_loaded(glob_var)
}, 100)
}
}
Another way to check an external script is loaded or not, you can use data function of jquery and store a validation flag. Example as :
if(!$("body").data("google-map"))
{
console.log("no js");
$.getScript("https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initilize",function(){
$("body").data("google-map",true);
},function(){
alert("error while loading script");
});
}
}
else
{
console.log("js already loaded");
}
I think it's better to use window.addEventListener('error') to capture the script load error and try to load it again.
It's useful when we load scripts from a CDN server. If we can't load script from the CDN, we can load it from our server.
window.addEventListener('error', function(e) {
if (e.target.nodeName === 'SCRIPT') {
var scriptTag = document.createElement('script');
scriptTag.src = e.target.src.replace('https://static.cdn.com/', '/our-server/static/');
document.head.appendChild(scriptTag);
}
}, true);
Merging several answers from above into an easy to use function
function GetScriptIfNotLoaded(scriptLocationAndName)
{
var len = $('script[src*="' + scriptLocationAndName +'"]').length;
//script already loaded!
if (len > 0)
return;
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scriptLocationAndName;
head.appendChild(script);
}
My idead is to listen the error log if there is an error on script loading.
const checkSegmentBlocked = (e) => {
if (e.target.nodeName === 'SCRIPT' && e.target.src.includes('analytics.min.js')) {
window.isSegmentBlocked = true;
e.target.removeEventListener(e.type, checkSegmentBlocked);
}
};
window.addEventListener('error', checkSegmentBlocked, true);
Some answers on this page are wrong. They check for the existence of the <script> tag - but that is not enough. That tells you that the tag was inserted into the DOM, not that the script is finished loading.
I assume from the question that there are two parts: the code that inserts the script, and the code that checks whether the script has loaded.
The code that dynamically inserts the script:
let tag = document.createElement('script');
tag.type = 'text/javascript';
tag.id = 'foo';
tag.src = 'https://cdn.example.com/foo.min.js';
tag.onload = () => tag.setAttribute('data-loaded', true); // magic sauce
document.body.appendChild(tag);
Some other code, that checks whether the script has loaded:
let script = document.getElementById('foo');
let isLoaded = script && script.getAttribute('data-loaded') === 'true';
console.log(isLoaded); // true
If the both of those things (inserting and checking) are in the same code block, then you could simplify the above:
tag.onload = () => console.log('loaded');
I found a quick tip before you start diving into code that might save a bit of time. Check devtools on the webpage and click on the network tab. The js scripts are shown if they are loaded as a 200 response from the server.
I want to remove remote js and load my local js in one production website.
So I use following userscript
// ==UserScript==
// #name TV full screen
// #match https://example.com/*
// #grant none
// #run-at document-start
// ==/UserScript==
new MutationObserver((mutations, observer) => {
const script = document.querySelector('script[src^="/static/bundles/main"]');
if (!script ) {
return;
}
observer.disconnect();
script .remove();
console.log('SRC removed');
document.head.appendChild(document.createElement('script')).src = "https://localhost/tv/my.js";
})
.observe(document.documentElement, { childList: true, subtree: true });
Following is the code present in production website
<script defer crossorigin="anonymous" type="text/javascript" src="/static/bundles/main.js" ></script>
since there is defer code in script tag , still the actual source is getting executed , eventhough tag is removed..How do I completely remove that script tag and stop execution and load my local file.
Try to change the selector changing the line:
const script = document.querySelector('script[src^="/static/bundles/main_chart"]');
with:
const script = document.querySelector('script[src^="/static/bundles/main.js"]');
May be Like This:
var myScript = document.createElement('script');
if (location.hostname === "localhost" || location.hostname === "127.0.0.1"){
myScript.src = '/path/to/my_LOCAL_Script...';
}else{
myScript.src = '/path/to/my_REMOTE_Script...';
}
document.head.appendChild(myScript);
Here's the code, not abridged (it's shortish):
// ==UserScript==
// #name Manga ChapterReader
// #license MIT/X11 + Attribution (passcod)
// #namespace http://www.mangareader.net
// #include http://www.mangareader.net/*
// #description Displays full chapters from MangaReader.net in a simpler interface.
// #author passcod
// #version 10.331
// ==/UserScript==
// version format: y.z
function START(array_of_scripts_to_load, callback) {
document.documentElement.innerHTML = '<head></head><body></body>';
for ( i in array_of_scripts_to_load) {
var script = document.createElement('script');
script.src = array_of_scripts_to_load[i];
var evl = new Object();
evl.handleEvent = function (e) {
callback();
};
script.addEventListener('load', evl, true);
document.getElementsByTagName('head')[0].appendChild(script);
}
}
var regular = /mangareader\.net\/[a-z0-9\-]+\/[0-9]+(\/.+)?/i, old = /mangareader\.net\/[0-9\-]+\/([a-z0-9\-]+)\/chapter-([0-9]+)\.htm/i;
if ( regular.test(window.location) ) {
//START(['http://lib/libstore/jquery.js','http://scrap.book/userscripts/mangareader/index.js'],
START(['http://code.jquery.com/jquery-1.4.2.min.js','https://bitbucket.org/passcod/scrap.book/raw/tip/userscripts/mangareader/index.js'],
function() {
$$$();
});
}
else if ( old.test(window.location) ) {
var parts = old.exec(window.location);
window.location = 'http://www.mangareader.net/'+parts[1]+'/'+parts[2];
}
This works perfectly in Firefox 4.0b7 (Windows) and nightly (Linux), but it fails with Fx 3.6.x (Reports from 3.6, 3.6.2, and 3.6.12).
I can't see why.
Oh, wait... I use Scriptish on Fx 4... maybe this has to do with something?
But apart from that, I'm totally at loss. The scripts don't get loaded. It even looks like the document.documentElement.innerHTML = '...' line doesn't work... did it in Firebug and it erases the document to <html></html>, but nothing more happens afterward.
Any ideas?
I fixed this by changing the loaded scripts to execute immediately:
(function () { /* ... */ })();
and then removing the callbacks.
There was no problem with the browser, but in the reaction time. For some reason, the userscript finished too early in Fx 4.
I'm working on a FireFox extension that listens to onStateChange. When the current document has been loaded it should insert a script to the page and it should be able to call the script on a button event.
Now I am able to add a button to all webpages by using:
nsCOMPtr<nsIDOMElement> NewInputElementTest;
rv = htmlDoc->CreateElement(NS_LITERAL_STRING("input"),getter_AddRefs(NewInputElementTest));
rv = NewInputElementTest->SetAttribute(NS_LITERAL_STRING("type"),NS_LITERAL_STRING("button"));
rv = NewInputElementTest->SetAttribute(NS_LITERAL_STRING("value"),NS_LITERAL_STRING("hummer"));
rv = body->AppendChild(NewInputElementTest,getter_AddRefs(AddedNewInputElement2));
The button is displayed correctly.
I wish to use the same procedure to add a SCRIPT to the page, like so:
rv = htmlDoc->CreateElement(NS_LITERAL_STRING("script"),getter_AddRefs(NewInputElement));
rv = NewInputElement->SetAttribute(NS_LITERAL_STRING("type"),NS_LITERAL_STRING("text/javascript"));
rv = NewInputElement->SetAttribute(NS_LITERAL_STRING("text"),NS_LITERAL_STRING("alert('hello world!')"));
rv = body->AppendChild(NewInputElement,getter_AddRefs(AddedNewInputElement));
All functions return success, but no script is added to the page. No alert is displayed, and if i insert a function and call it from the button.onclick then the FireFox log displayes that the function is not available.
If I use the exact same procedure from a javascript inside the html page, then it works find and the alert pops up.
Do I need to do anything to enable the script from my extension or why is the script not available from the button or anywhere else?
I hate to say it after you created a bunch of code, but check out Greasemonkey: https://addons.mozilla.org/en-US/firefox/addon/748
It'll probably handle a lot of your work for you.
Yes, sounds like you're tryin to re-invent the wheel. Use Greasemonkey as Oren suggested.
Here is a Greasemonkey script that I use to load external JS framework (Prototype and Scriptaculous in this case) load any number of external files (js and css) into a page.
// ==UserScript==
// #name External Loader
// #namespace http://ifelse.org
// #description Loads external JS and CSS
// #include http://*.yoursitedomainetc.com/*
// ==/UserScript==
var hasPrototype = ('Prototype' in unsafeWindow);
var hasEffects = ('Effect' in unsafeWindow);
function _require(url, isCSS) {
if (isCSS) {
var script = document.createElement('link');
script.setAttribute('type', 'text/css');
script.setAttribute('rel', 'stylesheet');
script.setAttribute('href', url);
} else {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('charset', 'UTF-8');
script.src = url;
}
document.getElementsByTagName('head')[0].appendChild(script);
}
// Load prototype; shouldn't get here because it is already on the page
if ( !hasPrototype ) {
_require('http://path.com/to/prototype/1.6.0.2/prototype.js');
}
// Load scriptaculous effects if it's not already loaded
if ( !hasEffects ) {
_require('http://path.com/to/scriptaculous/1.8.1/effects.js');
}
// Add greasemonkey ajax object
// Copies format of Prototype Ajax.Request to
// Allow to easily swap out at a later point (i.e. no longer FF plugin)
unsafeWindow.Remote = new Object;
unsafeWindow.Remote.Ajax = function(url, options) {
if (options.onCreate) {
options["onCreate"]();
}
var request = {
method: options.method || 'get',
url: url + ('?' + unsafeWindow.Object.toQueryString(options.parameters) || ''),
onload: function(response) {
if (response.status == 200)
options["onComplete"](response);
options["onSuccess"]();
},
onerror: options.onFailure || null
};
window.setTimeout(GM_xmlhttpRequest, 0, request);
};
// Load these External files
_require('http://path/to/anything/and/dont/cache/it.js' + '?cache=' + (new Date()).getTime());
_require('http://paht/to/something/else.css', true);
}
I'm trying to write a Greasemonkey script, and would like to use the jQuery library to do so, but I'm not quite sure how I would include jQuery from a web address to get rolling.
How would I include jQuery (from Google's web server) into the greasemonkey script so that I can just go:
$(document).ready(function(){
// Greasemonkey stuff here
});
I'd prefer to get it from this source:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
Update: Thanks for the help, the answers were very informative. I did, however, utilize my GoogleFu a little more and came across this solution: http://joanpiedra.com/jquery/greasemonkey/
Works like a charm.. just update the source to google's hosted version of jQuery to complete.
The recommended way in recent versions of greasemonkey is to use the #require comment tag.
E.g.
// ==UserScript==
// #name Hello jQuery
// #namespace http://www.example.com/
// #description jQuery test script
// #include *
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// ==/UserScript==
However... be aware that jQuery 1.4.1 and 1.4.2 are incompatible with this method
Thanks Paul Tarjan, for pointing this out. See jQuery forum thread.
Also be aware of these #require semantics
At the time that the user script is installed, Greasemonkey will download and keep a locally cached copy of the remote file that can be read almost instantly. The cached copy is kept in the same folder as your installed user-script. The remote file is not monitored for changes.
Please be aware that, at the time of writing this answer, this #require tag is only read at install-time. If you edit an existing user script to add this tag, it will be ignored. You need to uninstall and re-install your user script to pick up the change.
From here:
// ==UserScript==
// #name jQueryTest
// #namespace http://www.example.com/
// #include *
// ==/UserScript==
// Add jQuery
var GM_JQ = document.createElement('script');
GM_JQ.src = 'http://jquery.com/src/jquery-latest.js';
GM_JQ.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(GM_JQ);
// Check if jQuery's loaded
function GM_wait() {
if(typeof unsafeWindow.jQuery == 'undefined')
{ window.setTimeout(GM_wait,100); }
else { $ = unsafeWindow.jQuery; letsJQuery(); }
}
GM_wait();
// All your GM code must be inside this function
function letsJQuery() {
alert($); // check if the dollar (jquery) function works
// the next call fails
$("<div id='example' class='flora' title='This is my title'>I'm in
a dialog!</div>").dialog({
buttons: {
"Ok": function() {
alert("Ok");
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
}
It works perfectly, but you may want to limit the sites it runs on or host the jQuery js file on your own site so as not to steal their bandwidth.
You could try dynamically creating a script element:
var script = document.createElement("script");
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js";
document.getElementsByTagName("head")[0].appendChild(script);
You may need to delay for a bit while the script loads (setTimeout?)
Based on Chris's answer, I adjust to my own needs like following.
// ==UserScript==
// #description require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.jss
// #name Baidu Mask
// #namespace http://tampermonkey.net/
// #version 0.1
// #description try to take over the world!
// #author You
// #match https://www.ibm.com/developerworks/cn/opensource/os-cn-greasemonkey/index.html
// #match *://www.baidu.com/*
// #match *://baike.baidu.com/*
// #match *://zhidao.baidu.com/*
// #match *://www.weather.com.cn/*
// #grant none
// ==/UserScript==
(function () {
'use strict';
// Your code here...
var $j;
function GM_wait() {
if (typeof jQuery === 'undefined') {
window.setTimeout(GM_wait, 100);
}
else {
$j = jQuery.noConflict();
doJob();
}
}
function loadJquery() {
// Check if jQuery's loaded
if (typeof jQuery === 'undefined') {
// Add jQuery
var GM_JQ = document.createElement('script');
GM_JQ.src = 'https://code.jquery.com/jquery-1.12.4.min.js';
GM_JQ.type = 'text/javascript';
GM_JQ.id = 'jquery-lyz';
document.getElementsByTagName('head')[0].appendChild(GM_JQ);
GM_wait();
} else {
doJob();
}
}
loadJquery();
function doJob() {
if (typeof $j === 'undefined') {
$j = $;
}
var url_arr = [
{'name': "baidu", 'value': "www.baidu.com"},
{'name': "baike", 'value': "baike.baidu.com"},
{'name': "zhidao", 'value': "zhidao.baidu.com"},
{'name': "weather", 'value': "http://www.weather.com.cn"},
];
var url = location.href;
var siteObj = {};
$j(url_arr).each(function (i, item) {
if (url.indexOf(item.value) > -1) {
siteObj = item;
return false;
}
});
var delay_arr = [];
var timerCount = 1;
function hideTimer() {
timerCount++;
if (timerCount > 20) {
return;
}
delay_arr = $j.grep(delay_arr, function (_selector, i) {
var $ele = $j(_selector);
var visible = $ele.is(':visible');
console.log($ele, visible);
if (visible) {
$ele.hide();
return false;
}
return true; // keep the element in the array
});
if (delay_arr.length > 0) {
setTimeout(hideTimer, 500);
}
}
setTimeout(hideTimer, 500);
var $frms;
switch (siteObj.name) {
case 'baidu':
$j('#content_right').hide();
break;
case 'baike':
$j('.topA, .lemmaWgt-promotion-slide, .union-content, .right-ad, .lemmaWgt-promotion-vbaike, .nav-menu').hide();
delay_arr.push('#side_box_unionAd');
break;
case 'zhidao':
$j('.widget-new-graphic, #union-asplu, .jump-top-box').hide();
delay_arr.push('.wgt-daily');
delay_arr.push('.shop-entrance');
delay_arr.push('.cms-slide');
delay_arr.push('.nav-menu');
$frms = $j('iframe');
$frms.hide();
break;
case 'weather':
$j('.right, .hdImgs, .tq_zx, #di_tan, #zu_dui').hide();
//delay_arr.push('.wgt-daily');
$frms = $j('iframe');
$frms.hide();
break;
}
}
})();
My script need to work on different sites, while some has jquery included and some not, so I have to test out. The "require" way not work here.