Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript get current filescript path

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

like image 372
pleerock Avatar asked Dec 15 '11 16:12

pleerock


People also ask

How do I print the path of a file in JavaScript?

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.

How do I get the current working directory in typescript?

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.

How do I get the current working directory in node JS?

There are two ways you can get the current directory in NodeJS: Using the special variable __dirname. Using the built-in method process. cwd()

Where do script tags go?

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.


2 Answers

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).

Update

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);
        });
    });


})();
like image 169
meouw Avatar answered Sep 24 '22 03:09

meouw


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.


Note

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.

like image 42
John Slegers Avatar answered Sep 22 '22 03:09

John Slegers