Naming "class" and "id" HTML attributes - dashes vs. underlines [closed] - html

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
<div id="example-value"> or <div id="example_value">?
This site and Twitter use the first style. Facebook and Vimeo - the second.
Which one do you use and why?

Use Hyphens to ensure isolation between your HTML and JavaScript.
Why? see below.
Hyphens are valid to use in CSS and HTML but not for JavaScript Objects.
A lot of browsers register HTML Ids as global objects on the window/document object, in big projects, this can become a real pain.
For this reason, I use names with Hyphens this way the HTML ids will never conflict with my JavaScript.
Consider the following:
message.js
message = function(containerObject){
this.htmlObject = containerObject;
};
message.prototype.write = function(text){
this.htmlObject.innerHTML+=text;
};
html
<body>
<span id='message'></span>
</body>
<script>
var objectContainer = {};
if(typeof message == 'undefined'){
var asyncScript = document.createElement('script');
asyncScript.onload = function(){
objectContainer.messageClass = new message(document.getElementById('message'));
objectContainer.messageClass.write('loaded');
}
asyncScript.src = 'message.js';
document.appendChild(asyncScript);
}else{
objectContainer.messageClass = new message(document.getElementById('message'));
objectContainer.messageClass.write('loaded');
}
</script>
If the browser registers HTML ids as global objects the above will fail because the message is not 'undefined' and it will try to create an instance of the HTML object. By making sure an HTML id has a hyphen in the name prevents conflicts like the one below:
message.js
message = function(containerObject){
this.htmlObject = containerObject;
};
message.prototype.write = function(text){
this.htmlObject.innerHTML+=text;
};
html
<body>
<span id='message-text'></span>
</body>
<script>
var objectContainer = {};
if(typeof message == 'undefined'){
var asyncScript = document.createElement('script');
asyncScript.onload = function(){
objectContainer.messageClass = new message(document.getElementById('message-text'));
objectContainer.messageClass.write('loaded');
}
asyncScript.src = 'message.js';
document.appendChild(asyncScript);
}else{
objectContainer.messageClass = new message(document.getElementById('message-text'));
objectContainer.messageClass.write('loaded');
}
</script>
Of course, you could use messageText or message_text but this doesn't solve the problem and you could run into the same issue later where you would accidentally access an HTML Object instead of a JavaScript one
One remark, you can still access the HTML objects through the (for example) window object by using window['message-text'];

I would recommend the Google HTML/CSS Style Guide
It specifically states:
Separate words in ID and class names by a hyphen. Do not concatenate words and abbreviations in selectors by any characters (including none at all) other than hyphens, in order to improve understanding and scannability.
/* Not recommended: does not separate the words “demo” and “image” */
.demoimage {}
/* Not recommended: uses underscore instead of hyphen */
.error_status {}
/* Recommended */
#video-id {}
.ads-sample {}

It really comes down to preference, but what will sway you in a particular direction might be the editor you code with. For instance, the auto-complete feature of TextMate stops at a hyphen, but sees words separated by an underscore as a single word. So class names and ids with the_post work better than the-post when using its auto-complete feature (Esc).

I believe this is entirely up to the programmer. You could use camelCase too if you wanted (but I think that would look awkward.)
I personally prefer the hyphen, because it is quicker to type on my keyboard. So I would say that you should go with what you are most comfortable with, since both your examples are widely used.

Either example is perfectly valid, you can even throw into the mix ":" or "." as separators according to the w3c spec. I personally use "_" if it is a two word name just because of its similarity to space.

I use the first one (one-two) because its more readable. For images though I prefer the underscore (btn_more.png). Camel Case (oneTwo) is another option.

Actually some external frameworks (javascript, php) have difficulties (bugs?) with using the hypen in id names. I use underscore (so does 960grid) and all works great.

I would suggest underscore mainly for the reason of a javascript side-effect I'm encountering.
If you were to type the code below into your location bar, you would get an error: 'example-value' is undefined. If the div were named with underscores, it would work.
javascript:alert(example-value.currentStyle.hasLayout);

