tags:

views:

176

answers:

7

How do I get the absolute or site-relative path for an included javascript file.

I know this can be done in PHP, (__file__, I think). Even for an included page, one can check the path (to the included file). Is there any way to have this self awareness in Javascript?

I know I can can get the page URL, but need to get the JS URL.

Eg. Javascript needs to modify the src of an image on the page. I know where the image is relative to the JavaScript file. I don't know where the Javascript is relative to the page.

<body>
  <img id="img0" src="">
  <script src="js/imgMaker/myscript.js"></script>
</body>

function fixPath(){ 
  $$("#img0")[0].set('src','js/imgMaker/images/main.jpg');
}

Please do not tell me to restructure my function - the example is simplified to explain the need. In the actual case, a Mootools class is being distributed and people can put it into whatever folder they want.

I would just read the src of the script element, but the class can be part of any number of javascript files, so I can't know what the element looks like.

A: 

if you have folders:

/webroot
  /images
  /scripts

Then images would be an absolute path of /images/whatever.jpg and scripts would be an absolute path of /scripts/js.js

matpol
Right. I distribute my script to 1,000,000 people. Some will have a folder called scripts, some will have a folder called js, some wont have folders. I know where the images are relative to the script file. But I do not have the path to the script file. How do I get that?
SamGoody
I know where the images are relative to the script because I am distributing a folder with files and images, and I tell them they have to copy the folder as is into their server. But they could put the folder anywhere on the server they please, as long as they include the script in their page.
SamGoody
A: 

The path to the JS is irrelevant; links in the HTML file are always relative to the HTML file, even if you modify them from external JS.

[EDIT] If you need to build a path relative to the current web page, you can find its path in document.location.pathname. This path is relative to the web root but you should be able to find a known subpath and then work from there.

For example, for this page, it pathname would be /posts/1858724. You can look for posts and then build a relative path from there (for example posts/../images/smiley.png)

Aaron Digulla
This is true for JS, but not for CSS. links in a CSS file are relative to the CSS file, not the HTML file.
Marius
That's exactly the point!! Again: I know where the image is relative to the JavaScript file. I don't know where the Javascript is relative to the page. Since the path I will be inserting into the page must be relative the page, I need to know the path to the javascript file in order to create the correct path!
SamGoody
Oh, that's simple: You can find the path of the page in document.location.pathname It's relative to the web root but you should be able to find a known subpath and then work from there.
Aaron Digulla
+2  A: 

JavaScript (not JScript) has no concept of file names. It was developed for Netscape back in the days. Therefore there is no __file__ feature or anything similar.

The closest you can come are these two possibilities:

  1. What you already mentioned: Harvest all src attributes of all JS files and try to figure out which one is the right.

  2. Make it a necessary option, that the path to the images must be set in the embedding HTML file. If not set, use a reasonable and well-documented default:


<script type="text/javascript">
var options = {
  'path_to_images': '/static/images/' // defaults to '/js/img/'
};
</script>
Boldewyn
Can this be done in Jscript? Perhaps I should add a little snippet to catch IE, at least?
SamGoody
No. I mentioned it just, because you can execute JScript files on a Windows machine, and there you can access files via the so-called Windows Script Host. No luck in IE either, sorry.
Boldewyn
A: 

I'm using the following method to get the base URL and using it for loading the other prorotypes, maybe this is what you need. Lets say current script name is 'clone.js'.

    /*
     * get the base URL using current script
     */

    var baseURL = '';
    var myName = 'clone.js';
    var myPattern = /(^|[\/\\])clone\.js(\?|$)/;

    var scripts = document.getElementsByTagName("script");

    for (var i = 0; i < scripts.length; i++) {
        var src;
        if (src = scripts[i].getAttribute("src")) {
            if (src.match(myPattern)) {
                baseURL =  src.replace(myName, '');
                break;
            }
        }
    }

Var baseURL should contain what you need.

Sergii
+2  A: 

Based on http://ejohn.org/blog/%5F%5Ffile%5F%5F-in-javascript/

(function(){
  this.__defineGetter__("__FILE__", function() {
    return (new Error).stack.split("\n")[2].split("@")[1].split(":").slice(0,-1).join(":");
  });
})();

(function(){
  this.__defineGetter__("__DIR__", function() {
    return __FILE__.substring(0, __FILE__.lastIndexOf('/'));
  });
})();

Then later

img.setAttribute('src', __DIR__ + '/' + file);
rm
this is cool. Unfortunately it works only in FF.
Boldewyn
A: 

I know this question was asked awhile back but I have a similar situation to Sam's.

In my case, I have two reasons for the situation:

  1. The user can access different sub-domains, each with its own index page.
  2. The user can enter a password that causes index.php to adjust the paths.

Most of the references point to the same src locations for the scripts, but some do not. For instance, those at a different level of the tree would require a different path.

I addressed it by assigning an id to the index page's script tag. For example, the head might include...

<script id='scriptLocation' type='text/javascript' language='javascript' src='../scripts.test/script.js'></script>

My JavaScript is then able to read the path...

var myPath = document.getElementById("scriptLocation").src;
Alan Neal
A: 

Found another approach, perhaps someone with more JS ninja can flush this out.

CSS stylesheet are able to find the node that called them using document.stylesheets.ownernode.

I could not find a similar call for javascript files.

But, in some cases, if one can include a CSS file together with the javascript, and give the first rule some unique identifier. One can loop through all stylesheets till they find the one with the identifier [if(document.stylsheets[i].cssRules[0] == thisIs:myCSS)], than use ownerNode to get the path of that file, and assume the same for the JS.

Convoluted and not very useful, but its another approach - might trigger a better idea by someone.

SamGoody