Forum Moderators: open
I need to trigger some javascript to toggle the visibility of a div when a hyperlink is clicked. I have read several articles which suggest that an onClick handler function that returns false is a reliable cross-browser way of preventing the default action triggered by a page element (in this case loading the url in the href).
However despite assurances of this working cross browser all the way down to and including IE4, it doesn't seem to work on IE6 or even IE7. Both of these browsers execute first the onClick function and then the default action. Here is some simple code to illustrate:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
<title>onClick override test</title>
<meta http-equiv="content-type" content="text/html" />
<style type="text/css">
#scrollbox { height: 1000px; background: #FFFFCC; }
</style>
<script type="text/javascript">
function doNothing() { return false; }
</script>
</head>
<body>
<div id="scrollbox"></div>
<p>If you have JS enabled, the page should not scroll to the top when you <a href="#" onClick="return doNothing()">click this link</a>.</p>
</body>
</html>
Of course this works on pretty much every browser except IE, but that's not really good enough to be considered "cross-browser". It also fails with the simpler:
<a href="#" onClick="return false">
In my desperation I have also tried the IE proprietary:
function doNothing(e) {
e.returnValue = false;
return false;
}
and even
function init() {
var lnk = document.getElementById('foo');
lnk.addEventListener('click', doNothing, false);
lnk.attachEvent('click', doNothing, false);
}
...
<body onLoad="init()">
...
<a id="foo" href="#" onClick="return doNothing()">
...
Any explanation of any point I might be missing or some way to make IE behave like a civilized browser would be much appreciated.
Cheers,
Scott
Yes, I've definitely got JavaScript enabled in the IE browsers. In the actual application (rather than the stripped down trivial example presented here) both IE6 and IE7 correctly execute the DHTML function which toggled the DIV, but both go on to scroll the browser back up to the top.
In another example, if I have an actual URL in the href and call a function that opens a popup window using the same URL and returns false, Firefox will open the popup and leave the original page alone, but IE opens the popup AND loads the URL into the original page.
The presented example really works for you? It doesn't scroll the page back to the top in your IE?
Thanks,
Scott
The return value is ignored by some versions of IE6 and some versions of IE7 in a totally inconsistent way. The only explanation that seems to fit is that it is the result of some automatic Windows update.
Finally, I have two workable solutions to the problem.
The simpler way is to add event.returnValue = false to make it work in IE, and follow that up with return false for everyone else.
<a href="#" onclick="doSomething(); event.returnValue = false; return false;">click this link</a>
And then there is the much more convoluted but more OOP method of attaching events at onLoad (which of course requires harvesting the element/s to change and using different methods for IE and everyone else):
function preventDefaultAction(evt) {
if (evt) {
if (typeof evt.preventDefault!= 'undefined') {
evt.preventDefault(); // W3C
} else {
evt.returnValue = false; // IE
}
}
// safey for handling DOM Level 0
return false;
}function doSomething(evt) {
alert('do something cool');
return preventDefaultAction(evt);
}
function init() {
var target = document.getElementById('target');
if (target.addEventListener) { // use addEventListener for DOM
target.addEventListener('click', doSomething, false);
} else if (target.attachEvent) { // use attachEvent for IE
target.attachEvent('onclick', doSomething);
}
}
<body onLoad="init()">
<div id="scrollbox"></div>
<p>If you have JS enabled, the page should not scroll to the top when you <a id="target" href="#">click this link</a>.</p>
</body>
Hope this helps someone else,
Scott