Related

jQuery - Strings and targeting

I've tried to google my question but it makes me even more confused. My question is:
Here's the jQuery code:
$(document).ready(function() {
$(window).resize(function() {
if ($(this).width() < 200) {
$("p").css("color", "red");
} else {
$("p").css("color", "green");
}
});
}
Why do we write (this) and not ("this") ?
How do I know if (document) and (window) should be written with " " - and why's that?
Maybe you could link me somewhere that explains my issue. My code apparently works either way, I'm just curious about the why.
In JavaScript namespace, this is reserved [source].
The JavaScript object literal this refers to the inherited object from the present state in the current execution.
Another example of this we can see is when we are looping through an array and the object this would symbolize the current array object. You may, for example, see this.title, or this.description if we were iterating through a database array of blog posts.
this in jQuery refers to the inherited object. When we add the quotation marks, and it becomes a string, such as "this". This makes jQuery parse it as a DOM selector.
Then we are now looking for the HTML DOM selector <this>, which to my knowledge, does not actually exist in the accepted HTML syntax standards.
As otherwise stated, the concept of this will become tricky when you are working in other JavaScript environments, such as React or Angular. Within the context of a functional component, this becomes the state, such as handling user sessions.

Want `­` to be always visible

I'm working on a web app and users sometimes paste in things they've copy/pasted from other places and that input may come with the ­ character (0xAD). I don't want to filter it out, I simply need the user to see that there is an invisible character there, so they have no surprises later.
Does anyone know a way to make the ­ always be visible? To show a hyphen, rather than remain hidden? I suspect a custom web font might be needed, if so, does anyone know of a pre-existing one?
You would need to either use JavaScript or a custom typeface that has a visible glyph for the soft-hyphen character. Given the impracticalities of working with typefaces for the web (and burdening the user with an additional hundred-kilobyte download) I think the JavaScript approach is best, like so:
document.addEventListener("DOMContentLoaded", function(domReadyEvent) {
var textBoxes = document.querySelectorAll("input[type=text]");
for(var i=0;i<textBoxes.length;i++) {
textBoxes[i].addEventListener("paste", function(pasteEvent) {
var textBox = pasteEvent.target;
textBox.value = textBox.value.replace( "\xAD", "-" );
} );
}
} );

How to I disable form autofill in all browsers?

I've looked through a number of posts all pointing towards different ways of using the autocomplete property, but I have yet to have this work in all my browsers. I've seen some really ugly workarounds such as this, but I'm looking for something that is clean and easy.
What is a good way to disable text field autofill on all (or at least, most) common browsers?
The following code will disable autocomplete in FF, IE, and Chrome.
<script>
$(document).ready(function () {
// IE & FF
$('input').attr('autocomplete', 'off');
// Chrome
if ( $.browser.webkit ) {
$('input').attr('autocomplete', 'new-password');
}});
</script>
Enabling Autocomplete on both form and input fields (with the "off" value) for the sake of those law-abiding browsers that do play by the rules is always a good beginning - also for the unlikely event that one day "other" browser...s may feel like compliance isn't all bad.
Until that day hacks are needed. I've noticed that Chrome looks for matching data in at least three places: Labels (contexts), Names and Placeholders. If the Name field is missing from input fields it will look in both Labels and placeholders, but if the Name field is present it will only look in Name and Placeholder.
This script utilize the "form-control" class from Bootstrap on input fields that must be guarded from Autocomplete. Use any other class or filter you like. Also assuming that Placeholders are in use - just remove that part if not.
$(document).ready(function() {
// Begin
var this_obj = null, this_placeholder = null, this_name = null;
$(".form-control").focus(function() {
this_obj = this;
this_name = $(this).prop("name");
this_placeholder = $(this).attr("placeholder");
$(this).prop("name", "NaN" + Math.random());
$(this).attr("placeholder", "...");
}).blur(function() {
$(this_obj).prop("name", this_name);
$(This_obj).attr("placeholder", this_placeholder);
});
// End
});
Note: Leaving the Placeholder empty might actually inadvertently trigger the Autocomplete function as empty assignments are apparently ignored.
The two variables this_name and this_placeholder may be avoided as they are accessible through this_obj, but I like to keep them around for the sake of readability and clarity.
The Script is erm.. quite unobtrusive, as it cleans up after itself and it only requires one matching class or attribute.
It works in Version 68.0.3440.106 (Officiel version) (64-bit), IE11 11.228.17134.0 and Firefox 61.0.2 (64-bit). Sorry, haven't tested others.
Add a class to all your input tags, suppose no-complete
And in your js file add following code:
setTimeout(function (){
$('.no-complete').val ("");
},1);

Adapting web pages for foreign language support

I have created a set of 13 HTML/CSS/JS templates for CMS integration in the English language.
I need to include support for foreign languages, specifically Russian, Chinese and Arabic. Initial searches online haven't turned up any central resource for guidance on what is required for supporting different languages in HTML.
I understand I'll need to look at things like my font-stacks and character encoding and the Arabic templates will need particular support with my entire layout switching for the right-to-left reading style.
Can anyone point me to some reliable resources for doing this in a standards-compliant way? All templates must meet WCAG 2.0 AA requirements.
Step 1
To start, let’s assume we have the following HTML:
<div>Hello there, how are you?</div>
This DIV layer contains our title. Now, we have decided we want this title to be available in multiple languages. Our first step is adding a class to the div so we can identify it later on:
<div class="title">Hello there, how are you?</div>
Step 2
With that ready, we’re just two steps away. First off, we are going to create an XML file that includes our translations. In this XML file, we can store translations for multiple phrases and we can easily add more languages at a later stage. We shall save this file as languages.xml and save it in the same folder as our HTML file.
<?xml version="1.0" encoding="UTF-8"?>
<translations>
<translation id="title">
<english>Hello there, how are you?</english>
<italian>Ciao, come stai?</italian>
</translation>
</translations>
You will store all phrases you want to translate between the <translations></translations> tags. You will store each phrase in a <translation></translation> tag. In order to identify which phrase is being translated, we need to add the id=”title”. The name should match the name of the CSS class you assigned in the HTML. Finally, we can put the translations inside and surround them by tags defining the language. For instance, we need to put the Italian text in between <italian></italian> tags. Keep in mind that you can easily change the names of these tags – For example, you may choose to use <eng></eng> and <ita></ita> instead.
Step 3
With that complete, you just need to add jQuery to read the XML file and replace the contents of your DIVs based on the language selected. Here you go:
<script src="path/to/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
$(function() {
var language = 'italian';
$.ajax({
url: 'language.xml',
success: function(xml) {
$(xml).find('translation').each(function(){
var id = $(this).attr('id');
var text = $(this).find(language).text();
$("." + id).html(text);
});
}
});
});
</script>
That’s all the code needed – Have a look at it again with comments this time:
// Include jQuery script
<script src="path/to/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
// $(function() { should be used
// each time you use jQuery
$(function() {
// Here we set the language
// we want to display:
var language = 'italian';
// In order to get the translations,
// we must use Ajax to load the XML
// file and replace the contents
// of the DIVs that need translating
$.ajax({
// Here, we specify the file that
// contains our translations
url: 'language.xml',
// The following code is run when
// the file is successfully read
success: function(xml) {
// jQuery will find all <translation>
// tags and loop through each of them
$(xml).find('translation').each(function(){
// We fetch the id we set in the XML
// file and set a var 'id'
var id = $(this).attr('id');
// This is the most important step.
// Based on the language we can set,
// jQuery will search for a matching
// tag and return the text inside it
var text = $(this).find(language).text();
// Last, but not least, we set the
// contents of the DIV with a
// class name matching the id in the
// XML file to the text we just
// fetched
$("." + id).html(text);
});
}
});
});
</script>
And that’s it! Refresh your page and the Italian version should load, replacing the default English one. In the example above, we set the language manually:
var language = 'italian';
We could just as easily set that via PHP:
var language = '<?php echo $sLanguage; ?>';
Or by reading it from the URL – you can use this jQuery Plugin to do that.
Bonus Trick
As you add more languages, you will realize that phrases are longer in certain languages and shorter in others. We might want to have custom CSS for each language. Taking the example above, we would initially have the following:
div.title { font-size:30px; }
What if we wanted the Italian to have a smaller font? Easy! We need to make a slight modification to our jQuery:
$(function() {
var language = 'italian';
$.ajax({
url: 'language.xml',
success: function(xml) {
$(xml).find('translation').each(function(){
var id = $(this).attr('id');
var text = $(this).find(language).text();
$("." + id).html(text);
// Here's the new line we're adding.
// We are assigned the DIV a new class
// which includes the old class name
// plus a "_language" - In this case,
// loading Italian would assign the DIV
// a "title_italian" class
$("." + id).addClass(id + '_' + language);
});
}
});
});
Now that we’ve added that line, we can just add the following CSS:
div.title { font-size:30px; }
div.title_italian { font-size:20px; }
Your Italian text should now be smaller. Note: In order for this to work, you must put the new language CSS definitions underneath the default one. Switching those two lines around will not work.
Sorry for the late answer, but better late than never... :-)
Francois answer is a good solution for a simple and quick solution.
For a more complete and flexible solution (with plural forms handling, for example...), please have a look at: i18next.
They provide:
support for variables
support for nesting
support for context
support for multiple plural forms
gettext support
sprintf supported
detect language
graceful translation lookup
jquery function
get string or object tree
get resourcefiles from server
resource caching in browser
post missing resources to server
highly configurable
custom post processing
translation ui
I'm using i18next solution myself, though I would personally prefer a server-side solution to avoid any additional burden on client side... :-)
N.B. I have no relation at all with i18next.com... :-)

