In CSS, any image path is relative to the CSS file location.
f.ex if I put the CSS file in /media/css/mystyles.css
and use something like
Searching the DOM for your own <script>
tag as above is the usual method, yes.
However, you usually needn't search too hard: when you're in the body of the script — run at include-time — you know very well which <script>
element you are: the last one. The rest of them can't have been parsed yet.
var scripts= document.getElementsByTagName('script');
var path= scripts[scripts.length-1].src.split('?')[0]; // remove any ?query
var mydir= path.split('/').slice(0, -1).join('/')+'/'; // remove last filename part of path
function doSomething() {
img.src= mydir+'../images/myimage.jpeg';
}
This doesn't hold true if your script has been linked with <script defer>
(or, in HTML5, <script async>
). However, this is currently rarely used.
On more recent browsers, you can use the document.currentScript property to obtain the HTMLScript
element corresponding to that script, then query its src
property.
Can I use indicates support by 70% of the web’s users, at the time of this writing. Apparently Internet Explorer doesn’t support it, but Edge does. MDC lists support as Chrome 29+, Edge, Firefox 4.0+, Gecko 2.0+, Opera 16+ and Safari 8+. The comment by @mjhm already pointed out this feature, but back then it sounded very experimental.
One way is to put the path in the script itself:
var scriptPath = <?PHP echo json_encode(dirname($_SERVER['SCRIPT_NAME'])); ?>;
Inspired by bobince answer above, I wrote a jQuery version. Here is the code in one line:
var scriptpath = $("script[src]").last().attr("src").split('?')[0].split('/').slice(0, -1).join('/')+'/';
Edit: Filter the script
tag by the src
attribute, so that we get a src to work on.
As other posters mentioned you need to compute your base url for the script first, you can the script below to find it.
// find the base path of a script
var settings = {};
settings.basePath = null;
if (!settings.basePath) {
(function (name) {
var scripts = document.getElementsByTagName('script');
for (var i = scripts.length - 1; i >= 0; --i) {
var src = scripts[i].src;
var l = src.length;
var length = name.length;
if (src.substr(l - length) == name) {
// set a global propery here
settings.basePath = src.substr(0, l - length);
}
}
})('myfile.js');
}
log(settings.basePath);
NOTE that all the samples on this question take LAST tag occurrence, and as pointed out not supporting async loading. so if you want to do it perfect manner, you should be matching YOUR script name ADDITIONALLY. in fact scriptaculous does that.
just it's a problem that the "incomplete" code is highlighted and projects like http://areaaperta.com/nicescroll/ use that version of the code