How can I get the path of the current script in javascript using jQuery
for example I have site.com/js/script.js
and there is a code in this script:
$(document).ready(function() {
alert( ... this code ... );
}
It Should return alert box with the "/js/script.js" message. This function should work like magic __FILE__
constant in php
So, why do I need this?
I want to set background image dynamically:
$("somediv").css("background-image", "url(" + $SCRIPT_PATH + "/images/img.png)");
and images directory is the /js
directory, near the script.js
file
and js
folder's name can be dynamically set, so script and images can be in the /myprogect/javascript-files
directory
We can get the path of the present script in node. js by using __dirname and __filename module scope variables. __dirname: It returns the directory name of the current module in which the current script is located.
Using __dirname in a Node script will return the path of the folder where the current JavaScript file resides. Using ./ will give you the current working directory.
There are two ways you can get the current directory in NodeJS: Using the special variable __dirname. Using the built-in method process. cwd()
The <script> tag can be placed in the <head> section of your HTML or in the <body> section, depending on when you want the JavaScript to load.
You can rely on the fact that each <script>
element has to be evaluated* before the next one is inserted into the DOM.
This means that the script currently evaluated (as long as it is part of your markup and not dynamically inserted) will be the last one in the NodeList
retrieved with getElementsByTagName( 'script' )
.
This allows you to read that elements src attribute and from that determine the folder that the script is being served from - like this:
var scriptEls = document.getElementsByTagName( 'script' );
var thisScriptEl = scriptEls[scriptEls.length - 1];
var scriptPath = thisScriptEl.src;
var scriptFolder = scriptPath.substr(0, scriptPath.lastIndexOf( '/' )+1 );
console.log( [scriptPath, scriptFolder] );
I tried this technique with 3 scripts loaded from different folders and get this output
/*
["http://127.0.0.1:8000/dfhdfh/folder1/script1.js", "http://127.0.0.1:8000/dfhdfh/folder1/"]
["http://127.0.0.1:8000/dfhdfh/folder2/script2.js", "http://127.0.0.1:8000/dfhdfh/folder2/"]
["http://127.0.0.1:8000/dfhdfh/folder3/script3.js", "http://127.0.0.1:8000/dfhdfh/folder3/"]
*/
* from John Resigs blog linked to above
This means that when the script finally executes that it'll be the last script in the DOM - and even the last element in the DOM (the rest of the DOM is built incrementally as it hits more script tags, or until the end of the document).
As pimvdb points out - this will work as the script is being evaluated. You will need to store the path somehow if you are going to use it later. You can't query the DOM at a later point. If you use the same snippet for each script the value of scriptFolder
will be overwritten for each script. You should give each script a unique variable perhaps?
Wrapping your script in its own scope closes over the value of scriptFolder
making it available to the rest of the script without fear of being overwritten
(function() {
var scriptEls = document.getElementsByTagName( 'script' );
var thisScriptEl = scriptEls[scriptEls.length - 1];
var scriptPath = thisScriptEl.src;
var scriptFolder = scriptPath.substr(0, scriptPath.lastIndexOf( '/' )+1 );
$( function(){
$('#my-div').click(function(e){
alert(scriptFolder);
});
});
})();
Add the following code to your JS :
var retrieveURL = function(filename) {
var scripts = document.getElementsByTagName('script');
if (scripts && scripts.length > 0) {
for (var i in scripts) {
if (scripts[i].src && scripts[i].src.match(new RegExp(filename+'\\.js$'))) {
return scripts[i].src.replace(new RegExp('(.*)'+filename+'\\.js$'), '$1');
}
}
}
};
Suppose these are the scripts called in your HTML :
<script src="assets/js/awesome.js"></script>
<script src="assets/js/oldcode/fancy-stuff.js"></script>
<script src="assets/js/jquery/cool-plugin.js"></script>
Then, you can use the function like this
var awesomeURL = retrieveURL('awesome');
// result : 'assets/js/'
var awesomeURL = retrieveURL('fancy-stuff');
// result : 'assets/js/oldcode/'
var awesomeURL = retrieveURL('cool-plugin');
// result : 'assets/js/jquery/'
Note that this only works when there are no two script files in your HTML with the same name. If you have two scripts with the same name that are located in a different folder, the result will be unreliable.
If you dynamically add scripts to your page, you need to make sure your code is executed after the last script has been added to the DOM.
The follow example shows how to do this with one dynamically loaded script. It outputs a JSON array with the src
link for scripts that load an external js file and a base64-encoded string of the JS content for inline scripts:
var addScript = function(src, callback) {
var s = document.createElement( 'script' );
s.setAttribute( 'src', src );
document.body.appendChild( s );
s.onload = callback;
}
var retrieveURL = function(filename) {
var scripts = document.getElementsByTagName('script');
if (scripts && scripts.length > 0) {
for (var i in scripts) {
if (scripts[i].src && scripts[i].src.match(new RegExp(filename+'\\.js$'))) {
return scripts[i].src.replace(new RegExp('(.*)'+filename+'\\.js$'), '$1');
}
}
}
};
addScript('https://code.jquery.com/jquery-1.12.4.min.js', function() {
var scripts = document.getElementsByTagName('script');
var sources = [];
for (var i = 0; i < scripts.length; i++) {
if(scripts[i].src == '') {
sources.push(btoa(scripts[i].innerHTML));
} else {
sources.push(scripts[i].src);
}
}
document.body.innerHTML += '<pre>' + JSON.stringify(sources,null,2) + '</pre>';
});
See also this Fiddle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With