Latest posts

Email encrypting with DOM scripting

I’m going to take a look at how DOM scripting can be used to encrypt an email address using the principles of progressive enhancement.

Leaving an email address naked on a page may be a great way to find the best deals on herbal viagra or learn from a nice man in Zimbabwe that you’ve inherited a big heap of cash. For most of us though, it’s a big problem and a major cause of inbox pollution.

There are many ways in which web developers try to combat the problem of spam. These range from relatively simple solutions such as using HTML entity conversion, or using images, to more sophisticated ways using pure JavaScript.

The problem with the simpler ways is that many spam bots are able to easily convert from the encryption method back to the original. The problem with more complex ways is that the email address will not appear unless JavaScript is enabled, this presents accessibility problems. Microformats are becoming more and more popular and an encryption method should ideally work when the email address is part of an hCard.

Another solution that is fairly common is to write the email address as it would read eg: “phil at example dot com”. This idea is that humans are able to read and interpret the address and spam bots are not.

One problem with this method is that users often expect to be able to click on an email address and automatically boot up their mail client. The method I explore in this article uses a combination of the “at dot com” method with some unobtrusive JavaScript to produce an email address that looks and behaves as a user would expect.

The mark-up

The email address is wrapped in a span with a class of email. This is the semantic name given to email addresses in an hCard. As we’re using a class we can have multiple email addresses on the same page.

phil at example dot com

The JavaScript

I’m using a function getElementsByClassName created by Jonathan Snook and later updated by Robert Nyman to identify all of all our spans with a class name of email. A detailed description of how this function works can be found on Robert Nyman’s site.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function getElementsByClassName(oElm, strTagName, strClassName){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all :
oElm.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
strClassName = strClassName.replace(/\-/g, "\\-");
var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
var oElement;
for(var i=0; i<arrElements.length; i++){
    oElement = arrElements[i];
    if(oRegExp.test(oElement.className)){
        arrReturnElements.push(oElement);
    }
}
return (arrReturnElements)
}

Next we need to create our function replaceEmails:

function replaceEmails() {

We now need to identify all the span elements on the page that have a class of email. We assign these to an object called emails:

var emails = getElementsByClassName(document, "span", "email");

Next we loop through all the emails and create a variable called value to hold the value of the text within the element:

1
2
for (var i=0; i<emails.length; i++){
var value = emails[i].childNodes[0].nodeValue;

We then use the replace function to replace the @, any dots and space charaters:

1
2
replacementText = value.replace(/ at /, "@");
replacementText = replacementText.replace(/ dot /g, ".");</code></pre>

Then we remove the value completely from the variable value:

emails[i].childNodes[0].nodeValue = "";

Next we create an a element, assign it to a new variable link and append our href value to it:

1
var link = document.createElement("a");    link.href="mailto:"+replacementText;

We then create a mailLink variable which will contain the value of the link text:

1
var mailLink = document.createTextNode(replacementText);

Next we append the value of mailLink to link:

1
link.appendChild(mailLink);</code></pre>

We can now insert our link into the DOM and finish off our function:

1
2
3
4
5
6
var mailLink = document.createTextNode(replacementText);
    link.appendChild(mailLink);
    emails[i].appendChild(link);
}
}
window.onload = replaceEmails;

Conclusion

When JavaScript is enabled the user will see a normal mailto: link that will behave in the way they are used to. The solution degrades gracefully if JavaScript is disabled showing the original “phil at example dot com” text.

I have tested the solution using the Operator toolbar for Firefox and the email address can be saved to the address book as normal when used as part of an hCard. With JavaScript disabled the email address will be saved as “phil at example dot com” in the address book.

Because we are using spaces either side of “at” and “dot” the solution will work if the name in the email address contains at or dot - Hattie McDaniel and Dot Cotton would have no problems. The script would need to be tweaked if your domain name is at.something, e.g phil@at.com.

The main problem with this technique, as with most other techniques, is that the more people who know about and use it, the less integrity it has as spam bots will eventually become savvy to it.

Further reading

A List Apart - Graceful E-Mail Obfuscation Roel Van Gils offers an interesting, if not rather verbose method of fighting spam.

Wikipedia - Anti-spam techniques (e-mail) A fairly comprehensive list of many popular techniques.

Phil Swan
Published in: