如果有人注册您的网络应用程序,他们将电子邮件地址输入为 [电子邮件保护]?他们没有注意到,他们从未收到确认邮件,他们无法再次登录,“忘记密码”功能不起作用,并且有很多沮丧和互相指责。
我们不能帮忙吗?
我有一个非常基本的想法,建议使用 <datalist>
建议下拉菜单提供常见的电子邮件域。本质上是这样的

这样的数据列表可以附加到任何文本输入,它们本质上提供了建议。用户仍然可以输入他们想要的任何有效值。我认为这就像 <select>
和 <input>
的混合体。
以下是它的工作原理。
标记
完全正常的 HTML,无论是否
<label for="email">Email</label>
<input id="email" name="email" type="email" placeholder="[email protected]">
使用 JavaScript 插入数据列表
Datalist 是一个 HTML 元素,但我们不能立即将其放入标记中,因为我们还不知道要放入什么。我们放入其中的选项将需要包含电子邮件地址的第一部分。这是 JavaScript 的领域,因此我们不妨只在 JavaScript 运行时添加数据列表。
jQuery,因为我喜欢它。
// Create empty datalist and append to DOM
var datalist = $("<datalist />", {
id: 'email-options'
}).insertAfter("#email");
// Correlate to input
$("#email").attr("list", "email-options");
电子邮件顶级域名
电子邮件有一些非常流行的“顶级域名”。让我们将它们放在一个数组中
var domains = ["yahoo.com", "gmail.com", "google.com", "hotmail.com", "me.com", "aol.com", "mac.com", "live.com", "comcast.com", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk", "facebook.com", "verizon.net", "att.net", "gmz.com", "mail.com"];
根据需要调整。
监控按键
我们不想打扰用户,直到他们按下“@”键,我们知道他们正在继续输入电子邮件地址的域名部分。因此,首先,我们监控按键事件
$("#email").on("keyup", function() {
});
然后我们测试该值是否包含“@”
$("#email").on("keyup", function() {
var value = $(this).val();
if (value.indexOf("@") != -1) {
// it's there, update datalist
}
});
我们最好有条理
随着事情变得更加复杂,我们应该更加担心意大利面条代码和通常难以维护的混乱。让我们 井井有条,使用一个对象将所有内容整合在一起。
结构基本上是
var EmailDomainSuggester = {
domains: ["yahoo.com", "gmail.com", "google.com", "hotmail.com", "me.com", "aol.com", "mac.com", "live.com", "comcast.com", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk", "facebook.com", "verizon.net", "att.net", "gmz.com", "mail.com"],
bindTo: $('#email'),
init: function() {
this.addElements();
this.bindEvents();
},
addElements: function() {
// Create empty datalist
this.datalist = $("<datalist />", {
id: 'email-options'
}).insertAfter(this.bindTo);
// Corelate to input
this.bindTo.attr("list", "email-options");
},
bindEvents: function() {
this.bindTo.on("keyup", this.testValue);
},
testValue: function(event) {
var el = $(this),
value = el.val();
// remove the != -1 if you want the datalist to show up immediately as you type the @
// with it in place, it won't show up until you type the NEXT character
if (value.indexOf("@") != -1) {
value = value.split("@")[0];
EmailDomainSuggester.addDatalist(value);
}
},
addDatalist: function(value) {
}
}
EmailDomainSuggester.init();
动态生成数据列表
请注意,在上面的代码中,我在 split
中添加了一点点内容,该内容是我们从 @
符号处的输入中提取的值。这使我们能够提取电子邮件地址中域之前的部分。例如,“chriscoyier@gm” 的“chriscoyier”部分。然后我们将它传递给一个名为 addDatalist
的新函数。现在让我们使用它
// variables for iteration and string concatination
var i, newOptionsString = "";
// loop over all the domains in our array
for (i = 0; i < this.domains.length; i++) {
newOptionsString +=
"<option value='" +
value +
"@" +
this.domains[i] +
"'>";
}
// add all the <option>s to our datalist
this.datalist.html(newOptionsString);
如果我们还没准备好,就删除数据列表
作为最后的清理工作,如果输入中的值还没有“@”符号,我们应该删除数据列表。即使用户最初输入了它,然后又退回去了。我们可以在 testValue
函数中处理它。我们要么使用最新版本更新数据列表,要么完全删除它
if (value.indexOf("@") != -1) {
value = value.split("@")[0];
EmailDomainSuggester.addDatalist(value);
} else {
// empty list
EmailDomainSuggester.datalist.empty();
}
最终演示
与其在这里粘贴一大块代码,不如在 Pen 中查看它
查看 Pen 使用 帮助完成电子邮件地址 by Chris Coyier (@chriscoyier) on CodePen
更健壮的解决方案
记录在案,我不确定数据列表方法是否是一个好主意。这需要一些真正的用户体验测试才能确定它是否真的有用。它可能会以用户混淆的形式造成伤害。我更确定某种形式的电子邮件域检查是一个好主意。
GitHub 上有一个名为 mailcheck.js 的开源项目,它看起来很棒。

jquery.email-autocomplete.js 是另一个选择。
是的
您使用过这样的东西吗?您对这些方法怎么看?您是否针对此或类似的想法进行了任何用户体验测试?您是否有其他想法来解决“错误电子邮件”问题?
很棒的可用性技巧。Steve Krug 会感到自豪。
我不确定哪个更好,但我以前见过数据列表的使用……不记得哪个网站,但(从高级用户的角度来看)我喜欢列表。从开发人员的角度来看,“你是否要输入……”似乎更容易,而且更简洁。
哇,Ryan 谢谢你毁了我今天在办公室的一天,应该添加一个简单的 NSFW 警告。
我喜欢它。我认为解决输入错误的电子邮件问题将非常有用,但我同意你最后的评论,即“你是否要输入 [电子邮件保护]?”解决方案可能更好。它不那么突兀,对用户来说也不那么令人震惊。
如果一个外行正在注册一个全新的网站,并且该网站向他们提供了一个电子邮件列表,而他们认出了其中一些地址是他们曾经使用过的地址,这可能会引发隐私问题(即使该解决方案实际上不存在隐私问题)。
FWIW,根据我两年前进行的有限研究,输入错误的电子邮件约占表单提交量的 1%
换句话说,如果你每月有 1000 人注册你的网站,其中 10 人会失败,也许 5 人会因为沮丧而联系你……或者每月大约 30-60 分钟的客服,这取决于在你的 CMS 中更改电子邮件地址的难易程度。
如果你有 10000 个注册用户,那就是 2 天的工作。
无论哪种方式,似乎花几个小时研究和实施这项技术都会在几周或几个月内得到回报。如果你已经拥有用户群,查看最常见的域名会使这项技术更加实用。事实上,你可以更进一步,自动执行每月维护,检查最近使用的域名以填充列表。
我认为这会造成一些混淆,因为这样的下拉菜单保留了浏览器原生功能以显示最近的表单历史记录。而且你必须禁用它,这不仅令人困惑,而且令人讨厌。
我同意。mailcheck.js 的 UI 似乎不太令人困惑。
自动建议用于各种表单,尤其是谷歌。我不认为你会发现太多困惑。但是,如果你真的担心,你可以用视觉方式将其与建议区分开来,并在列表中添加“建议”一词。
像往常一样,好文章。Treehouse 的节目最近介绍了一个很酷的 jQuery 表单验证库:Omar Shammas 的 Formance.js。快去看看吧!
(http://teamtreehouse.com/library/the-treehouse-show/episode-59-form-validation-safari-push-notifications-javascript-performance)
http://omarshammas.github.io/formancejs
我也很好奇这些解决方案与要求用户两次输入电子邮件地址(作为减少误输入电子邮件的一种方式)的普遍模式相比如何。我个人更喜欢这些。
我已经用过几次 **mailcheck.js** 了,用户真的很喜欢它。
我还添加了一个事件监听器(Google Analytics)到“您指的是”链接,当您想知道它是否有所作为时,这很有帮助。
这似乎是一个非常好的技术,但是我不确定我是否是唯一注意到这一点的人,但在 Mavericks 上的 Safari 中,菜单确实会在键入“@”后显示,我认为这与新的自动填充密码/用户名有关。
我想这就像对问题的内置解决方案,只允许您在您的 Mac 上输入过的有效电子邮件地址。它肯定会在不支持此功能的旧系统上很方便。
我的意思是它不会显示。
我也是,在 ML 上运行 Safari 6,code pen 不起作用。
我不明白这怎么是侵入式的,因为它基本上与所有浏览器已经拥有的行为相同:下拉菜单出现在与您之前填写的表单类似的表单字段上,或者如果您正在填写相同的表单(就像这里的评论表单*)。
此外,这正是我们几年前由 Google 推出的“实时搜索”(我说的不是“即时搜索”,那是另一回事)。
我没有看到网上有人抱怨上面这两个功能是侵入式的,而 Chris 的这个想法是基于相同概念的。
不过,我确实看到一个技术问题和一个潜在的可用性问题。
技术问题是,这个脚本在我的 iPhone 5 上运行 iOS 6 时不起作用(我打算在屈服于 flat 之前再等更长时间)。有人可以在 iOS 7 上确认吗?
我看到的潜在可用性问题是,用户可能会在他们甚至没有完成电子邮件地址之前看到这个功能“神秘地知道”他们的电子邮件地址而感到不安。只是说一下。在这种情况下,也许 mailcheck.js 会有优势,因为它发生在用户完成之后。再说一次,只是说一下。
我还想知道:每次我要在 CSS-Tricks.com 上发帖时,我需要填写顶部的字段,因为我之前已经填写过它们,所以 Firefox 会向我显示一个包含我过去使用过的电子邮件的下拉菜单,所以:当这两个功能结合在一起时会发生什么,浏览器的下拉菜单和脚本的下拉菜单?
*看看这里。
剧透:它实际上结合得很好,因为你可以看到顶部的部分是浏览器自己的下拉菜单,而下面的部分是脚本的,用细线明显区分开来。
我想我宁愿有两个电子邮件地址字段,就像密码一样。
对我来说很有道理 :)
我不知道你怎么样,但作为一个用户,我总是复制/粘贴第二个电子邮件(这完全违背了目的)。在少数情况下,这种能力被禁用,这绝对让我恼火。
有趣的想法,虽然我想知道它是否会增加人们意外地将其他电子邮件提供商自动补全为例如 gmail 地址的风险。
对代码的一些挑剔
似乎你在每次在“@”之后按键时都重建数据列表,这似乎有点浪费。记住旧的“value”(“@”之前的部分),只在它改变时重建,可能更清晰。
只有我觉得我们有越多“方法”去做某事,我们似乎就越难决定使用哪一个吗?
对于所有三种方法,我都能看到(主要是)优点和(一些)缺点;双重电子邮件字段、数据列表和“您指的是”,所以除了试图猜测您的“平均”用户可能或可能不会发现“令人困惑”之外,我想这归结为选择一个并坚持使用它。
不幸的是,我全都要 O.O
如果你是一名 tuts 订阅者,请查看我一年多前写的关于做类似事情的教程。
https://tutsplus.com/tutorial/building-a-mobile-friendly-form-with-email-domain-suggestion/
如往常一样,很简洁,Chris!我可能更喜欢在测试了之后使用“mailcheck.js”风格。Google Chrome 立即为我提供了
<input type="email">
的自动完成功能。然后自动完成突然被替换为巨大的列表,有点令人困惑。所以也许浏览器的自动填充已经足够解决了这个问题?但是再说一次:好主意!服务器端(或使用 Ajax 的客户端端)解决方案是使用这个 PHP 函数:**checkdnsrr()**。
基本上,您可以验证您电子邮件地址中输入的邮件服务器是否为真实的邮件服务器。
查看文档:https://php.ac.cn/manual/fr/function.checkdnsrr.php
这似乎是最简单且最具未来性的解决方案(不是说 gmail.com 会消失,但有些提供商可能会消失)。
设计师经常忘记他们创造的背后有一个服务器——不妨用用它。
我刚在我的商务电子邮件设置时遇到了这个问题!而且它确实很有帮助!我意外地输错了域名,它帮我修正了!我爱这个网站!
可以通过忽略向下和向上箭头键的按压来改进体验。 ;-)
不,那对用户体验来说是致命的……
你怎么会想出这么糟糕的主意?
我认为你的域名列表中有一个拼写错误。至少我知道 gmx.com 作为一个电子邮件提供商,而 gmz.com 似乎不是。在旨在减少拼写错误的工具中出现拼写错误有点讽刺 :-)
我们在 Vimeo 使用“您指的是 x?”的方式。MailCheck 看起来是一个很棒的库,但正如文档中所述,你绝对应该考虑根据你的网站访问者最常使用的域名提供自己的域名建议。这样做的缺点是,你可能会发现自己需要进行很多更新。
雅虎和 Hotmail 对多个 TLD 的喜爱一直是迄今为止最大的问题,所以最近我创建了一个单独的循环来用所有可能的排列填充我的列表。
嗨,Chris,好主意,很酷,但是无法使用键盘选择任何选项。
我无法使用箭头键从下拉菜单中选择任何选项。
我听说这是 Firefox 中的一个问题。在我的 Chrome 中工作。它只是一个原生 Datalist,其中键盘命令在 Firefox 中有效,所以这是一个代码问题。请随意分叉并修复 =)
@rocketmail.com 不在列表中 ><