Adding your email with Javascript
An often used method to put your email address on your site in a spam-proof manner is by using Javascript. Advantage of this method is that it is pretty much transparent to the end user, they can see and click on your email address just as always, while the spambot can’t make heads or toes of it. The downside is that it uses Javascript, so people must have a browser which supports it (all modern browsers do), and have it enabled.
Some of the script’s features:
- It works in XHTML.
- You can import the script once in the head, and run it from the document’s body tag. No need for scripting inside your document.
- Apply easily by setting a ‘myemail’ class on a span tag.
- There is no need for
<noscript>
tags.
To enable the script, you have to first fill in your email address in the script’s eml variable, then include the script in your document, add onload="putEmail();
to the document’s <body>
tag, and finally put <span class="myemail">(need Javascript for email link)</span>
(or something similar) everywhere you want to show your address. An example XHTML document is given below.
The code
// // Email address link javascript (by Grauw) // ============================= // Using standard DOM methods working in an XHTML environment. // // License: Public Domain (but feel free to mention my name ;)) // // Usage: // * Fill in your email address in the variable ‘eml’ below, // * Put a tag with class="myemail" where you want the link, // * Add onload="putEmail();" to your <body> tag. // function putEmail() { var eml = 'email' // The email address... eml += '@' eml += 'domain.com' var link = document.createElement("a"); link.setAttribute("href", "mailto:" + eml); link.appendChild(document.createTextNode(eml)); var spans = getElementsByClass("span", "myemail"); for (var i = 0; i < spans.length; i++) spans[i].parentNode.replaceChild(link.cloneNode(true), spans[i]); } // // Returns an array of elements with the given class // function getElementsByClass(elem, classname) { var classes = new Array(); var alltags = document.getElementsByTagName(elem); for (i = 0; i < alltags.length; i++) if (alltags[i].className == classname) classes[classes.length] = alltags[i]; return classes; }
Example XHTML code using this script, with the important bits highligted:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Email script test</title> <script type="text/javascript" src="email.js"></script> </head> <body onload="putEmail();"> <p>Email: <span class="myemail">(need JavaScript for email link)</span></p> </body> </html>
Some explanation of the code…
Let’s go in some more detail about what this script does. It’s fairly simple really, so I’ll keep it short.
function putEmail() { var eml = 'email' // The email address... eml += '@' eml += 'domain.com'
As the comment says, this is the email address you would want to insert. Putting it like this ensures that a spambot can not recognize it.
var link = document.createElement("a"); link.setAttribute("href", "mailto:" + eml); link.appendChild(document.createTextNode(eml));
This piece of code first creates an <a>
tag, then adds a href
attribute to it with the contents "mailto:"
+ the email address (so now there is a link the user can click on), and finally puts the email address as text inside it as well (to show to the user). This is the email link, however it has not been placed in the web page yet.
var spans = getElementsByClass("span", "myemail"); for (i = 0; i < spans.length; i++) spans[i].parentNode.replaceChild(link.cloneNode(true), spans[i]); }
This part of the script first collects all <span>
elements which have the ‘myemail’ class set, and then replaces each of them with a copy (‘clone’) of the link.
function getElementsByClass(elem, classname) { var classes = new Array(); var alltags = document.getElementsByTagName(elem); for (i=0; i<alltags.length; i++) if (alltags[i].className == classname) classes[classes.length] = alltags[i]; return classes; }
The final part of the script is the getElementsByClass
function used earlier in the script. Basically what this does is take all tags specified in the first parameter (in our case, ‘span’), and then look through all of them to see which have a matching classname. The ones which have are added to a result list, which is passed back to the calling function.
Note that instead of ‘span’ one could also choose another element, or you could even use ‘*’ (‘all elements’) meaning that it does not matter on which element you put the ‘myemail’ class. Small problem with ‘*’ is that it does not work in Internet Explorer 5, so if that is important to you, don’t use it. But unless you need it, you shouldn’t really use ‘*’ anyway, because it’s a bit slower.
Making it work in Internet Explorer 5
Note that I don’t see much point in this – few people are still using IE5 anyway and their numbers are decreasing rapidly (for indicative stats look at the W3Schools' browser statistics). But for the sake of it, here we go:
There is one issue with Internet Explorer 5 which prevents this from working, and that is that IE5 does not support the replaceChild
method. There are two alternatives however: the first is to use appendChild
instead, which IE5 supports. Downside of this is that it actually adds the link to the <span>
’s contents instead of replacing it, so the ‘noscript’ functionality kind of gets lost. This is what you need to change:
for (i = 0; i < spans.length; i++) spans[i].appendChild(link.cloneNode(true));
The second alternative can be found in a nonstandard extension Microsoft made called replaceNode
. This one is supported on their older browsers, so the following addition should be enough to get everything working:
for (i = 0; i < spans.length; i++) document.replaceNode ? spans[i].replaceNode(link.cloneNode(true)) : spans[i].parentNode.replaceChild(link.cloneNode(true), spans[i]);
It checks if replaceNode
is supported, and if so uses that instead. And yes, I realize replaceNode
actually looks a lot nicer than the stuff we have to do for replaceChild
, but a standard isn’t a standard for nothing, and replaceNode
isn’t in it (and hence not supported on most if not all non-IE browsers). :)
Well, that’s about all there is to say about this.