0

The website that I am working on has a <base> tag point to a different URL than the one that the website has. What I would like to do is get around the <base> tag by using the trueURL bellow to find the url of the webpage, because i need it to construct some internal anchors, because i need the actual url of the website so the internal anchors work correctly.

The issue that im having is that i don't know how i should use the url that i store in my trueURL variable. Is it possible to use it and then add extra extensions to the url to get it to point to my anchors? Below is a rough example of what I would like to be able to do

var trueURL = window.location.href;

    <html>

    <ol>
        <li>
            <a href= [trueURL] + "#link1">Link1</a>
        </li>

        <li>
            <a href= [trueURL] + "#link2">Link2</a>
        </li>

        <li>
            <a href= [trueURL] + "#link3">Link2</a>
        </li>
    </ol>

    </html>

Therefore in the end i would like to have a link that looks like trueURL#link3.

Thanks in advance,

:D :D

sSmacKk
  • 1,033
  • 4
  • 15
  • 30
  • You don't need to add [trueURL] in your href property. It will automatically append #link to your existing browser URL. – Chinmayee G Sep 07 '12 at 08:56
  • I dont see what you want to get around, if you are using the a tag, you dont need the trueURL. Can you make an example in jsfiddle.net of what you try to achieve? Then we mabye could help you out. – mattematico Sep 07 '12 at 15:52
  • sorry, i realize that i didnt ask my question correctly, i hope my reformulation is better than the previous version. – sSmacKk Sep 08 '12 at 08:40
  • possible duplicate of [How to override tag without removing the tag itself?](http://stackoverflow.com/questions/12303241/how-to-override-base-tag-without-removing-the-tag-itself) – Pointy Sep 10 '12 at 17:19

4 Answers4

2

I am working on the assumption that your real case is more complex than your example. If it isn't, then review the other answers, which may be more appropriate for what you need to do.

What this will do is...

  1. Run on the window load event a function that will...
  2. Find every element in the DOM that is an A tag, and...
  3. Loop through those found A tags and check if the element has an enhance class, and if so...
  4. Split the href at the # to get the current a element's hash value, which we will...
  5. Combine it with the following:

    '//' + location.host + location.pathname;
    

    Giving us the current page's URL without a hash or query string. If you want the query string (what's after the ? in a URL), add location.search:

    '//' + location.host + location.pathname + location.search;
    

Note, the // part is protocol relative, so it will use whatever the base href's protocol is, e.g., http or https. You may want to specify that, however.

Markup

Note the class attribute, which we will use to identify which a tags to manipulate.

<ol>
    <li>
        <a href="#link1">Link 1</a> - 
        No enhance class, should be subject to <strong>BASE HREF</strong>: 
        <strong class="p">&raquo; http://example.com#link1</strong>
    </li>
    <li>
        <a href="#link2" class="enhance">Link 2</a> - 
        Has enhance class, should be:
        <strong class="p">&raquo; http://fiddle.jshell.net/_display/#link2</strong>
    </li>
    <li>
        <a href="#link3" class="enhance">Link 3</a> - 
        Has enhance class, should be:
        <strong class="p">&raquo; http://fiddle.jshell.net/_display/#link3</strong>
    </li>
    <li>
        <a href="#link3" class="enhance">Link 4</a> - 
        Has enhance class, should be:
        <strong class="p">&raquo; http://fiddle.jshell.net/_display/#link4</strong>
    </li>
</ol>​

Javascript

//--
// window.onload is not preferred, window.addEventListener
// should be used. Except that only IE9 supports it, and
// IE8 and lower do not support it, and uses window.attachEvent
// instead, which you can test for. 
//
// I'm using window.onload here simply as a shortcut method and
// for clarity. This can also go in a script tag at the bottom
// of the body tag, in which case you can remove window.onload
// and use a self-calling anonymous function like:
//
//     (function updateLinks(){... all the same as below ...})();
//
// This will ensure you are out of the global variable scope.
//--
window.onload = function updateLinks() {
    //--
    // Modern browsers can use document.getElementsByClassName
    // or you can use a shiv script to add it to browsers that 
    // don't. I'll do it the "manual" way here, and this works
    // cross-browser. The downside is that it will interate 
    // through every A tag on the page, looking for the "small"
    // few that have the el.className we're looking for here.
    //--
    var els = document.getElementsByTagName("a"),
        l = els.length,
        trueURL = '//' + location.host + pathname,
        i, el, hash;

    for (i = 0; i < l; i++) {
        el = els[i];

        if (el.className.indexOf("enhance") != -1) {
            hash = el.href.split('#');
            el.href = trueURL + "#" + hash[1];
        }
    }
};

http://jsfiddle.net/userdude/unnH8/

