Javascript:history.go(-1) IE6 Question?

Morning, :slight_smile:

I’m using this code to close a popup menu that pops up via the :target pseudo. <a href=“url” onclick=“javascript:history.go(-1);return false”>X</a>

Works perfect. Works with JS on or off to close the popup. And it goes back one to fix the target back button delima. BUT… it doesn’t work in IE6. Is there some different way I need to write that to make her happy?

Eric, Unfortunately IE6 has an issue where it doesn’t refresh the contents of an anchor fragment when you hit the back or forward navigation buttons (it also affects Opera previous to v10.5 surprisingly!), therefore the effects will not be visible (I’ve experimented to a great level with the :target pseudo - my new look site uses it extensively). The only way (within IE6) you would be able to invoke such a change (that I’m aware of) would be to (instead of using that yucky back button script), simply use an onclick event (attached to all anchor links) to detect what fragment is currently selected (location.hash.substr(1)) on a millisecond delay (to allow the onclick to be triggered) and then invoke the style changes you require through a script (which effectively repeats what’s in the :target CSS code). :slight_smile:

I’ve adapted what I use in my site to give you an idea:


function bootup(){
var tds = document.getElementsByTagName("a");
for( var x=0; x < tds.length; x++ ){tds[x].onclick = function(){setTimeout(process, 1);};}
}
function process(){
var current = document.getElementById(location.hash.substr(1));
if (location.hash.substr(1) == "the-hash-you-want-here") {
current.className="CSS-Class-To-Apply-Here";
}
}
window.onload=bootup;

The above detects every click event of an anchor element, runs the process function which grabs the fragment selected post the click (hence the setTimeout) and if the hash equals the fragment you want, it’ll attach a class to the element with that ID - you can use that name to put the CSS version in. It’s unobtrusive, ensures IE6 notices and makes the changes when navigation occurs, and gives IE an equal shot at :target. I’ve tested that script (I use a slightly more complex version of it in my site - which uses JavaScript conditional comments to ensure it only applies to IE - but it does the job and I know it gives effective target pseudo support for IE6, IE7, IE8 and IE9 will work with it too.) Hope the code is useful. As far as I’m aware, I’m the only person to have coded a working :target fix for IE6. :slight_smile:

Awesome - thanks Alex! But, I’m slow. Tried but I couldn’t piece it together. Can you show me please? What do I add to the closing anchor? <a href=“”>X</a> And then in your script, what do I change those two variables to? Thanks!

Eric, You don’t put anything in the anchor, you just link to it as normal, it’s unobtrusive and requires no ugly JavaScript attributes in the HTML, you put the file in the external JavaScript document, set “the-hash-you-want-here” to whatever you want the action to trigger on… such as “url” you would simply put “url” as the thing to take action on, and in “CSS-Class-To-Apply-Here” you just give it a name, and add some CSS into your Stylesheets using that class name, for example if you named it “hello”, you would add a class selector to your CSS with .hello {} and the properties you want inside… the JavaScript basically adds a class attribute to that anchor as it’s clicked (and therefore that classes CSS will run when it’s clicked) - though a word of caution, once that class is added it will remain there until it’s overwritten, I’m adding a bit of JavaScript which you will simply need to add to ensure it clears up after itself each time a links clicked. :slight_smile:

The below is the revised code:


function bootup(){
var tds = document.getElementsByTagName("a");
for( var x=0; x < tds.length; x++ ){tds[x].onclick = function(){setTimeout(process, 1);};}
}
function process(){
var current = document.getElementById(location.hash.substr(1));
if (location.hash.substr(1) == "the-hash-you-want-here") {
current.className="CSS-Class-To-Apply-Here";
} else {
var tds = document.getElementsByTagName("a");
for( var x=0; x < tds.length; x++ ){tds[x].className = "";}
}
}
window.onload=bootup;

The else {} bit is the added bit I forgot to include (I’ve got to run out the door so I was in a hurry). :stuck_out_tongue:

Summary: No onclick=“” junk needed in the HTML, just stick that code in an external JavaScript file, rename “the-hash-you-want-here” to the fragment name (“#hello” will be “hello”) and classname = the CSS class you want to use (“hello” will be .hello {} in the CSS). The script should take care of the rest! - You add an IF for each fragment your linking too which needs :target style attached to it… it’s pretty straight forward - and it’s pretty clean code too. :slight_smile:

OK, thanks Alex. I’ll try to piece that together. I already have the JS to trigger IE. From the sounds of it this JS does the same. I’ll play with. Thanks!

Huh. Call me stupid, but I still don’t get it. I know I don’t put anything in the anchor, but what do I put in the href=“”? And the “the-hash-you-want-here”. What exactly goes in there? And the CSS I need for it - why? CSS won’t close anything. This script just takes the history back one right? Sorry to be a pain, but unfortunately I think I’ll need a full working example for me to grasp this one. If not, no biggy, I don’t mind letting IE6 fall anymore.

Instead of attaching an event on to every on-page link, don’t you think that there would be less strain on the client software if there were only the one event on the body instead?


document.body.onclick = function (evt) {
    evt = evt || window.event;
    var targ = evt.srcElement || evt.target;
    if (targ.nodeType === 3) {
        targ = targ.parentNode();
    }
    if (targ.nodeName === 'A') {
         setTimeout(process, 1);
    }
};

Eric: The fragment link goes in the HREF (such as “url”) and it also goes in “the-hash-you-want-here” (just minus the # symbol - like “url”). :slight_smile:

No the history does NOT “just go back one”, I made it clear in my first post that you cannot make that work in IE6… there is no way whatsoever for Internet Explorer to know the address bar changed (you could constantly monitor the address bar for changes but that would seriously lag the end users machine ad-infinitum). The script just monitors what happens when you click an anchor link, it sees what fragment URL was selected, and then sets a CSS style (which you need to give the same values as the :target selector CSS will have in your code) - basically giving the same effect. I don’t have a working example on the web (Except my website) - but due to complexities with my own design, I had to let IE6 go and just code it to work but not be as glorified as IE7 and IE8 (you can blame positioning bugs for that).

Perhaps it might be, I’m not a JavaScript expert though so I went with what I knew would work (and in all fairness I tested it on a pretty old machine with a clunky older version of IE - and it performed the action in a millisecond). I would have thought though that monitoring the onclick on the body would have more of a long term performance hit than simply doing the grunt-work on loading the page and it performing “as-is” - especially as the design I used it on was a single page website where no refreshes or reloads need occur - so the impact is pretty minimal as the “cycle” only occurs on a singular basis. :slight_smile:

It’s one of those trade-off situations.
Where you have hundreds of, or more, links on a page, instead of the web client running checking every one of those links to see if the event occurred, only the 1 event occurs instead.

Whether one is more suitable than the other can only be properly determined by performance testing. From anecdotal evidence though, the benefits occur when 50 or more events are replaced with a single event instead.

Thanks for the clarification, I can understand the issue of looping through loads of anchors.

I guess this is one of those “trial and error” situations to determine which performs the best. :slight_smile:

Ahh… well I already have a small script that automagically triggers the :target in IE. Without needing to add the hash or classes.

This instead seems to work pretty well. It kills the back button thing. And works in in IE6/7. <a href=“url” onMouseDown=“javascript:history.go(-1)”>X</a>