montrealist
montrealist

Reputation: 5693

How can code in a JavaScript file get the file's URL?

I need to dynamically load a CSS stylesheet into a page that's on a different domain. How can I get the complete URL of the JS file to use in the href attribute of the stylesheet?

For instance, here is the structure:

http://bla.com/js/script.js

http://bla.com/css/style.css

I want to dynamically load the stylesheet into a page http://boo.net/index.html. The problem is, I don't know the bla.com bit in advance, just the fact that the stylesheet is in ../css/ relative to the JS file.

The script is, of course, included on index.html. jQuery's fine too.

Upvotes: 18

Views: 40496

Answers (7)

Patrick Roberts
Patrick Roberts

Reputation: 51977

Even easier than using an id is to just leave the markup alone and use document.currentScript. The link to MDN mentions under the Notes section, a small quirk requiring the JavaScript to execute synchronously, and I'm about to explain how to avoid this pitfall.

It's important to note that this will not reference the <script> element if the code in the script is being called as a callback or event handler; it will only reference the element while it's initially being processed.

The advantage of this solution is that you are not required to use special markup, and this is especially helpful if you can't access the HTML yourself for some reason (e.g. if it's used by a client or a developer using your API).

If the script is executed synchronously (meaning the main content of the script isn't wrapped in an event listener or some other function set to evaluate later than when the code is "initially being processed" ), you can simply use document.currentScript to access the currently processing <script> element of your code. To demonstrate how to use this effectively, I'll provide a basic demo below.

HTML:

<script type="text/javascript" src="http://bla.com/js/script.js"></script>

JavaScript in http://bla.com/js/script.js:

var myScript = document.currentScript,
    mySrc = myScript.getAttribute('src');

console.log(mySrc); // "http://bla.com/js/script.js"

$(function () {
    // your other code here, assuming you use jQuery
    // ...
});

If you don't want the variable to be exposed to the global scope, you can also do this:

(function () {
    var myScript = document.currentScript,
        mySrc = myScript.getAttribute('src');

    console.log(mySrc); // "http://bla.com/js/script.js"

    $(function () {
        // your other code here
        // ...
    });
}()); // self-executing anonymous function

Basically the point is to make sure and access document.currentScript during synchronous execution of the script, otherwise it will not reference what you expect it to.

Upvotes: 19

bradt
bradt

Reputation: 531

var JS_SELF_URL = (function() {
    var script_tags = document.getElementsByTagName('script');
    return script_tags[script_tags.length-1].src;
})();

As the browser parses tags, it also downloads and executes them. Therefore when your JS file is executed it is currently the last tag parsed.

Upvotes: 6

Toby
Toby

Reputation: 301

With Jquery, you could do something like:

$('script[src$="my_script.js"]').attr('src').replace('my_script.js','');
// outputs something like: "/static/js/"

Upvotes: 7

sid3k
sid3k

Reputation: 225

Stack property of error objects can provide URL information.

try 
{ 
  throw new Error();
}
catch(exc)
{
  console.log(exc.stack);
}

Unfortunately, Webkit doesn't (but Chromium does) support stack property. There are a few browsers supporting this feature: http://173.45.237.168/reference/html/api/Error.html#Error.stack

Instead of stack, Webkit provides sourceURL property, here is the exampe usage:

try 
{ 
  throw new Error();
}
catch(exc)
{
  console.log(exc.sourceURL);
}

Upvotes: 0

Grant Wagner
Grant Wagner

Reputation: 25941

Add an ID to the script tag:

<script type="text/javascript" id="myScript" src="http://bla.com/js/script.js"></script>

And in http://bla.com/js/script.js:

var myScript = document.getElementById('myscript');
var myScriptSrc = myScript.getAttribute('src');
alert(myScriptSrc); // included for debugging

You should be able to manipulate the value of myScriptSrc to obtain the path to any other content on bla.com.

I think this sample is what James Black meant in his answer.

Lastly, to everyone suggesting the use of document.location, please keep in mind that if you want read-only access to the current page address, you should be using document.URL or window.location. If you want to set the page address, you should always use window.location.href. Although window.location = 'location'; works, it has always bothered me to see a String being assigned to a Location. I'm not sure why since JavaScript allows all sorts of other implicit type conversions.

  • mozilla reference: document.location was originally a read-only property, although Gecko browsers allow you to assign to it as well. For cross-browser safety, use window.location instead. To retrieve just the URL as a string, the read-only document.URL property can be used.
  • Sun reference: Do not use location as a property of the document object; use the document.URL property instead. The document.location property, which is a synonym for document.URL, is deprecated.

Upvotes: 21

James Black
James Black

Reputation: 41848

You could look in the script tag for the javascript location, and by using document.location you could probably determine the relative addressing, in order to determine where the css file may be.

Upvotes: 0

bjelli
bjelli

Reputation: 10100

You can read document.location, but you could also just use relative URLs

Upvotes: -1

Related Questions