tobbe
tobbe

Reputation: 1807

get relative URL with javascript

Is there an easy way to get the relative url with javascript? Im trying to use window.location.href but it returns the absolute path.

What im trying to do is this: I have two pages; mobile.html and desktop.html. I want to use ONE javascript-file to detect whether the user is on a mobile or desktop (I know, this is not a very good way to do it..) like this:

var is_mobile = //alot of text from http://detectmobilebrowsers.com/
                //that returns true/false, this works fine

if (is_mobile){

    if (window.location.href != "mobile.html"){
        window.location = "mobile.html";
    }
}

else {
    if (window.location.href != "desktop.html"){
        window.location ="desktop.html";
    }
}

So the problem with absolute path is that when testing either mobile/desktop.html they both go into infinite loop pagerefresh..

Upvotes: 4

Views: 13408

Answers (5)

Adam Gawne-Cain
Adam Gawne-Cain

Reputation: 1690

Here is @m93a's answer adapted to work without modifying the URL class, and with typescript types...

/**
 * Returns relative URL from base to target.
 * @param target
 * @param base
 * @param reload `false` to use "#" whenever the path and query of this url and the base are equal,
 *               `true` to use filename or query (forces reload in browsers)
 * @param root   `true` to force root-relative paths (e.g. "/dir/file"),
 *               `false` to force directory-relative paths (e.g. "../file"),
 *               `undefined` to always use the shorter one.
 * @param dotSlash whether or not to include the "./" in relative paths.
 */
export function uriRelativize(target: string | URL, base: string | URL, reload?: boolean, root?: boolean, dotSlash?: boolean): string {
    if (!(target instanceof URL))
        target = new URL(target);
    if (!(base instanceof URL))
        base = new URL(base);

    reload = !!reload;
    dotSlash = !!dotSlash;

    var rel = "";

    if (target.protocol !== base.protocol) {
        return target.href;
    }

    if (target.host !== base.host ||
        target.username !== base.username ||
        target.password !== base.password) {

        rel = "//";

        if (target.username) {
            rel += target.username;
            if (target.password)
                rel += ":" + target.password;
            rel += "@";
        }

        rel += target.host;
        rel += target.pathname;
        rel += target.search;
        rel += target.hash;

        return rel;

    }

    if (target.pathname !== base.pathname) {

        if (root) {
            rel = target.pathname;
        } else {

            var thisPath = target.pathname.split("/");
            var basePath = base.pathname.split("/");
            var tl = thisPath.length;
            var bl = basePath.length;

            for (var i = 1, l = Math.min(tl, bl) - 1; i < l; i++) {
                if (thisPath[i] !== basePath[i]) {
                    break;
                }
            }

            for (var cd = bl - 1; cd > i; cd--) {

                if (!rel && dotSlash) {
                    rel += "./";
                }

                rel += "../";
            }

            if (dotSlash && !rel)
                rel += "./";

            for (l = tl; i < l; i++) {
                rel += thisPath[i];
                if (i !== l - 1) {
                    rel += "/";
                }
            }

            if (root !== false && rel.length > target.pathname.length) {
                rel = target.pathname;
            }

            if (!rel && basePath[basePath.length - 1]) {
                rel = "./";
            }

        }
    }

    if (rel || target.search !== base.search) {
        rel += target.search;
        rel += target.hash;
    }

    if (!rel) {
        if (reload) {
            rel = target.search || "?";
            rel += target.hash;
        } else {
            rel = target.hash || "#";
        }
    }
    return rel;
}

Upvotes: 0

csha
csha

Reputation: 9564

URL.getRelativeURL

There's a bullet-proof public-domain extension for the standard URL object called getRelativeURL.

This would solve the problem for you:

var loc = new URL(location.href); //get the current location
var dir = new URL(".", loc); //get the current directory
var rel = loc.getRelativeURL(dir); //relative link from dir to loc

if( rel !== "mobile.html" ){ ... }

Try it live. View on Gist.

Upvotes: 0

Trevor Dixon
Trevor Dixon

Reputation: 24352

var page = window.location.pathname.split('/').pop();

if (isMobile && page !== 'mobile.html')
    window.location = 'mobile.html';
else if (!isMobile && page !== 'desktop.html')
    window.location = 'desktop.html';

Upvotes: 6

Zafer
Zafer

Reputation: 2190

Another solution to find out whether the location.href ends with mobile.html or not, without using regular expressions:

if(window.location.href.indexOf("mobile.html") != (window.location.href.length - "mobile.html".length)) {
  ..
}

Upvotes: 1

bfavaretto
bfavaretto

Reputation: 71918

Just test if it ends with either HTML file. You could use regular expressions:

if(/desktop\.html$/.test(window.location.href)) {
     // code for desktop
} else if(/mobile\.html$/.test(window.location.href)) {
     // code for mobile
}

Upvotes: 1

Related Questions