Forum Moderators: open
The code structure is something like:
<ul id="tabs">
<li><a href="#mast_articles">Articles</a></li>
<li><a href="#mast_property">Property</a></li>
<li><a href="#mast_jobs">Jobs</a></li>
<li><a href="#mast_products">Products & Services</a></li>
</ul>
<div id="mast_articles">Articles</div>
<div id="mast_property">Property</div>
<div id="mast_jobs">Jobs</div>
<div id="mast_products">Products & Services</div> The list items get turned into tabs, but for users without Javascript they stay as links through to the appropriate box. Previously I had:
onclick="switchTab(); return false;" The return false cancelled the href action and everyone was happy. Now, I'm using something like:
addEvent(tab,'click',switchTab); to add the switching mechanism, but that doesn't allow me to add the return false. I've tried adding it to the end of the switchTab function but of course that doesn't get passed through to the link.
Any ideas?
/* Add the an event arg, e, if not already present */
function switchTab(e)
{
/* --code 'n' stuff--*/
/* Cancel default action */
preventDefault(e);
}
/* Handy XB function
Replace corrupted ¦¦ chars
*/
function preventDefault(e)
{
e = e¦¦event;
if(e.preventDefault) e.preventDefault();
else e.returnValue = false;
}
function addEvent(obj, evType, fn){
if (obj.addEventListener){
obj.addEventListener(evType, fn, false);
return true;
} else if (obj.attachEvent){
var r = obj.attachEvent("on"+evType, fn);
return r;
} else {
return false;
}
} Could you run through your little prevent default script? I'm not a JS expert and tend to get lost in scoping issues. Thanks!
Could you run through your little prevent default script?
The name of the game is normalisation between standards & IE.
(1)
<p onclick="myFunction(event)"> (2)
myElm.onclick = myFunction (3)
a:
myElm.addEventListener("click", myFunction) myElm.attachEvent("onclick", myFunction) [pre]function myFunction(e)
{
// blah
}[/pre] In myFunction...
(1) e is the event object in all browsers (for slightly different reasons).
The variable name, event, must be used in the event handler.
(2) e is undefined in IE.
(3) e is the event in all browsers (I believe in IE too)
Written more succinctly this time..
[pre]function preventDefault(e)
{
e=e¦¦event;
e.preventDefault? e.preventDefault() : e.returnValue = false;
}[/pre] Since we're not sure of getting the event passed through all the time in IE, we normalise:
e=e¦¦event In JS logic, this sets
e to itself if it is defined, if not, e is set to the value of the global variable, event. (Different approach, same effect: if(!e)e=event;) e.preventDefault? e.preventDefault() : e.returnValue = false; Similar JS boolean logic. If e.preventDefault is defined (
e has a preventDefault method) then we use it, else we assume it is an IE event and set its returnValue to false. I don't like attachEvent. The attached function doesn't execute in the context of the element (ie
this doesn't point to the element). Being Mac-less, I'm in the dark as regards Safari. It's just a slightly unsettling mystery to me.
An even less (far less) obtrusive method would be to pick up the events when they bubble up to the document, but I've written enough blah already.
Unfortunately my company requires our sites to be Safari 1.0+ compatible. It seems (from my limited attempts so far) that modern JS is in a similar position to CSS 5 or 6 years ago - a morass of incompatible implementations with the shining cliffs of DOM a mere dot on the horizon. My problem is that not very many of the samples out there take account of Safari and even less take account of IE5.2 on the mac, which unfortunately makes it useless for me to try and integrate them into my work :(
Looks like I'll have to practise DOM in my spare time then.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>tst_436_This+Evt.htm</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<style type="text/css">
</style>
<script type="text/javascript">
window.onload=function(){
document.getElementById('aOne').onclick=testThis;
document.getElementById('aTwo').onclick=testPrev;
}
function testThis(){
if(window.addEventListener){
alert('Stds comp \n'+this.id);
return false;
}else if(window.attachEvent){
alert('IE \n'+this.id);
}
}
function testPrev(e){
e=e¦¦event;
e.preventDefault? e.preventDefault() : e.returnValue = false;
}
</script>
</head>
<body>
<p>
<a href="#" id="aOne">test "this"</a>
</p>
<p>
<a href="tst_436b_This+Evt.htm" id="aTwo">test preventDefault/returnValue</a>
</p>
</body>
</html>
On Firefox, Opera, and Konqueror 3.3.2 the first test correctly identified the id of the 'this' entity through the addEventListener applied alert. Of course, IE also correctly identified the id, as well.
On all of the above, the code in the testPrev function prevented the link from being executed. This suggests that current versions of Safari should, as well. I have yet to find something that Konqueror can do that Safari can't. On rare occasion, the converse is true, though only until Konqueror is updated.
Which brings us to: Mr. Marx, you needn't search out a fleshy fruit to be reasonably assured of what will run on Safari. Simply install Linux in a partition on your Windoze machine, dual boot, and use the KDE web editor, Quanta Plus for your tests. Quanta is an excellent editor and it uses Konqueror for its preview engine. I would recommend Xandros for a first-timer coming from the MS world (http://www.xandros.com/about/downloads.html), though Kubuntu (http://www.xandros.com/about/downloads.html) is a servicable alternative, a bit less familiar to fans of the Evil Empire, though.
As I have advised many a new convert to the penquin's ranks, about the only thing you have to get used to is file permissions.