IE not marking links as "visited" when rendered via javascript

I am working with a site where all content is rendered via ajax postbacks using jquery. I am using Ben Alman's hashchange (http://benalman.com/projects/jquery-hashchange-plugin/) to manage the hash history which allows me to bookmark pages, use the back button etc... Everything works perfectly on everything but IE 9 of course. In IE there is a small issue with "visited" links not being marked as visited. You can see that the link turns purple(visited) for a split second after you click it before the new content is loaded. But once you click the back button the link appears as though it has never been visited. Here is a jfiddle example of what I am talking about: http://jsfiddle.net/7nj3x/3/

Here is the jsfiddle code assuming you have jquery and the hashchange plugin referenced in head:

$(function(){
  // Bind an event to window.onhashchange that, when the hash changes, gets the
  // hash and adds the class "selected" to any matching nav link.
  $(window).hashchange( function(){
    alert("Hash changed to:"+location.hash);  
    var hash = location.hash;
    // Set the page title based on the hash.
    document.title = 'The hash is ' + ( hash.replace( /^#/, '' ) || 'blank' ) + '.';
    //simulate body being rendered by ajax callback 
      if(hash == ""){  
        $("body").html("<p id='nav'><a href='#test1'>test 1</a> <a href='#test2'>test 2</a> <a href='#test3'>test 3</a></p>");
      }
      else{
        $("body").html("Right click within this pane and select \"Back\".");  
      }
  })
  // Since the event is only triggered when the hash changes, we need to trigger
  // the event now, to handle the hash the page may have loaded with.
  $(window).hashchange(); 
});

Answers


You can simply use IE conditional comments to load a specific style:

<!--[if IE]>
  a:visited {
     padding-left: 8px;
     background: url(images/checkmark.gif) no-repeat scroll 0 0;
}
<![endif]-->

Why not setup a code block only to be used by IE that sets the value of a hidden input tag to reflect the click behavior. If a link is clicked you could set the value of the input tag equal to that link id and allow you js to update the elements class to reflect the change.

HTML if IE
<input type="hidden" id="clicked_link" />


JQuery JS if IE
$(function() {
    $(a).click(function() {
        $(this).attr('id').addClass('visited_link_class');
    });
});

CSS
.visited_link_class { color:#your color;}

Maybe if you create the proper elements and building a DOM segment before appending it to the document.

Not sure it would work, can't test it here, but here goes my try adapting your code.

$(function(){
  // Bind an event to window.onhashchange that, when the hash changes, gets the
  // hash and adds the class "selected" to any matching nav link.
  $(window).hashchange( function(){
    alert("Hash changed to:"+location.hash);  
    var hash = location.hash;
    // Set the page title based on the hash.
    document.title = 'The hash is ' + ( hash.replace( /^#/, '' ) || 'blank' ) + '.';
    //simulate body being rendered by ajax callback 
      if(hash == ""){  
        $("body").html(
          $("<p>").id("nav")
            .append($("<a>")
              .attr("href","#test1")
              .text("teste 1"))
            .append($("<a>")
              .attr("href","#test2")
              .text("test 2"))
            .append($("<a>")
              .attr("href","#test3")
              .text("test 3"))
        );
      }
      else{
        $("body").text("Right click within this pane and select \"Back\".");  
      }
  })
  // Since the event is only triggered when the hash changes, we need to trigger
  // the event now, to handle the hash the page may have loaded with.
  $(window).hashchange(); 
});

Try to consider css LVHA roles, which means the order of an a tag pseudo class matters.

First time to define those class:

  • A:link
  • A:visited
  • A:hover
  • A:active

If this still did not solve your problem, you can use another js router(hashchange): https://github.com/flatiron/director I used this one a lot and it works perfectly in many situations.


An option would be to also fake the browser history using the HTML5 history API. This way only after deleting the browser history the link will be 'unvisited'.

Like said on this useful page:

[...] method above switches out the URL in the address bar with '/hello' despite no assets being requested and the window remaining on the same page. Yet there is a problem here. Upon hitting the back button we'll find that we don't return to the URL of this article but instead we'll go back to whatever page we were on before. This is because replaceState does not manipulate the browser's history, it simply replaces the current URL in the address bar.

So like also mentioned on that page you'll have to do a:

history.pushState(null, null, hash);

 You can simply use IE conditional comments to load a specific style:    
<!--[if IE]>
      a:visited {
         padding-left: 8px;
         background: url(images/checkmark.gif) no-repeat scroll 0 0;
    }
<![endif]-->

This is a security feature in ie. The functionality of :visited has been restricted in many modern browsers to prevent CSS exploit. Hence, there's no workaround for this issue.


Need Your Help

Good Git deployment using branches strategy with Heroku?

ruby-on-rails git deployment heroku

What is a good deployment strategy to use with Git + Heroku (Ruby on Rails)?

Inheritance from multiple interfaces with the same method name

c# inheritance methods interface multiple-inheritance

If we have a class that inherits from multiple interfaces, and the interfaces have methods with the same name, how can we implement these methods in my class? How can we specify which method of which