Effective method to hide email from spam bots [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Closed 1 year ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
When placing email addresses on a webpage do you place them as text like this:
joe.somebody#company.com
or use a clever trick to try and fool the email address harvester bots? For example:
HTML Escape Characters:
joe.somebody#company.com
Javascript Decrypter:
function XOR_Crypt(EmailAddress)
{
Result = new String();
for (var i = 0; i < EmailAddress.length; i++)
{
Result += String.fromCharCode(EmailAddress.charCodeAt(i) ^ 128);
}
document.write(Result);
}
XOR_Crypt("êïå®óïíåâïäùÀãïíðáîù®ãïí");
Human Decode:
joe.somebodyNOSPAM#company.com
joe.somebody AT company.com
What do you use or do you even bother?
Working with content and attr in CSS:
.cryptedmail:after {
content: attr(data-name) "#" attr(data-domain) "." attr(data-tld);
}
<a href="#" class="cryptedmail"
data-name="info"
data-domain="example"
data-tld="org"
onclick="window.location.href = 'mailto:' + this.dataset.name + '#' + this.dataset.domain + '.' + this.dataset.tld; return false;"></a>
When javascript is disabled, just the click event will not work, email is still displayed.
Another interesting approach (at least without a click event) would be to make use of the right-to-left mark to override the writing direction. more about this: https://en.wikipedia.org/wiki/Right-to-left_mark
This is the method I used, with a server-side include, e.g. <!--#include file="emailObfuscator.include" --> where emailObfuscator.include contains the following:
<!-- // http://lists.evolt.org/archive/Week-of-Mon-20040202/154813.html -->
<script type="text/javascript">
function gen_mail_to_link(lhs,rhs,subject) {
document.write("<a href=\"mailto");
document.write(":" + lhs + "#");
document.write(rhs + "?subject=" + subject + "\">" + lhs + "#" + rhs + "<\/a>");
}
</script>
To include an address, I use JavaScript:
<script type="text/javascript">
gen_mail_to_link('john.doe','example.com','Feedback about your site...');
</script>
<noscript>
<em>Email address protected by JavaScript. Activate JavaScript to see the email.</em>
</noscript>
Because I have been getting email via Gmail since 2005, spam is pretty much a non-issue. So, I can't speak of how effective this method is. You might want to read this study (although it's old) that produced this graph:
Have a look at this way, pretty clever and using css.
CSS
span.reverse {
unicode-bidi: bidi-override;
direction: rtl;
}
HTML
<span class="reverse">moc.rehtrebttam#retsambew</span>
The CSS above will then override the reading direction and present the text to the user in the correct order.
Hope it helps
Cheers
Not my idea originally but I can't find the author:
<a href="mailto:coxntact#domainx.com"
onmouseover="this.href=this.href.replace(/x/g,'');">link</a>
Add as many x's as you like. It works perfectly to read, copy and paste, and can't be read by a bot.
I generally don't bother. I used to be on a mailing list that got several thousand spams every day. Our spam filter (spamassassin) let maybe 1 or 2 a day through. With filters this good, why make it difficult for legitimate people to contact you?
Invent your own crazy email address obfuscation scheme. Doesn't matter what it is, really, as long as it's not too similar to any of the commonly known methods.
The problem is that there really isn't a good solution to this, they're all either relatively simple to bypass, or rather irritating for the user. If any one method becomes prevalent, then someone will find a way around it.
So rather than looking for the One True email address obfuscation technique, come up with your own. Count on the fact that these bot authors don't care enough about your site to sit around writing a thing to bypass your slightly crazy rendering-text-with-css-and-element-borders or your completely bizarre, easily-cracked javascript encryption. It doesn't matter if it's trivial, nobody will bother trying to bypass it just so they can spam you.
I think the only foolproof method you can have is creating a Contact Me page that is a form that submits to a script that sends to your email address. That way, your address is never exposed to the public at all. This may be undesirable for some reason, but I think it's a pretty good solution. It often irks me when I'm forced to copy/paste someone's email address from their site to my mail client and send them a message; I'd rather do it right through a form on their site. Also, this approach allows you to have anonymous comments sent to you, etc. Just be sure to protect your form using some kind of anti-bot scheme, such as a captcha. There are plenty of them discussed here on SO.
You can protect your email address with reCAPTCHA, they offer a free service so people have to enter a CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) to see your email: https://www.google.com/recaptcha/admin#mailhide
I've written an encoder (source) that uses all kinds of parsing tricks that I could think of (different kinds of HTML entities, URL encoding, comments, multiline attributes, soft hyphens, non-obvious structure of mailto: URL, etc)
It doesn't stop all harvesters, but OTOH it's completely standards-compliant and transparent to the users.
Another IMHO good approach (which you can use in addition to tricky encoding) is along lines of:
<a href="mailto:userhatestogetspam#example.com"
onclick="this.href=this.href.replace(/hatestogetspam/,'')">
If you have php support, you can do something like this:
<img src="scriptname.php">
And the scriptname.php:
<?php
header("Content-type: image/png");
// Your email address which will be shown in the image
$email = "you#yourdomain.com";
$length = (strlen($email)*8);
$im = #ImageCreate ($length, 20)
or die ("Kann keinen neuen GD-Bild-Stream erzeugen");
$background_color = ImageColorAllocate ($im, 255, 255, 255); // White: 255,255,255
$text_color = ImageColorAllocate ($im, 55, 103, 122);
imagestring($im, 3,5,2,$email, $text_color);
imagepng ($im);
?>
I know my answer won't be liked by many but please consider the points outlined here before thumbing down.
Anything easily machine readable will be easily machine readable by the spammers. Even though their actions seem stupid to us, they're not stupid people. They're innovative and resourceful. They do not just use bots to harvest e-mails, they have a plethora of methods at their disposal and in addition to that, they simply pay for good fresh lists of e-mails. What it means is, that they got thousands of black-hat hackers worldwide to execute their jobs. People ready to code malware that scrape the screens of other peoples' browsers which eventually renders any method you're trying to achieve useless. This thread has already been read by 10+ such people and they're laughing at us. Some of them may be even bored to tears to find out we cannot put up a new challenge to them.
Keep in mind that you're not eventually trying to save your time but the time of others. Because of this, please consider spending some extra time here. There is no easy-to-execute magic bullet that would work. If you work in a company that publishes 100 peoples' e-mails on the site and you can reduce 1 spam e-mail per day per person, we're talking about 36500 spam emails a year. If deleting such e-mail takes 5 seconds on average, we're talking about 50 working hours yearly. Not to mention the reduced amount of annoyance. So, why not spend a few hours on this?
It's not only you and the people who receive the e-mail that consider time an asset. Therefore, you must find a way to obfuscate the e-mail addresses in such way, that it doesn't pay off to crack it. If you use some widely used method to obfuscate the e-mails, it really pays off to crack it. Since as an result, the cracker will get their hands on thousands, if not tens or hundreds of thousands of fresh e-mails. And for them, they will get money.
So, go ahead and code your own method. This is a rare case where reinventing the wheel really pays off. Use a method that is not machine readable and one which will preferably require some user interaction without sacrificing the user experience.
I spent some 20 minutes to code off an example of what I mean. In the example, I used KnockoutJS simply because I like it and I know you won't probably use it yourself. But it's irrelevant anyway. It's a custom solution which is not widely used. Cracking it won't pose a reward for doing it since the method of doing it would only work on a single page in the vast internet.
Here's the fiddle: http://jsfiddle.net/hzaw6/
The below code is not meant to be an example of good code. But just a quick sample of code which is very hard for machine to figure out we even handle e-mails in here. And even if it could be done, it's not gonna pay off to execute in large scale.
And yes, I do know it doesn't work on IE = lte8 because of 'Unable to get property 'attributes' of undefined or null reference' but I simply don't care because it's just a demo of method, not actual implementation, and not intended to be used on production as it is. Feel free to code your own which is cooler, technically more solid etc..
Oh, and never ever ever name something mail or email in html or javascript. It's just way too easy to scrape the DOM and the window object for anything named mail or email and check if it contains something that matches an e-mail. This is why you don't want any variables ever that would contain e-mail in it's full form and this is also why you want user to interact with the page before you assign such variables. If your javascript object model contains any e-mail addresses on DOM ready state, you're exposing them to the spammers.
The HTML:
<div data-bind="foreach: contacts">
<div class="contact">
<div>
<h5 data-bind="text: firstName + ' ' + lastName + ' / ' + department"></h5>
<ul>
<li>Phone: <span data-bind="text: phone"></span></li>
<li>E-mail <span data-bind="visible: $root.msgMeToThis() != ''"><input class="merged" data-bind="value: mPrefix" readonly="readonly" /><span data-bind="text: '#' + domain"></span></span></li>
</ul>
</div>
</div>
</div>
The JS
function ViewModel(){
var self = this;
self.contacts = ko.observableArray([
{ firstName:'John', mPrefix: 'john.doe', domain: 'domain.com', lastName: 'Doe', department: 'Sales', phone: '+358 12 345 6789' },
{ firstName:'Joe', mPrefix: 'joe.w', domain: 'wonder.com', lastName: 'Wonder', department: 'Time wasting', phone: '+358 98 765 4321' },
{ firstName:'Mike', mPrefix: 'yo', domain: 'rappin.com', lastName: 'Rophone', department: 'Audio', phone: '+358 11 222 3333' }
]);
self.msgMeToThis = ko.observable('');
self.reveal = function(m, e){
var name = e.target.attributes.href.value;
name = name.replace('#', '');
self.msgMeToThis(name);
};
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
You can try to hide characters using html entities in hexa (ex: &#x40 for #).
This is convenient solution, as a correct browser will translate it, and you can have a normal link.
The drawback is that a bot can translate it theorically, but it's a bit unusual.
I use this to protect my e-mail on my blog.
Another solution is to use javascript to assemble part of the address and to decode on-the-fly the address.
The drawback is that a javascript-disabled browser won't show your adress.
The most effective solution is to use an image, but it's a pain for the user to have to copy the address by hand.
Your solution is pretty good, as you only add a drawback (writing manually the #) only for user that have javascript disabled.
You can also be more secure with :
onclick="this.href='mailto:' + 'admin' + '#' + 'domain.com'"
One of my favorite methods is to obfuscate the email address using php, a classic example is to convert the characters to HEX values like so:
function myobfiscate($emailaddress){
$email= $emailaddress;
$length = strlen($email);
for ($i = 0; $i < $length; $i++){
$obfuscatedEmail .= "&#" . ord($email[$i]).";";
}
echo $obfuscatedEmail;
}
And then in my markup I'll simply call it as follows:
<a href="mailto:<?php echo myobfiscate('someone#somewhere.com'); ?>"
title="Email me!"><?php echo myobfiscate('someone#somewhere.com');?> </a>
Then examine your source, you'll be pleasantly surprised!
I wouldn't bother -- it is fighting the SPAM war at the wrong level. Particularly for company web sites I think it makes things look very unprofessional if you have anything other than the straight text on the page with a mailto hyperlink.
There is so much spam flying around that you need good filtering anyway, and any bot is going end up understanding all the common tricks anyway.
HTML:
<a href="#" class="--mailto--john--domain--com-- other classes goes here" />
JavaScript, using jQuery:
// match all a-elements with "--mailto--" somehere in the class property
$("a[class*='--mailto--']").each(function ()
{
/*
for each of those elements use a regular expression to pull
out the data you need to construct a valid e-mail adress
*/
var validEmailAdress = this.className.match();
$(this).click(function ()
{
window.location = validEmailAdress;
});
});
Spambots won't interpret this, because it is a lesser-known method :)
First, define the css:
email:before {
content: "admin";
}
email:after {
content: "#example.com";
}
Now, wherever you want to display your email, simply insert the following HTML:
<div id="email"></div>
And tada!
I use a very simple combination of CSS and jQuery which displays the email address correctly to the user and also works when the anchor is clicked or hovered:
HTML:
moc.elpmaxe#em
CSS:
#lnkMail {
unicode-bidi: bidi-override;
direction: rtl;
}
jQuery:
$('#lnkMail').hover(function(){
// here you can use whatever replace you want
var newHref = $(this).attr('href').replace('spam', 'com');
$(this).attr('href', newHref);
});
Here is a working example.
I don't bother. You'll only annoy sophisticated users and confuse unsophisticated users. As others have said, Gmail provides very effective spam filters for a personal/small business domain, and corporate filters are generally also very good.
The best method hiding email addresses is only good until bot programmer discover this "encoding" and implement a decryption algorithm.
The JavaScript option won't work long, because there are a lot of crawler interpreting JavaScript.
There's no answer, imho.
!- Adding this for reference, don't know how outdated the information might be, but it tells about a few simple solutions that don't require the use of any scripting
After searching for this myself i came across this page but also these pages:
http://nadeausoftware.com/articles/2007/05/stop_spammer_email_harvesters_obfuscating_email_addresses
try reversing the emailadress
Example plain HTML:
<bdo dir="rtl">moc.elpmaxe#nosrep</bdo>
Result : person#example.com
The same effect using CSS
CSS:
.reverse { unicode-bidi:bidi-override; direction:rtl; }
HTML:
<span class="reverse">moc.elpmaxe#nosrep</span>
Result : person#example.com
Combining this with any of earlier mentioned methods may even make it more effective
One easy solution is to use HTML entities instead of actual characters.
For example, the "me#example.com" will be converted into :
email me
A response of mine on a similar question:
I use a very simple combination of CSS and jQuery which displays the
email address correctly to the user and also works when the anchor is
clicked:
HTML:
moc.elpmaxe#em
CSS:
#lnkMail {
unicode-bidi: bidi-override;
direction: rtl;
}
jQuery:
$('#lnkMail').hover(function(){
// here you can use whatever replace you want
var newHref = $(this).attr('href').replace('spam', 'com');
$(this).attr('href', newHref);
});
Here is a working example.
Here is my working version:
Create somewhere a container with a fallback text:
<div id="knock_knock">Activate JavaScript, please.</div>
And add at the bottom of the DOM (w.r.t. the rendering) the following snippet:
<script>
(function(d,id,lhs,rhs){
d.getElementById(id).innerHTML = "<a rel=\"nofollow\" href=\"mailto"+":"+lhs+"#"+rhs+"\">"+"Mail"+"<\/a>";
})(window.document, "knock_knock", "your.name", "example.com");
</script>
It adds the generated hyperlink to the specified container:
<div id="knock_knock"><a rel="nofollow" href="your.name#example.com">Mail</a></div>
In addition here is a minified version:
<script>(function(d,i,l,r){d.getElementById(i).innerHTML="<a rel=\"nofollow\" href=\"mailto"+":"+l+"#"+r+"\">"+"Mail"+"<\/a>";})(window.document,"knock_knock","your.name","example.com");</script>
A neat trick is to have a div with the word Contact and reveal the email address only when the user moves the mouse over it. E-mail can be Base64-encoded for extra protection.
Here's how:
<div id="contacts">Contacts</div>
<script>
document.querySelector("#contacts").addEventListener("mouseover", (event) => {
// Base64-encode your email and provide it as argument to atob()
event.target.textContent = atob('aW5mb0BjbGV2ZXJpbmcuZWU=')
});
</script>
The only safest way is of course not to put the email address onto web page in the first place.
Use a contact form instead. Put all of your email addresses into a database and create an HTML form (subject, body, from ...) that submits the contents of the email that the user fills out in the form (along with an id or name that is used to lookup that person's email address in your database) to a server side script that then sends an email to the specified person. At no time is the email address exposed. You will probably want to implement some form of CAPTCHA to deter spambots as well.
There are probably bots that recognize the [at] and other disguises as # symbol. So this is not a really effective method.
Sure you could use some encodings like URL encode or HTML character references (or both):
// PHP example
// encodes every character using URL encoding (%hh)
function foo($str) {
$retVal = '';
$length = strlen($str);
for ($i=0; $i<$length; $i++) $retVal.=sprintf('%%%X', ord($str[$i]));
return $retVal;
}
// encodes every character into HTML character references (&#xhh;)
function bar($str) {
$retVal = '';
$length = strlen($str);
for ($i=0; $i<$length; $i++) $retVal.=sprintf('&#x%X;', ord($str[$i]));
return $retVal;
}
$email = 'user#example.com';
echo 'mail me';
// output
// mail me
But as it is legal to use them, every browser/e-mail client should handle these encodings too.
One possibility would be to use isTrusted property (Javascript).
The isTrusted read-only property of the Event interface is a Boolean
that is true when the event was generated by a user action, and false
when the event was created or modified by a script or dispatched via
EventTarget.dispatchEvent().
eg in your case:
getEmail() {
if (event.isTrusted) {
/* The event is trusted */
return 'your-email#domain.com';
} else {
/* The event is not trusted */
return 'chuck#norris.com';
}
}
⚠ IE isn't compatible !
Read more from doc: https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
I make mine whateverDOC#whatever.com and then next to it I write "Remove the capital letters"
Another, possibly unique, technique might be to use multiple images and a few plain-text letters to display the address. That might confuse the bots.