我称之为第 2 部分,因为上周我在 Tutorial Blog 上开始了这个冒险之旅,我们首先**设计**了一个独特的联系表单。
在这里,我们将从上周结束的地方继续,使用 HTML/CSS 构建这个表单,并使用 jQuery 添加一些验证,并使其与 PHP 协同工作。以下是我们要构建的内容:
1. 从 Photoshop 中切出图像
大型背景图像(表单元素以外的所有内容)
页面背景纹理(用于其他所有地方)
发送按钮
输入区域背景。要创建此背景,我裁剪了该区域周围的部分,导出后,更改了该图层上的“颜色叠加”图层样式并再次导出。然后,我打开这两个导出的文件,将其中一个放置在另一个的顶部,并再次导出。
文本区域背景。与上述技术相同。
2. 标记表单
在大多数方面,这是一个典型的<form>。一些标签和输入,并在末尾有一个提交按钮。与众不同的是,我们需要包含 Left 和 Right div,因为这本质上是一个两列表单。此外,每个输入都包装在一个 div 中,因为我们需要一个挂钩来正确应用我们创建的背景图像。
以下是所有标记:
<div id="page-wrap">
<form method="post" action="contactengine.php" id="commentForm">
<fieldset>
<div id="formLeft">
<label for="Name">Name:</label>
<div class="input-bg">
<input type="text" id="Name" name="Name" class="required" minlength="2" />
</div>
<label for="City">City:</label>
<div class="input-bg">
<input type="text" id="City" name="City" class="required" minlength="2" />
</div>
<label for="Email">Email:</label>
<div class="input-bg">
<input type="text" id="Email" name="Email" class="required email" />
</div>
</div>
<div id="formRight">
<label for="Message">Message:</label></td>
<div class="message-bg">
<textarea name="Message" id="Message" rows="20" cols="20" class="required"></textarea>
</div>
<br />
<input type="image" src="images/send-button.jpg" name="submit" value="Submit" class="submit-button" />
</div>
<div class="clear"></div>
</fieldset>
</form>
</div>
3. 使用 CSS 样式化
我不会解释每个属性,因为我认为其中很多都非常简单且不言自明。首先,我将在这里显示代码,然后我将在下面解释一些重点/不太明显的内容。
* { margin: 0; padding: 0; }
body { font-size: 62.5%; font-family: Georgia, serif; background: url(images/page-bg.jpg); }
.clear { clear: both; }
fieldset { border: none; }
#page-wrap {
width: 800px;
margin: 0 auto;
background: url(images/form-bg.jpg) top center no-repeat;
min-height: 600px;
}
form {
padding: 83px 0 0 76px;
}
h1 {
text-align: center;
padding-top: 200px;
}
#formLeft {
width: 320px;
float: left;
}
#formLeft input {
width: 250px;
margin: 0 0 20px 0;
border: none;
text-align: center;
background: none;
margin: 13px 0 0 8px;
font-size: 1.4em;
}
#formLeft .input-bg {
background: url(images/form-sm-bg.jpg) bottom left no-repeat transparent;
height: 45px;
margin-bottom: 10px;
position: relative;
}
#formLeft .active {
background: url(images/form-sm-bg.jpg) top left no-repeat transparent;
}
#formRight {
width: 360px;
float: right;
padding-right: 44px;
}
#formRight textarea {
width: 298px;
height: 209px;
display: block;
border: none;
background: none;
margin: 0 0 0 20px;
padding: 13px 0 13px 0;
font-family: Helvetica, sans-serif;
font-size: 1.3em;
}
#formRight .message-bg {
background: url(images/message-bg.jpg) bottom left no-repeat transparent;
height: 238px;
}
#formRight .active {
background: url(images/message-bg.jpg) top left no-repeat transparent;
}
label {
display: block;
font-size: 1.3em;
text-indent: 10px;
font-weight: bold;
}
label.error {
position: absolute;
top: -16px;
right: 49px;
padding: 3px;
color: #da3939;
font-size: 1.0em;
text-align: right;
font-style: italic;
font-weight: normal;
}
input.submit-button {
float: right;
padding-right: 31px;
}
请注意,即使我正在使用表单,我在这里也使用了 * 选择器。当您应用 border: none; 时,* 选择器和表单不兼容,这会破坏提交按钮等元素的默认样式。我们已经准备好好地破坏默认样式,所以就这样吧 =)
还记得我们添加的用于包装输入的挂钩吗?我们将背景图像应用于这些挂钩而不是输入本身。输入不喜欢背景图像。我们还为输入创建了一个“active”类,其中背景图像从左下角移到左上角。应用和删除该类将创建我们稍后将介绍的当前字段突出显示。
每个额外的挂钩也具有相对定位。这是因为在表单验证期间将动态添加到页面中的“错误”消息。为了使这些消息正确定位,它们将被绝对定位在其相对定位的父元素**内部**。
这里我们**没有做**的一件事是将背景图像应用于提交按钮。通过将提交按钮的类型设置为“image”并为其提供 src 图像,而不是类型为“submit”并应用背景图像,可以获得更好的跨浏览器结果。
4. 使用 jQuery 实现当前字段突出显示
出于良好的可用性和美观性的考虑,我们将实现当前字段突出显示。这就是我们使用两种不同颜色创建这些表单背景图像的原因。CSS 通过其 :focus 伪类提供了一些对此的支持,但这对我们没有帮助,原因有两个。首先,它仅适用于表单元素,我们需要更改表单元素的父元素的样式,而这在 CSS 中是不可能的。其次,:focus 类并未得到广泛支持。
我们将为此使用 jQuery,因为它支持我们需要的全部事件类型:悬停、焦点和失焦。所需的效果是,当鼠标悬停在任何这些表单元素上时,父元素的背景图像将切换到我们的备用版本,表示它是当前字段。
由于我们希望对两种不同类型的元素执行此操作,因此我们需要编写两个单独但非常类似的 jQuery 代码块。
<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#formLeft .input-bg").hover(function() {
$(this).addClass("active");
}, function() {
$(this).removeClass("active");
});
$("#formLeft input").focus(function() {
$(this).parent().addClass("active");
});
$("#formLeft input").blur(function() {
$("#formLeft .input-bg").removeClass("active");
});
$("#formRight .message-bg").hover(function() {
$(this).addClass("active");
}, function() {
$(this).removeClass("active");
});
$("#formRight textarea").focus(function() {
$(this).parent().addClass("active");
});
$("#formRight textarea").blur(function() {
$("#formRight .message-bg").removeClass("active");
});
});
</script>
这可能看起来比实际情况更复杂……所有这些操作只是在发生不同事件时向相应的元素添加和删除“active”类。这使得当前字段突出显示在鼠标悬停时以及输入被 Tab 键选中时都能正常工作。
更多关于 当前字段突出显示的信息,请点击此处。
5. 验证表单
表单验证对联系表单的发送方和接收方都有用。对于发送方,它确保他们执行了诸如提供有效电子邮件地址等操作。如果他们正在使用联系表单,那么他们很可能不介意被回复,因此,此操作是为了确保该字段正确填写。对于接收方,表单验证是防止垃圾邮件的良好开端。此外,更直接地说,它确保所有提交都包含已声明为最重要的信息。
由于我们已经在使用强大的 jQuery,因此让我们使用它来处理客户端的表单验证。幸运的是,已经有一个 很棒的插件 可用于此目的。只需在页面上包含该脚本(当然是在主 jQuery 库之后),并通过引用表单的 ID 来向表单添加验证即可。
<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="js/jquery.validate.js"></script>
<script type="text/javascript">
$(document).ready(function(){
...
$("#commentForm").validate();
});
</script>
此插件正在查找输入的特定类名(在某些情况下还有其他属性)来执行验证。例如,我们希望“姓名”字段是必填字段,并且值长度大于或等于两个字符。只需向我们的输入元素添加两个新属性:class=”required”和minlength=”2″。
<input type="text" name="Name" class="required" minlength="2" />
对于电子邮件地址验证,只需添加如下类名即可:
<input type="text" name="Email" class="required email" />
有关更高级和不同类型的验证,请参阅插件的文档。
6. 使其与 PHP 协同工作
我们的表单验证将阻止提交按钮触发表单的“action”,如果任何字段未通过检查。但是,如果所有字段都有效,我们希望表单实际**执行某些操作**,对吧?由于这是一个联系表单,我们希望发生的事情是生成电子邮件并将其发送到指定的电子邮件地址。
在我们的标记中,表单的“action”在此处声明:
<form method="post" action="contactengine.php" id="commentForm">
这将调用“contactengine.php”文件并将表单中的变量作为 POST 变量发送给它。然后,我们的任务是捕获这些变量,创建格式化的电子邮件,并发送电子邮件。
以下是执行此操作的方法。这是 contactengine.php 文件的全部内容:
<?php
// CHANGE THE THREE VARIABLES BELOW
$EmailFrom = "[email protected]";
$EmailTo = "[email protected]";
$Subject = "Contact Form Submission";
$Name = Trim(stripslashes($_POST['Name']));
$Tel = Trim(stripslashes($_POST['Tel']));
$Email = Trim(stripslashes($_POST['Email']));
$Message = Trim(stripslashes($_POST['Message']));
// prepare email body text
$Body = "";
$Body .= "Name: ";
$Body .= $Name;
$Body .= "\n";
$Body .= "Tel: ";
$Body .= $Tel;
$Body .= "\n";
$Body .= "Email: ";
$Body .= $Email;
$Body .= "\n";
$Body .= "Message: ";
$Body .= $Message;
$Body .= "\n";
// send email
$success = mail($EmailTo, $Subject, $Body, "From: <$EmailFrom>");
// redirect to success page
// CHANGE THE URL BELOW TO YOUR "THANK YOU" PAGE
if ($success){
print "<meta http-equiv="refresh" content="0;URL=contactthanks.html">";
}
else{
print "<meta http-equiv="refresh" content="0;URL=error.html">";
}
?>
这部分的核心是“mail”函数,它实际上执行电子邮件发送操作。请注意,我们在设置变量($success)的同时调用它。此变量将告诉我们邮件是否成功发送。如果为 TRUE,我们可以重定向到我们的“感谢”页面。否则,我们应该让用户知道某些操作出错,并重定向到错误页面。
演示和下载
好了,朋友们!一个外观漂亮且功能齐全的表单。
查看演示
(请勿尝试通过此表单实际联系我。如果您需要联系我,请使用我的 常规联系表单)。
下载示例
(包括 Photoshop 文件)
问题…
Safari 倾向于在其所有文本输入和文本区域周围应用其发光的蓝色边框。在撰写本文时,无法解决此问题。这丝毫不会影响表单的可用性,只是在该设计中看起来有点奇怪。更新:gaga 在下面指出,在这些表单元素上设置 outline: none 将消除 Safari 的发光蓝色边框。我之前不知道这一点,谢谢!
IE 和 Opera 倾向于在文本区域上放置垂直滚动条,无论如何。同样,这不是什么大问题,但我认为当它们不需要时看起来有点蠢。
验证码有什么用?
如你所知,表单验证有助于减少垃圾邮件,但并不能完全消除。如果你要创建一个你认为容易受到垃圾邮件攻击的表单,你可能需要考虑添加一个验证码。验证码通常是“输入你看到的字母”之类的形式,然后显示一个包含一些被线条遮挡的字母的图形。有时你也会看到像“1+1等于多少?”这样的简单验证码,因为即使是最简单的验证码也被证明在阻止随机的表单垃圾邮件方面非常有效。
我认为最好的免费验证码是 reCAPTCHA,它运行良好,易于实现,并且有助于数字化书籍。
在之前的文章中,我演示了如何在联系表单中使用 reCAPTCHA,并且它仍然有效。所以如果你有兴趣将 reCAPTCHA 添加到这个联系表单中,可以查看这个例子。
很棒的文章,谢谢。也要特别感谢 tutorialblog.org。
你包含了
label
标签,但是你的输入元素没有相同的 ID。你无法点击标签来访问输入字段。你写了
<label for=”Name”>Name:</label>
但要使其正常工作,你需要为“Name”的输入字段添加 ID 属性
<input type=”text” id=”Name” name=”Name” class=”required” minlength=”2″ />
除此之外,这是一篇好文章。干得好。
@koew: 发现问题了,谢谢。我已经添加了这些 ID。
对于 Safari 中的蓝色边框… 尝试添加
input, textarea { outline: none; }
它应该可以解决 ;-)谢谢 gaga!之前不知道这一点。文章已更新。
对于 textarea,尝试在其上设置
overflow: auto
。它应该适用于 IE,但 Opera … 不太行。我听说,如果你声明:
* {margin:0; padding:0;}
,它可能会减慢页面渲染速度,因为它需要检查页面上的每个元素是内联还是块级,并应用样式,而不是只重置你想要标准化的填充和边距的元素。关于重置样式和优化页面性能的一些想法。
@Chad: 确实,
*
选择器会让渲染引擎做更多工作,但我从未见过关于它到底增加了多少工作量以及造成了多少延迟的明确证据。我使用它很多年了,从未听过任何抱怨。我支持提高性能,但我感觉差异非常微不足道。非常感谢这篇文章。在 jQuery 方面非常有帮助,我确实需要开始使用/学习更多。
有一些(很小的)UI 问题让我不太满意
1) 当光标位于某个字段中时,如果将鼠标悬停在另一个字段上,则当前聚焦的字段和悬停的字段的背景都会发生变化。在这个例子中,我看到字段的背景颜色作为焦点,并且在鼠标移动过程中发生变化……嗯,我不确定我是否喜欢这样。可能会让用户感到有点困惑。
2) 在 Safari 中,你可以调整 textarea 字段的大小。并且如果调整大小,背景不会扩展以包含新的 textarea(预期行为)。更糟糕的是,由于 textareas 的
outline
样式设置为none
,你无法再看到文本区域的边界。同样,仅限 Safari 用户。也许有办法修复 textarea 边界,使其无法调整大小?3) 我不太喜欢输入字段上的
text-align: center
。不常看到。请不要把这当作批评。我只是想提出一些观点,供其他人设计表单时参考。
另一篇很棒的文章。你总是能在恰当的时候写出我需要的文章,就像新的 jQuery 视频一样。谢谢!
这正是我长期以来一直在寻找的东西。感谢你制作了如此简洁易懂的教程。很棒的工作!继续努力 :)
谢谢,
Mason
这真的是一篇很棒的文章。现在我要熬夜了,因为我要尝试做这个。
我似乎无法使 PHP 部分工作!
我已经设置了 Xampp,并且 Web 服务器运行良好,但是提交后直接跳转到我创建的 error.html 页面。
此表单非常不安全。客户端验证**仅**用于方便用户。它无法防止垃圾邮件、黑客或烦人的 Web 开发人员(比如我 :P)。黑客只需创建一个没有所有 JavaScript 的 HTML 文件即可。垃圾邮件机器人甚至不会使用表单,它们只会解析表单的 ID 并发送原始数据包。**始终**在服务器上检查输入。**永远**不要相信用户。
非常有益的文章。阅读代码并按照此类文章中的步骤操作,我学到了很多东西。感谢你抽出时间发布这篇文章。
是否可以使验证在 Opera 中工作?因为它根本没有进行验证。
这似乎是 Opera 9.5、jQuery 1.2.6 和此插件的一个已知问题。也许可以尝试回滚到 jQuery 1.2.4?
有没有办法将其全部合并为一个表单?以便在现有表单上显示感谢消息,但不会跳转到另一个页面???
谢谢。
我正在尝试在我的妻子的网站上使用你的评论表单,但它无法进行验证或突出显示字段。
http://simonewphoto.com/test2/test.html
我不确定我哪里做错了。如果你能帮我解决这个问题,那就太好了。
看起来你在那个页面上使用了许多 JavaScript 库,这可能会导致冲突?我建议下载安装并使用 Firebug,以便查看页面抛出的 JavaScript 错误。然后,也许可以下载表单的新副本并反向实施它,在每次更改后检查其功能。
很棒的文章。我一直很欣赏你的教程有多么全面。不过,我这里遇到了一些小问题。
我正在我的作品集网站上实现此表单的变体,但由于此表单的 XHTML 无法验证,因此我被卡住了。看起来
minlength
属性已弃用,并且仅保留了maxlength
。你知道脚本的任何简单修复方法或可以替代minlength
以实现相同结果的属性吗?(我知道需要相应地更改 jQuery)谢谢。有没有办法在 WordPress 中使用这种类型的联系表单?这是一个很棒的教程!谢谢!
谢谢
谢谢
谢谢
谢谢
很棒的文章。干得好
你好
只是想提醒一下任何从教程代码中阅读本文的人,你在 PHP 文件中忘记在双引号前添加反斜杠。(不过,源文件中的代码没问题)应该是
if ($success){
print "< meta http-equiv=\"refresh\" content=\"0;URL=contactthanks.html\">";}else{
print "< meta http-equiv=\"refresh\" content=\"0;URL=error.html\">";
}
我已经按照上面写的正确输入了代码,但是当我点击发送时,它想下载“contactengine.php”文件而不是发送电子邮件。我哪里做错了?
如何在contactengine.php中获取selectbox的值,以及如何获取多个值?
如何为contactengine.php设置样式?