Mouseover the links to see the current setting. As always, thoroughly test with real markup in multiple browsers.

Jared Farrish
  • 46,034
  • 16
  • 88
  • 98
Jeremy J Starcher
  • 21,760
  • 5
  • 48
  • 70
  • Not trying to steal your thunder, since this is identical to my own answer I just posted except it uses the technique that is less efficient but better supported. My answer was originally for the closed duplicate. – Jared Farrish Sep 10 '12 at 17:38
  • I did some pretty heavy editing to improve the answer, which had a few issues (as pointed out, it was off the cuff). Feel free to rollback if you don't want it or like it. I also posted a fiddle demo. – Jared Farrish Sep 11 '12 at 03:45
1

If you are serious about trueURL = window.location.href then you are working WAY too hard.

Just make the link #link1 - it automatically will be relative to the current href.

If that was just an example, you may be interested in the:

<BASE href="...">

tag. This will let you change the relative href for all links in the page at once.

And you can do it with javascript by getting each <A...> DOM element and modifying the href property.

Ariel
  • 23,798
  • 4
  • 53
  • 68
1

First, if you're not using base yet or are but can switch away from using it, please read:

Is it recommended to use the <base> html tag?

Which will give you many good reasons to think twice. Moral of the story: It's usually a bad idea to use base. There are good reasons, and it is useful; I have used it to great delight many times when working with designers to have local copies of the markup that I can work with but still maintain connections back into the site's assets. But for production sites, it's too clever by half.

Also, this answer was originally written for a different question that was an exact duplicate, so I'm posting this here, although there's an answer that's very similar to it already.


Do you have control over the markup or can you use a selector to get only the elements you want to effect? You could:

HTML (Note the class truelink.)

<ol>
    <li>
        <a href="#link1" class="truelink">True Link1</a>
    </li>
    <li>
        <a href="#link2" class="truelink">True Link2</a>
    </li>
    <li>
        <a href="#link3" class="truelink">True Link3</a>
    </li>
</ol>

Javascript

​window.addEventListener('load', function links(){
    var base = document.getElementsByTagName('base')[0],
        links = document.getElementsByClassName('truelink'),
        l = links.length,
        uri = 'http://www.host.tld/path?query=test';

    console.log('Base:', base, ', True Links:', links);

    console.log('Modifying links in five seconds...');

    setTimeout(function go(){
        console.log('Modifying links now...');

        while (l--){
            links[l].href = links[l].href.replace(base.href, uri);
        }

        console.log('Base: ', base, 'True Links: ', links);
    }, 5000);
});​

http://jsfiddle.net/M5Hdk/

Keep in mind that this technique demonstrates using document.getElementsByClassName, which is not supported by IE until version 9. If you have to support lower versions than IE9, see Jeremy J Starcher's answer for a less "efficient" but better supported method. There's also document.querySelectorAll, which is supported by IE8 and above and all other major browsers. If you only need to support IE8, I would suggest using this to select your links over the method Jeremy demonstrates.

I also delay the change for five seconds so you can see it work. Obviously, this won't be necessary for you (most likely).

The only thing I'm not sure about right now is whether or not my .replace() will always find the base.href to replace in all browsers, so it may be better to detect the presence of a relative url before doing a replace, so you can do whatever else appropriately. For some related background on this possible "issue", see my question that deals with how browsers handle href attributes differently in the DOM:

Method for selecting elements in Sizzle using fully-qualified URLs

Also, this will perhaps work most seamlessly if it falls in an inline script tag right after the content, or at the end of body tag, in which case you will want to remove the window.addEventListener part and replace with a self-executing function.

Their are other options, all are probably a little more problematic:

  • Blow away the base tag altogether. If you do this, though, you'll first want to check if you need to manually insert the base.href content into the links, otherwise I'm sure things can break or become brittle.
  • Add an event listener to the a links you want to use your true link and manipulate it that way onclick, just don't forget to return false at the end of the click handler function, so the browser doesn't follow the link. This is probably the most seamless method, but is probably not best for all situations.
  • Probably others.

Be sure to test with real world markup. base is a mildly quirky tool, so manhandling it may lead to unusual side effects. You were warned.

Community
  • 1
  • 1
Jared Farrish
  • 46,034
  • 16
  • 88
  • 98
0

I would have done it this way

HTML

<ol>
    <li>
        <a class="build">Link1</a>
    </li>

    <li>
        <a class="build">Link2</a>
    </li>

    <li>
        <a class="build">Link2</a>
    </li>
</ol>​

Javascript/Jquery

$(function(){
    var trueURL = window.location.href;
    var i = 1;
    $('a.build').each(function(){
        $(this).attr('href', trueURL + '#link' + i);
        i = i+1;
    });
});

Example of working code Here

mattematico
  • 679
  • 3
  • 14