jQuery2-开发秘籍-二-

39 阅读26分钟

jQuery2 开发秘籍(二)

原文:zh.annas-archive.org/md5/44BEA83CD04274AA076F60D831F59B04

译者:飞龙

协议:CC BY-NC-SA 4.0

第四章:用 jQuery 效果添加引人入胜的视觉效果

在本章中,我们将涵盖:

  • 滑动页面元素

  • 隐藏和显示元素

  • 淡入淡出元素

  • 切换效果

  • 停止效果

  • 链接效果

  • 创建一个基本的相册

  • 创建一个闪烁的按钮

  • 使用效果删除元素

介绍

本章将向您展示如何向您的界面添加简单的效果,以增强网站的整体美观度和用户体验。向元素添加基本效果可以对用户的印象产生巨大影响。jQuery 提供了让开发人员快速添加效果(如滑动、淡入淡出、隐藏等)的功能。

滑动页面元素

滑动页面元素的能力使开发人员能够创建一系列接口,如手风琴。这个食谱将向您展示如何将滑动效果应用于一系列元素。

准备工作

使用你喜欢的文本编辑器或 IDE,在一个易于访问的位置创建一个空白的 HTML 页面,并将此文件保存为recipe-1.html。确保你已经在与此 HTML 文件相同的位置下载了最新版本的 jQuery。

如何做…

通过执行以下步骤学习如何使用 jQuery 滑动页面元素:

  1. 将以下 HTML 代码添加到recipe-1.html中。确保将 jQuery 库的源位置更改为下载并放置在您计算机上的最新版本 jQuery 的位置。

    <!DOCTYPE html>
    <html>
    <head>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-1.js"></script>
      <title>Chapter 4 :: JQuery Effects</title>
      <link type="text/css" media="screen" rel="stylesheet" href="recipe-1.css" />
    </head>
    <body>
      <div class="frame">
        <div class="actions">
          <button id="down">Slide Down</button>
          <button id="up">Slide Up</button>
        </div>
        <div class="box one"></div>
        <div class="box two"></div>
        <div class="box three"></div>
        <div class="box four"></div>
      </div>
    </body>
    </html>
    
  2. 除了 jQuery 库文件之外,您可能还注意到我们还包含了一个名为recipe-1.js的第二个 JavaScript 文件。创建此 JavaScript 文件并将其保存在与 HTML 文件相同的目录中。将以下 JavaScript 代码添加到recipe-1.js文件中:

    $(function(){
      $('#up').click(function(){
        $('.one').slideUp(4000);
        $('.two').slideUp(3000);
        $('.three').slideUp(2000);
        $('.four').slideUp(1000);
      });
      $('#down').click(function(){
        $('.one').slideDown(4000);
        $('.two').slideDown(3000);
        $('.three').slideDown(2000);
        $('.four').slideDown(1000);
      });
    });
    
  3. 除了这两个 JavaScript 文件,我们还包含了一个 CSS 文件,为我们的 HTML 元素添加了一些样式。在同一目录中创建recipe-1.css文件,并添加以下代码:

    .frame {
      width: 530px;
      height: 190px;
      margin: 50px auto auto auto;
      background-color: #E1E1E1;
      padding: 10px;
    }
    .frame .box {
      width: 125px;
      height: 125px;
      float: left;
      margin-right: 10px;
    }
    .frame .box:last-child {
      margin-right: 0;
    }
    .frame .actions {
      background-color: #333333;
      margin-bottom: 10px;
      text-align: center;
      padding: 10px;
    }
    .frame .actions button {
      height: 35px;
    }
    .one {
      background-color: red;
    }
    .two {
      background-color: green;
    }
    .three {
      background-color: blue;
    }
    .four {
      background-color: orange;
    }
    
  4. 在网络浏览器中打开recipe-1.html,您应该看到一个类似以下截图的网页:如何做…

  5. 单击向上滑动按钮,以看到应用于每个彩色框元素的向上滑动效果,速度各异;然后单击向下滑动以查看相反效果。

它是如何工作的…

现在,让我们详细了解以前执行的步骤。

HTML

我们为此食谱创建的 HTML 文件简单地使用 div 元素创建了四个框,然后提供了两个按钮,可与 jQuery 结合使用来触发元素效果。

jQuery

我们将所有 JavaScript 代码都包裹在$(function(){});中。这将确保我们的代码在页面加载时执行。在函数内部,我们按照以下代码片段所示,将点击事件附加到每个按钮:

$('#up').click(function(){
  $('.one').slideUp(4000);
  $('.two').slideUp(3000);
  $('.three').slideUp(2000);
  $('.four').slideUp(1000);
});
$('#down').click(function(){
  $('.one').slideDown(4000);
  $('.two').slideDown(3000);
  $('.three').slideDown(2000);
  $('.four').slideDown(1000);
});

.click() 函数允许我们在用户点击相应按钮后执行一组代码。在每个 .click() 方法的回调函数中,我们选择每个框的 div 元素,并使用 jQuery 的 .slideUp().slideDown() 函数,具体取决于用户单击了哪个按钮。

jQuery 的幻灯片函数允许您指定一系列参数。在上面的例子中,我们已经指定了效果持续时间(以毫秒为单位)。这使我们能够控制每个框元素向上或向下滑动所花费的时间,从而提供瀑布效果。

CSS

我们创建的 CSS 文件添加了样式并定位了每个 HTML 元素,使我们能够最好地展示 jQuery 的幻灯片功能。它允许我们更改每个框的背景颜色,并允许我们将界面居中对齐。

还有更多...

在前面的例子中,如果您多次单击 向上滑动向下滑动 按钮,您可能会注意到不同框元素之间的一些闪烁。这种闪烁是因为当向上滑动效果完成时,框元素的 CSS display 属性被设置为 none。这意味着该元素不仅将不可见,而且还不会影响任何相邻元素的位置。

因此,将设置为左浮动的元素会有更多空间向左移动,因为完成其向上滑动效果的框元素不再妨碍。如下截图所示:

还有更多...

在这里,您可以看到第二个绿色框元素的显示值设置为 none,导致其他框元素进一步向左浮动。当幻灯片动画已经多次触发并且元素必须向左移动以使其他元素变得不可见时,显示可能会闪烁更多。可以通过不允许触发多次触发效果来防止此类问题。在本章后面的 创建基本相册 配方中已经解释了这个问题的一个简单解决方案。

另请参阅

  • 淡入淡出元素

  • 隐藏和显示元素

  • 创建基本的相册

隐藏和显示元素

jQuery 包含一些函数,可以让您简单地隐藏和显示元素,尽管您可以将这些函数与其他效果结合使用。

准备就绪

创建一个名为 recipe-2.html 的新 HTML 文件,并将其保存到与您的 jQuery 库相同的文件夹中。

如何做…

通过执行以下步骤,了解如何使用 jQuery 轻松隐藏和显示 DOM 中的元素:

  1. recipe-2.html 中,添加以下 HTML 代码。确保对 jQuery 库的引用指向您下载版本的正确位置和文件名。

    <!DOCTYPE html>
    <html>
    <head>
      <title>Chapter 4 :: JQuery Effects :: Recipe 2</title>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-2.js"></script>
    </head>
    <body>
    <button class="show">Show</button>
    <button class="hide">Hide</button>
    <p class="text">Hiding and showing HTML elements with jQuery is so easy!</p>
    </body>
    </html>
    
  2. 创建一个名为 recipe-2.js 的 JavaScript 文件,并将其保存在与您刚刚创建的 HTML 文件相同的目录中。将以下 JavaScript 代码添加到此文件中:

    $(function(){
      $('#show').click(function(){
          $('.text').show();
      });
      $('#hide').click(function(){
          $('.text').hide();
      });
    });
    
  3. 在网页浏览器中打开recipe-2.html将呈现出一个非常基本的网页,其中包含两个按钮和一些文本。单击显示隐藏按钮将在文本上执行相关效果,演示如何使用 jQuery 显示和隐藏元素是多么简单。

工作原理…

现在,让我们详细了解之前执行的步骤。

HTML

此配方中使用的 HTML 代码非常基础,需要很少的解释。HTML 代码创建了一个带有两个按钮的网页。每个按钮都有自己的 ID——showhide。还有一个具有text类的单个段落元素。jQuery 将使用这些 ID 来监听点击事件并在段落元素上执行效果。

jQuery

与前一篇配方类似,我们为每个按钮附加了一个点击事件处理程序。这使我们能够根据点击了哪个按钮来执行效果。为此,我们使用以下代码:

$('#show').click(function(){
  $('.text').show();
});
$('#hide').click(function(){
  $('.text').hide();
});

要执行显示和隐藏效果,我们使用相应的 jQuery 函数show()hide()。这些 jQuery 函数简单地切换所选元素的显示属性(在本例中,段落元素具有text类)。将display属性设置为none可隐藏元素;将其设置为block可显示元素。

还有更多…

使用 jQuery 的show()hide()函数有额外的好处。使用 jQuery,您可以根据它们的内部 HTML 代码显示和隐藏元素。您还可以将show()hide()函数与其他 jQuery 效果或动画一起使用。

参见

  • 淡入淡出元素

  • 滑动页面元素

淡入淡出元素

如果仅仅显示或隐藏元素还不够,jQuery 提供了淡入淡出 HTML 元素的功能。此配方利用了 jQuery 的淡入和淡出功能,在选择显示或隐藏元素时添加了更多效果。

准备工作

创建一个名为recipe-3.html的空白 HTML 文件,并将其保存在与最新版本的 jQuery 相同的目录中。

如何做…

使用 jQuery 执行以下步骤来淡入淡出 DOM 元素:

  1. 将以下 HTML 代码添加到recipe-3.html,确保对 jQuery 库的引用正确:

    <!DOCTYPE html>
    <html>
    <head>
      <title>Chapter 4 :: JQuery Effects :: Recipe 3</title>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-3.js"></script>
      <link type="text/css" media="screen" rel="stylesheet" href="recipe-3.css" />
    </head>
    <body>
      <div class="frame">
        <div class="top">
          <label>Add Item:</label>
          <input type="text" id="new-item" />
          <button id="add-new-item">Add</button>
        </div>
        <ol class="list"></ol>
      </div>
    </body>
    </html>
    
  2. 在相同目录中创建一个 CSS 文件。将其保存为recipe-3.css,并添加以下代码来为 HTML 页面设置样式:

    .frame {
      width: 500px;
      min-height: 200px;
      margin: 50px auto auto auto;
      background-color: #E1E1E1;
      padding: 10px;
    }
    .top {
      background-color: #333333;
      padding: 10px;
      text-align: center;
      color: #FFF;
    }
    .list li {
      line-height: 30px;
    }
    
  3. 创建一个名为recipe-3.js的 JavaScript 文件,并添加以下 jQuery 代码:

    $(function(){
      $('#add-new-item').click(function(){
        var item = $('#new-item').val();
        if (item.length > 0) {
          var newItem = $("<li>" + item + "</li>").fadeIn();
          $('.list').append(newItem);
          $('#new-item').val("");
        }
      });
    });
    
  4. 在网页浏览器中打开recipe-3.html,你将看到一个类似以下截图的网页:如何做…

  5. 添加项目文本框中输入一些文本,然后单击添加按钮将使用 jQuery 淡入效果将输入的文本追加到列表中。

工作原理…

现在,让我们详细了解之前执行的步骤。

HTML

HTML 代码创建了一个包含文本输入和按钮以及一个空有序列表元素的简单界面,然后可以使用 jQuery 填充它。

CSS

添加了一个 CSS 文件以定位和样式化简单的用户界面,这样我们就可以更好地用 jQuery 展示淡入效果。

jQuery

首先,jQuery 代码使用以下代码将一个点击事件附加到添加按钮:

$(function(){
  $('#add-new-item').click(function(){

  });
});

我们在此回调函数中添加了以下代码,以提供所需的效果,使用fadeIn()函数将输入文本添加到列表中:

var item = $('#new-item').val();
if (item.length > 0) {
var newItem = $("<li>" + item + "</li>");
$('.list').append(newItem).fadeIn();
$('#new-item').val("");
}

此代码创建了item变量,并使用$('#new-item').val()将输入框的值赋给它。然后我们检查这个值的长度是否大于零,因为我们不想向列表中添加空白项。我们可以使用 JavaScript 简单地使用variablename.length(在本例中为item.length)来检查字符串的长度。

在这个if语句内部,我们创建另一个名为newItem的变量。我们将一个新创建的 HTML 列表项元素赋值给它,值是来自输入框的item变量。我们使用 jQuery 的选择器($())将列表项封装起来,这使我们能够对此 DOM 元素使用fadeIn()函数。

现在我们有了一个列表项,我们可以使用 jQuery 提供的append()函数将其追加到具有类名list的有序列表元素中。这将把新创建的 DOM 元素添加为有序列表的最后一个子元素。因为我们在这个 DOM 元素上使用了fadeIn()函数,它首先会隐藏,然后淡入,从而得到我们想要的效果。

还有更多...

在本文中,我们使用了fadeIn()函数,它允许我们使用淡入效果将一个不可见的元素变为可见。jQuery 还为我们提供了一个fadeOut()函数,它提供了相反的功能。这两个函数都接受一系列参数,允许开发人员调整行为。主要参数是持续时间,它允许我们以毫秒为单位指定元素淡入或淡出的时间。阅读有关这些函数的可用选项的更多信息,请访问api.jquery.com/fadeIn/

此外,jQuery 提供了一个fadeTo()函数,允许您在效果完成后不完全隐藏或显示元素,调整元素的不透明度。了解更多功能,请访问api.jquery.com/fadeTo/

另请参阅

  • 使用效果删除元素

  • 创建一个基本的照片库

  • 创建一个闪烁的按钮

切换效果

许多 jQuery 效果都有相反的功能,例如hide()show()以及fadeIn()fadeOut()。到目前为止,本章中的代码示例已经分别处理了每一个函数;例如,一个按钮用于显示,另一个按钮用于隐藏。对于其中一些函数,jQuery 提供了能够切换这些相反效果的能力。这是有益的,因为我们不需要单独处理每种情况,或者决定我们需要使用其中的哪一个。本文将查看切换功能,并向您展示如何使用它们。

准备工作

在您喜欢的文本编辑器或 IDE 中,创建一个名为recipe-4.html的空白 HTML 文件,并将其保存在与您的 jQuery 库相同的目录中。

操作步骤…

  1. 将以下 HTML 代码添加到recipe-4.html以创建一个基本的网页:

    <!DOCTYPE html>
    <html>
    <head>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-4.js"></script>
      <title>Chapter 4 :: JQuery Effects :: Recipe 4</title>
    </head>
    <body>
      <div>
        <button class="fadeToggle">Toggle Fade!</button>
        <button class="slideToggle">Toggle Slide!</button>
        <button class="hideToggle">Toggle Hide!</button>
      </div>
      <p class="text">Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out! Here is some text that can be faded in and out!</p>
    </body>
    </html>
    
  2. 您可能已经注意到我们在此 HTML 页面中包含了一个 JavaScript 文件。在与recipe-4.html相同的目录中创建此 JavaScript 文件,并将其保存为recipe-4.js。将以下 jQuery 代码添加到此文件中,以将点击事件处理程序附加到 HTML 中的按钮元素:

    $(function(){
      $('.fadeToggle').click(function(){
        $('.text').fadeToggle();
      });
      $('.slideToggle').click(function(){
        $('.text').slideToggle();
      });
      $('.hideToggle').click(function(){
        $('.text').toggle();
      });
    });
    
  3. 在 web 浏览器中打开recipe-4.html,您应该看到一个类似于以下截图的网页:操作步骤…

  4. 单击其中一个按钮将切换相关效果并将其应用于段落元素。

工作原理…

现在,让我们详细了解先前执行的步骤。

HTML

本示例中的 HTML 代码创建了一个带有一些文本的段落元素。该元素具有text类名,允许我们选择此元素并执行一系列效果。除了这个段落元素之外,HTML 还提供了三个不同的按钮。每个按钮都有不同的类名,允许我们使用 jQuery 检测每个单独的点击并根据点击的按钮执行不同的效果。

jQuery

本示例中的 jQuery 代码非常基础。在页面加载时,我们为每个按钮附加一个点击事件处理程序。每个点击事件处理程序在其回调函数内部有一个不同的切换功能。

jQuery 的切换函数确定了所选元素的状态,然后执行相反的效果。这意味着我们不需要将此逻辑编程到我们的应用程序中,而可以将其卸载到 jQuery。通过使用toggleFade()函数,我们可以使用一行代码来淡入或淡出段落元素,而无需针对每种情况编码,就像我们在先前的示例中所做的那样。对于执行滑动动画的slideToggle()方法也是如此。最后,我们可以使用toggle方法,它简单地隐藏或显示所选元素。

更多内容……

与其他 jQuery 效果函数一样,切换函数还可以接受一组可选参数。主要参数是效果持续时间。以下代码将强制幻灯片效果持续 1000 毫秒:

$('.slideToggle').click(function(){
$('.text').slideToggle(1000);
});

您可以在 jQuery API 文档中阅读有关其他可用选项的信息,该文档位于api.jquery.com/slideToggle/

停止效果

随着您的应用程序的增长以及开始使用更复杂的效果,您可能希望能够停止这些效果和转换。这可能是由于用户动作导致不再需要当前效果或某种其他形式的事件。

准备工作

创建一个名为recipe-5.html的空白 HTML 文档,并将其保存到最新版本的 jQuery 库所在的相同目录中。

操作步骤…

学习通过执行以下步骤停止 jQuery 效果:

  1. 将以下 HTML 代码添加到recipe-5.html中,以创建一个基本的网页,用于演示如何停止效果:

    <!DOCTYPE html>
    <html>
    <head>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-5.js"></script>
      <title>Chapter 4 :: JQuery Effects :: Recipe 5 </title>
      <link type="text/css" media="screen" rel="stylesheet" href="recipe-5.css" />
    </head>
    <body>
    <div class="frame">
      <div class="actions">
        <button id="slide">Slide</button>
        <button id="stop">Stop</button>
        <button id="Finish">Finish</button>
      </div>
      <ul class="output"></ul>
      <div class="slideMe"></div>
    </div>
    </body>
    </html>
    
  2. 为了更好地演示 jQuery 效果,我们需要添加一些 CSS 代码来样式化和定位recipe-5.html中的 HTML 元素。在同一目录中创建一个名为recipe-5.css的 CSS 文件,并添加以下代码:

    .frame {
      width: 600px;
      margin: auto;
      background-color: #CCC;
      padding: 10px;
    }
    .actions {
      padding: 10px;
      background-color: #333;
      text-align: center;
    }
    .slideMe {
      background-color: green;
      height: 150px;
      margin-top: 10px;
    }
    
  3. 要启动和停止 jQuery 效果,请创建一个名为recipe-5.js的 JavaScript 文件,并将其保存在与 HTML 和 CSS 文件相同的目录中。添加以下 jQuery 代码:

    $(function(){
      $('#slide').click(function(){
        $('.slideMe').slideToggle(1000, function(){
          $('.output').append("<li>Slide effect completed.</li>");
        });
      });
      $('#stop').click(function(){
        $('.slideMe').stop();
      });
      $('#finish').click(function(){
        $('.slideMe').finish();
      });
    });
    
  4. 在 Web 浏览器中打开recipe-5.html,您将看到一个类似以下屏幕截图的网页:操作步骤…

  5. 单击Slide按钮将开始该效果,绿色框 division 元素将开始向上滑动 1000 毫秒。单击Stop按钮将在您单击它的点停止效果,Finish按钮将立即完成效果。

工作原理…

现在,让我们详细了解之前执行的步骤。

HTML

我们这个教程的简单 HTML 为我们提供了一个可以应用效果的 division 元素,一些可以用于触发 jQuery 代码的按钮,以及我们可以用来输出有关执行的 jQuery 代码的一些信息的列表。

CSS

包含在 HTML 页面中的 CSS 代码使我们能够以一种能够轻松演示本教程中效果的方式定位每个 HTML 元素。

jQuery

我们在 HTML 页面中为三个按钮附加了三个不同的点击事件处理程序,通过使用它们的 ID 进行选择:slidestopfinish。在这些事件处理程序的回调函数中,我们使用以下代码启动幻灯片效果:

$('#slide').click(function(){
$('.slideMe').slideToggle(1000, function(){
  $('.output').append("<li>Slide effect completed.</li>");
});
});

我们使用slideToggle()函数来启动滑下或滑上效果,这取决于slideMedivision 元素当前是否可见。我们向slideToggle()函数提供了两个参数。第一个参数是我们希望滑动效果生效的持续时间。第二个参数是一个回调函数,一旦动画完成,将执行该函数。

在这个回调函数中,我们向具有类名output的无序列表元素追加了一个列表项。这意味着当幻灯片效果完全完成时,将在output列表中可见一个新的列表项。我们这样做是为了演示停止效果和完成效果之间的区别,后面的部分将对此进行描述。

另外两个事件处理程序,如下面的代码片段所述,以与先前提到的事件处理程序相同的方式选择slideMedivision 元素,除了这些不会启动一个效果,而是停止当前的效果:

$('#stop').click(function(){
  $('.slideMe').stop();
});
$('#finish').click(function(){
  $('.slideMe').finish();
});

stop()函数将停止在所选元素上当前正在运行的任何效果。如果滑动向上效果已经完成一半,您单击了Stop,您将看到一半绿色的slideMe分区元素。stop()函数不会完成滑动效果,因此slideToggle()回调函数不会被执行,并且不会向输出列表添加列表项。相反,finish()函数会立即完成在所选元素上正在执行的任何效果。这意味着如果滑动向上效果已经完成一半,您单击了FinishslideMe分区元素将立即变为不可见,然后向输出列表添加一个新项,上面写着滑动效果已完成。如果在效果回调函数中存在对您的应用程序至关重要的代码,您可以使用finish()来确保它被执行。或者,您可能不想执行此代码和/或想要明显地停止效果;在这种情况下,您将使用stop()

串联效果

jQuery 允许我们将不同的效果函数链到单个选定元素上。这使我们能够轻松地按顺序执行多个效果。

如何操作…

通过执行以下步骤,学习使用 jQuery 的强大功能来编写更好的代码:

  1. 创建一个名为recipe-6.html的空白 HTML 文件,并将其保存在计算机上易于访问的位置。将以下 HTML 代码添加到此文件中,并确保更新对 jQuery 库的引用:

    <!DOCTYPE html>
    <html>
    <head>
      <title>Chapter 4 :: JQuery Effects :: Recipe 6</title>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-6.js"></script>
      <link type="text/css" media="screen" rel="stylesheet" href="recipe-6.css" />
    </head>
    <body>
      <button id="start">Start</button>
      <div class="box"></div>
    </body>
    </html>
    
  2. 创建一个名为recipe-6.css的 CSS 文件,并添加以下代码:

    .box {
      width: 200px;
      height: 200px;
      background-color: red;
    }
    Create a JavaScript file and save it as recipe-6.js. Add the following JavaScript code.
    $(function(){
      $('#start').click(function(){                                              $('.box').fadeOut().fadeIn().slideUp().slideDown().fadeTo(1000, 0.1).fadeTo(1000, 1);
      });
    });
    
  3. 在网页中打开recipe-6.html文件,然后单击Start按钮。红色框将执行一系列效果。

工作原理…

本示例提供了一个非常简单的例子,说明了如何串联 jQuery 提供的不同效果函数。在此示例中,我们对盒子 div 元素执行fadeOut()fadeInslideUp()slideDown()和两个fadeTo()效果。由于以下代码位于start按钮的单击事件处理程序回调函数中,因此这些效果将依次执行:

$('.box').fadeOut().fadeIn().slideUp().slideDown().fadeTo(1000, 0.1).fadeTo(1000, 1);

fadeTo()函数会为选定的元素动画并改变其不透明度,它们都被提供了两个参数。第一个参数是效果持续的毫秒数,第二个是效果应该完成的不透明度。

参见

  • 创建基本的图库

创建基本的图库

大多数人都知道网络上有许多 jQuery 图库实现可供使用;其中许多是 jQuery 插件,可以快速实现。学习如何创建自己的图库也有好处。您将深入了解其中一些插件的工作原理,从而更轻松地定制它们以更好地满足您的需求。您还将了解更多关于 jQuery 的强大功能以及如何在本书中前面学到的技能。

准备工作

我们首先需要一个名为recipe-7.html的空白 HTML 文件,保存在与最新版本的 jQuery 相同的目录中。要创建一个图像画廊,我们还需要一些图像。在与recipe-7.html文件相同的目录中创建一个名为images的文件夹,并保存至少八张在 Internet 上免费可用的图像。

如何做…

通过执行以下步骤学习如何从头开始使用 jQuery 创建一个吸引人的相册:

  1. 将以下 HTML 代码添加到recipe-7.html以创建我们的网页和图像画廊 HTML 模板:

    <!DOCTYPE html>
    <html>
    <head>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-7.js"></script>
      <link rel="stylesheet" type="text/css" href="recipe-7.css" media="screen" />
      <title>Chapter 4 :: JQuery Events :: Recipe 7 - jQuery image gallery</title>
    </head>
    <body>
      <div class="gallery" data-thumb-width="150">
        <div class="frame">
          <img src="img/Chrysanthemum.jpg" />
          <img src="img/Desert.jpg" />
          <img src="img/Hydrangeas.jpg" />
          <img src="img/Jellyfish.jpg" />
          <img src="img/Koala.jpg" />
          <img src="img/Lighthouse.jpg" />
          <img src="img/Penguins.jpg" />
          <img src="img/Tulips.jpg" />
        </div>
        <div class="bottom">
          <a href="#" class="arrow left-arrow" data-direction="left"><i class="arrow-left"></i></a>
          <a href="#" class="arrow right-arrow" data-direction="right"><i class="arrow-right"></i></a>
          <div class="thumbs"></div>
        </div>
      </div>
    </body>
    </html>
    
  2. 更新 frame division 元素内每个图像的源(src="img/code>),使其指向您刚刚添加的图像。

  3. 在与recipe-7.html相同的目录中创建一个名为recipe-7.css的 CSS 文件,并添加以下 CSS 代码来样式化我们的画廊:

    body {
      margin: 0;
      padding: 0;
      background-color: #333;
    }
    .gallery {
      width: 600px;
      margin: 50px auto auto auto;
      position: relative;
    }
    .gallery .frame {
      height: 450px;
      margin-bottom: 10px;
      position: relative;
    }
    .gallery .frame img {
      display: block;
      width: 100%;
      position: absolute;
      left: 0;
      top: 0;
    }
    .gallery .bottom {
      overflow: hidden;
    }
    .gallery .thumbs {
      height: 120px;
      white-space: nowrap;
      text-align: center;
    }
    .gallery .thumbs a {
      display: inline-block;
      opacity: 0.5;
      -webkit-transition: opacity 0.5s ease-in-out;
      -moz-transition: opacity 0.5s ease-in-out;
      -ms-transition: opacity 0.5s ease-in-out;
      -o-transition: opacity 0.5s ease-in-out;
      transition: opacity 0.5s ease-in-out;
    }
    .gallery .thumbs a:hover {
      opacity: 1.0;
    }
    .gallery .arrow {
      width: 50px;
      height: 50px;
      background-color: #000;
      position: absolute;
      -webkit-border-radius: 50px;
      -moz-border-radius: 50px;
      border-radius: 50px;
      bottom: 35px;
    }
    .gallery .arrow.disabled {
      background-color: #252525;
    }
    .gallery .left-arrow {
      left: -60px;
    }
    .gallery .right-arrow {
      right: -60px;
    }
    .gallery .arrow-right {
      width: 0;
      height: 0;
      border-top: 12px solid transparent;
      border-bottom: 12px solid transparent;
      border-left: 12px solid #1a1a1a;
      position: absolute;
      right: 16px;
      top: 13px;
    }
    .gallery .arrow-left {
      width: 0;
      height: 0;
      border-top: 12px solid transparent;
      border-bottom: 12px solid transparent;
      border-right:12px solid #1a1a1a;
      position: absolute;
      right: 21px;
      top: 13px;
    }
    
  4. 创建一个名为recipe-7.js的 JavaScript 文件,并添加以下 JavaScript 代码来启动我们的画廊:

    /** DECLARE SOME DEFAULT VARIABLES WHICH WILL BE USED THROUGHOUT **/
    var images;
    var imageWidth;
    $(function(){
      imageWidth = $('.gallery').data("thumb-width");
      /** COLLECT ALL THE IMAGES FROM WITHIN THE .gallery DIV **/
      images = $('.gallery').find('img');
      /** FOR EACH OF THESE IMAGES, CREATE A THUMBNAIL AND ADD A CLASS TO IDENTIFY THE IMAGE AND THUMBNAIL RELATIONSHIP **/
      $.each(images, function(index, value){
        $(value).addClass("img" + index);
        $('.gallery .thumbs').append("<a href='#' data-index='" + index + "' class='thumb'><img src='" + $(this).prop("src") + "' width='" + imageWidth + "' height='120' border='0' /></a>");
      });
      /** UPDATE THE SCROLL BUTTONS **/
      updateScrollButtons();
      /** EVENT HANDLERS FOR SCROLL BUTTONS **/
      $('.arrow').click(function(){
        var element = $(this);
        if (!element.hasClass('disabled')) {
          element.addClass('disabled');
          var scrollString = "-=";
          if ($(this).data("direction") == "left") {
            scrollString = "+=";
          }
          $('.thumbs').animate({
            marginLeft: scrollString + imageWidth + "px"
          }, "fast", function(){
            element.removeClass('disabled');
            updateScrollButtons();
          });
        }
      });
      /** EVENT HANDLERS FOR IMAGES **/
      $('.gallery').on("click", ".thumb", function(){
        var thumb = $(this);
        var image = $('.img' + thumb.data('index'));
        $.each(images, function(index, value){
          if (!$(value).hasClass('img' + thumb.data('index'))) {
            $(value).hide();
          }
        });
        if (image.css("display") != "block") {
          image.fadeIn();
        }
      });
    });
    function updateScrollButtons() {
      var thumbs = $('.thumbs');
      var thumbsMarginLeft = parseInt(thumbs.css("margin-left"));
      var thumbsMaxWidth = (images.length * imageWidth);
      if (thumbsMarginLeft >= 0) {
        $('.left-arrow').addClass('disabled');
      } else {
        $('.left-arrow').removeClass('disabled');
      }
      if ((thumbsMarginLeft * -1) >= (thumbsMaxWidth - thumbs.width() / 2)) {
        $('.right-arrow').addClass('disabled');
      } else {
        $('.right-arrow').removeClass('disabled');
      }
    }
    
  5. 在 Web 浏览器中打开recipe-7.html,您将看到一个类似以下截图的 jQuery 图像画廊:How to do it…`

  6. 选择左右箭头将允许您滚动照片,单击照片将在主框架中显示较大版本。

工作原理…

现在,让我们详细了解之前执行的步骤。

HTML

由于 jQuery 的帮助,我们能够用极少的 HTML 代码创建一个吸引人且功能齐全的画廊。除了基本的 HTML 文档结构之外,我们还定义了一个类为gallery的 division 元素。以下是 jQuery 将用来基于大多数 DOM 交互的 division 元素代码:

<div class="gallery" data-thumb-width="150"></div>

另外,我们还使用 HTML5 数据属性来定义缩略图的宽度。我们的 jQuery 代码将使用此值来调整缩略图的大小。

使用以下 HTML 代码,我们还创建了一个类名为frame的 division 元素,其兄弟元素是我们想要在画廊中显示的图像:

<div class="frame">
<img src="img/Chrysanthemum.jpg" />
<img src="img/Desert.jpg" />
<img src="img/Hydrangeas.jpg" />
<img src="img/Jellyfish.jpg" />
<img src="img/Koala.jpg" />
<img src="img/Lighthouse.jpg" />
<img src="img/Penguins.jpg" />
<img src="img/Tulips.jpg" />
</div>

最后,在我们的 HTML 中,我们创建一个左右箭头,它将与 jQuery 一起使用来滚动图像缩略图。我们还创建了一个类为thumbs的 div 元素,将使用以下 jQuery 代码填充缩略图图像:

<div class="bottom">
<a href="#" class="arrow left-arrow" data-direction="left"><i class="arrow-left"></i></a>
<a href="#" class="arrow right-arrow" data-direction="right"><i class="arrow-right"></i></a>
<div class="thumbs"></div>
</div>

CSS

此配方中使用的大部分 CSS 代码都非常基础,只是将元素放置在页面的适当位置。主画廊 division 元素设置为 600 像素宽,并居中显示在屏幕上。为了使我们能够将左右箭头放在画廊框架外部,我们将它们的位置设置为绝对,并使用负边距将它们推到更左和更右。

主缩略图滚动部分的 overflow 值设置为 hidden,防止大部分缩略图被显示。 这使我们可以使用 jQuery 将这些元素滚动到视图中。 缩略图本身的 display 值设置为 inline-block,允许它们在单行中左到右堆叠在一起。

为了产生附加效果,我们还使用了一些基本的 CSS 动画。 缩略图的不透明度设置为 0.5,以便它们不会成为应用程序的主要焦点。 当用户悬停在缩略图上时,使用 CSS 过渡创建淡入效果,如下所示:

.gallery .thumbs a {
  display: inline-block;
  opacity: 0.5;
  -webkit-transition: opacity 0.5s ease-in-out;
  -moz-transition: opacity 0.5s ease-in-out;
  -ms-transition: opacity 0.5s ease-in-out;
  -o-transition: opacity 0.5s ease-in-out;
  transition: opacity 0.5s ease-in-out;
}
.gallery .thumbs a:hover {
  opacity: 1.0;
}

除了官方的 CSS3 transition 属性之外,我们还使用了浏览器特定的替代方案,以确保 CSS 动画在所有最流行的浏览器中都能正常工作。

-webkit-transition: opacity 0.5s ease-in-out;
-moz-transition: opacity 0.5s ease-in-out;
-ms-transition: opacity 0.5s ease-in-out;
-o-transition: opacity 0.5s ease-in-out;

jQuery

JavaScript 文件开头声明了两个变量,以便它们的值可以在整个应用程序中使用;这些变量称为全局变量。 应用程序代码的大部分被放置在 jQuery 的加载函数中,这样一旦页面加载完成,代码就会执行,如下所示:

var images;
var imageWidth;
$(function(){
  imageWidth = $('.gallery').data("thumb-width");
  /** COLLECT ALL THE IMAGES FROM WITHIN THE .gallery DIV **/
  images = $('.gallery').find('img');
  /** FOR EACH OF THESE IMAGES, CREATE A THUMBNAIL AND ADD A CLASS TO IDENTIFY THE IMAGE AND THUMBNAIL RELATIONSHIP **/
  $.each(images, function(index, value){
    $(value).addClass("img" + index);
    $('.gallery .thumbs').append("<a href='#' data-index='" + index + "' class='thumb'><img src='" + $(this).prop("src") + "' width='" + imageWidth + "' height='120' border='0' /></a>");
  });
});

使用 jQuery 的 data() 函数从我们之前创建的 HTML 代码中提取缩略图宽度。 然后将该值存储在 imageWidth 变量中,供以后在应用程序中使用。 使用 $('.gallery').find('img') 函数搜索 gallery div 元素中的所有 img 元素并将它们存储为 images 变量中的数组。 使用 jQuery $.each() 函数来迭代 images 数组中的每个 img 元素。 在 $.each() 的回调函数中,我们首先使用 addClass() 函数基于数组索引为主图像元素添加一个类(即 img0img1 等等)。 然后,创建一个带有图像的锚元素,并使用先前声明的 imageWidth 变量来设置宽度。 使用 append() 函数,然后将锚元素插入到 DOM 中 thumbs div 元素中。 此外,该锚元素的 data-index 属性值设置为与较大图像的类名相匹配。

$.each() 函数中,我们调用一个名为 updateScrollButtons 的自定义函数,该函数在 JavaScript 文件的末尾声明。 该函数用于根据当前缩略图的位置确定是否应该启用箭头按钮。 这可以防止用户将缩略图滚动到图像库的底部部分。 一旦用户向右滚动到最后的缩略图,右箭头按钮就会被禁用。 一旦用户向左滚动到第一个缩略图,左箭头按钮就会被禁用。

接下来,使用以下代码为每个箭头按钮附加了一个点击事件处理程序,以便我们可以检测用户何时想要浏览缩略图图像。

$('.arrow').click(function(){
var element = $(this);
if (!element.hasClass('disabled')) {
  element.addClass('disabled');
  var scrollString = "-=";
  if ($(this).data("direction") == "left") {
    scrollString = "+=";
  }
  $('.thumbs').animate({
    marginLeft: scrollString + imageWidth + "px"
  }, "fast", function(){
    element.removeClass('disabled');
    updateScrollButtons();
  });
}
});

在点击事件处理程序的回调函数中,我们首先声明一个变量,并将点击的元素存储在其中,引用为 $(this),意思是点击的元素。使用此变量,我们可以使用 jQuery 函数 hasClass 来确定点击的元素是否具有类 disabled。我们将此函数中的所有代码包装在 if 语句中,以便如果点击的元素具有 disabled 类,则不执行此代码。在 if 语句中,我们使用 addClassdisabled 类添加到点击的元素中。这是为了防止用户能够频繁点击滚动箭头并导致不希望的动画效果。

我们还声明了一个名为 scrollString 的变量,其默认值为 -=。该值将在 jQuery 的 animate() 函数中使用,该函数将为我们的缩略图提供滚动动画。根据所点击的箭头的 data-direction 属性值,此值将保持为 -=,这意味着 thumbs div 的左边距将被减去(即向右滚动),或者该值将更改为 +=,这意味着左边距将被添加(即向左滚动)。

最后,在此事件处理程序回调函数中,使用 jQuery 的 animate() 函数修改 thumbs div 元素的左边距,从而提供滚动效果。再次使用 imageWidth 变量来设置滚动位置以匹配缩略图的宽度,如下所示:

$('.gallery').on("click", ".thumb", function(){
var thumb = $(this);
var image = $('.' + thumb.attr('rel'));
$.each(images, function(index, value){
    if (!$(value).hasClass(thumb.attr('rel'))) {
        $(value).hide();
    }
});
if (image.css("display") != "block") {
    image.fadeIn();
}
});

下一段代码的下一步是将点击事件处理程序附加到 gallery div 元素上。点击事件处理程序监听任何具有 thumb 类的元素上的点击。这使我们能够指定在单击缩略图后要执行的代码。在回调函数中,我们选择被点击的缩略图并将元素引用存储在 thumb 变量中。我们还使用点击的元素的 data-index 属性值来选择较大的图像,并将其引用存储在 image 中。

再次使用 $.each() 函数来迭代所有图像。我们隐藏与点击的缩略图中的图像不匹配的每个图像。这样只有所选图像才会出现在主查看面板中。我们还使用 css() 函数来检查较大图像的 display 属性,以确定图像当前是否可见。如果不可见,我们使用 jQuery 的淡入效果来显示它,完成图像库功能。

创建一个闪烁的按钮

使用 jQuery 的效果函数,我们可以创建一个闪烁的按钮,可以在 Web 应用程序或网站中使用,以吸引用户的注意力。

准备工作

创建一个名为 recipe-8.html 的空白 HTML 文档,并确保您已下载并准备好将其包含在此 HTML 文件中的最新版本的 jQuery。

如何做...

通过执行以下步骤了解如何使用 jQuery 创建一个简单的闪烁按钮效果:

  1. 将以下代码添加到刚刚创建的recipe-8.html中,记得更新对 jQuery 库的引用。

    <!DOCTYPE html>
    <html>
    <head>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-8.js"></script>
      <title>Chapter 4 :: JQuery Effects :: Recipe 8 </title>
      <link type="text/css" media="screen" rel="stylesheet" href="recipe-8.css" />
    </head>
    <body>
    <div class="frame">
      <h1>Newsletter!</h1>
      <p>Enter your email address below to sign-up for our monthly newsletter.</p>
      <form>
        <input type="text" class="email-input" name="email" placeholder="Your Email" />
         <button class="blinker">Sign-up Now!</button>
      </form>
    </div>
    </body>
    </html>
    
  2. 创建一个名为recipe-8.css的 CSS 文件,并添加以下 CSS 代码以为 HTML 中创建的通讯表单添加样式:

    @import url(http://fonts.googleapis.com/css?family=Leckerli+One);
    @import url(http://fonts.googleapis.com/css?family=Happy+Monkey);
    body {
      background-color: #333333;
      font-family: 'Happy Monkey', cursive;
    }
    h1 {
      font-family: 'Leckerli One', cursive;
      font-size: 60px;
      line-height: 80px;
      padding: 0;
      margin: 0;
      text-align: center;
      color: #333;
    }
    .frame {
      width: 500px;
      margin: 50px auto auto auto;
      height: 300px;
      background-color: #FFF;
      box-shadow: #000 3px 3px 2px;
      border-radius: 10px;
      padding: 20px;
      text-align: center;
    }
    .frame p {
      font-size: 18px;
      line-height: 25px;
    }
    .frame form .email-input {
      height: 40px;
      font-size: 30px;
      width: 400px;
      font-family: 'Happy Monkey', cursive;
    }
    .frame form .blinker {
      height: 40px;
      width: 150px;
      font-size: 20px;
      margin-top: 20px;
      font-family: 'Happy Monkey', cursive;
    }
    
  3. 在与 CSS 和 HTML 文件相同的目录中创建一个 JavaScript 文件。将此文件保存为recipe-8.js并添加以下 jQuery 代码:

    $(function(){
      $('.email-input').on('focus', function(){
        $('.blinker').fadeTo(300, 0.1).fadeTo(300, 1);
      })
    });
    
  4. 在 Web 浏览器中打开recipe-8.html,你会看到一个类似下面截图的网页:如何操作…

  5. 单击文本框内部将使“立即注册!”按钮闪烁以吸引用户的注意。

工作原理是…

在此配方中使用的 HTML 和 CSS 代码创建了一个页面,允许用户订阅通讯。HTML 或 CSS 代码中没有复杂的元素,因此不需要进一步解释。

这个配方提供了一个简单的示例,演示了我们如何使用 jQuery 来实现按钮闪烁的外观。其思想是,当用户点击文本框输入电子邮件地址时,“立即注册!”按钮会闪烁以吸引他们的注意。

在我们的 jQuery 代码中,我们首先将事件处理程序附加到文本输入以获得焦点。当页面上的元素受到用户的关注时,即通过点击它或通过标签切换到表单元素时,将触发“焦点”事件。在此事件处理程序的回调函数中,我们使用fadeTo()jQuery 效果函数来顺序淡出并淡入按钮,创建闪烁效果。在本示例中,fadeTo()函数接受两个参数,效果持续时间和元素不透明度。我们在第一个fadeTo()函数中指定元素的不透明度为0.1,以淡出按钮。然后我们指定1.0以淡入按钮。我们可以通过改变指定的持续时间来控制效果的速度,该持续时间设置为300毫秒。

还有更多……

有许多方法可以使用 jQuery 创建闪烁效果。在 第六章 用户界面 中,您将学习如何更改元素的 CSS 属性,从而可以添加阴影和彩色边框,以大大增强闪烁效果。fadeTo()函数提供了创建此效果的最简单方法,但请注意,有一些替代方法可以提供更大的影响,可能更适合您的需求。

当强制元素闪烁、移动或闪烁以吸引用户的注意时,必须非常小心,以免引起烦恼,因为这可能会产生相反的效果,使他们远离。这些效果只应用作微妙的提示,以促使用户与您的用户界面进行交互。

另请参见

  • 淡出元素

  • 创建一个基本的照片库

带有效果的删除元素

通常,您会创建诸如列表或表格之类的界面,用于表示来自数据库的数据。如果界面是用于管理目的,通常可以添加、编辑和删除这些项目。当添加这些项目时,我们可以使用 jQuery 效果来增强用户体验,如淡出元素示例中所述。当从 DOM 中删除项目时,我们也可以提供效果。由于 jQuery,这非常容易做到。

准备就绪

与本章中的其他示例一样,您需要一个空白的 HTML 文档。将此文档保存为recipe-9.html,并确保它与最新版本的 jQuery 在同一个目录中。

如何做...

了解如何通过执行以下步骤以带有效果的方式移除 DOM 元素:

  1. 将以下 HTML 代码添加到您刚刚创建的 HTML 文档中:

    <!DOCTYPE html>
    <html>
    <head>
      <script src="img/jquery.min.js"></script>
      <script src="img/recipe-9.js"></script>
       <title>Chapter 4 :: JQuery Effects :: Recipe 9 </title>
      <link type="text/css" media="screen" rel="stylesheet" href="recipe-9.css" />
    </head>
    <body>
    <div class="frame">
      <h1>User Management</h1>
      <table width="100%" id="user-table">
        <thead>
        <tr>
          <th>Username</th>
          <th>Email</th>
          <th>Full Name</th>
          <th>Date of Birth</th>
          <th></th>
        </tr>
        </thead>
        <tbody>
        <tr>
          <td>jd101</td>
          <td>j.doe@somewhere.com</td>
          <td>John Doe</td>
          <td>16-05-1987</td>
          <td><button class="delete">Delete</button></td>
        </tr>
        <tr>
          <td>msmith17</td>
          <td>smithy@nowhere.com</td>
          <td>Jane Smith</td>
          <td>18-08-1988</td>
          <td><button class="delete">Delete</button></td>
        </tr>
        <tr>
          <td>tommy22</td>
          <td>tom@idontknow.com</td>
          <td>Thomas Knowhow</td>
          <td>10-08-1980</td>
          <td><button class="delete">Delete</button></td>
        </tr>
        </tbody>
      </table>
    </div>
    </body>
    </html>
    
  2. 您可能已经注意到了前一个 HTML 代码的标题中包含的 CSS 文件。创建recipe-9.css并添加以下 CSS 代码:

    @import url(http://fonts.googleapis.com/css?family=Lato:300,400);
    body {
      background-color: #333333;
      font-family: 'Lato', sans-serif;
    }
    h1 {
      line-height: 60px;
      padding: 0;
      margin: 0 0 15px 0;
      text-align: center;
      color: #333;
      font-weight: 300;
    }
    .frame {
      width: 700px;
      margin: 50px auto auto auto;
      background-color: #FFF;
      box-shadow: #000 3px 3px 2px;
      border-radius: 10px;
      padding: 20px;
      text-align: center;
    }
    
  3. 除了 CSS 文件外,HTML 页面还包含了一个 JavaScript 文件。创建一个名为recipe-9.js的 JavaScript 文件,并将其保存在与 HTML 和 CSS 文件相同的目录中。将以下 jQuery 代码添加到此文件中:

    $(function(){
      $('#user-table').on("click", ".delete", function(){
        var response = confirm("Are you sure you want to delete this user?");
        if (response) {
          $(this).parent().parent().fadeOut().remove();
        }
      });
    });
    
  4. 在网页浏览器中打开recipe-9.html,你将看到一个简单的用户管理界面。点击任何条目旁边的删除按钮将提示你确认是否要删除。当用户点击确定时,该特定用户的条目将淡出并从 DOM 中移除。

工作原理...

这个示例也有一些基本的 HTML 和 CSS 代码,不需要解释。相反,让我们专注于 jQuery 代码。

我们所有的 jQuery 代码都包装在$(function(){});中,这是 jQuery 的加载函数,允许我们在页面加载时执行。我们将点击事件处理程序附加到用户表,并监听任何具有delete类的元素的点击,如下所示。从 HTML 代码中,您将知道这些元素是delete按钮。

$('#user-table').on("click", ".delete", function(){

});

在此事件处理程序的回调函数内部,我们使用原生 JavaScript 函数confirm()并将其输出分配给response变量。这将向用户显示一个弹出窗口,其中包含消息确定要删除此用户吗?。如果用户点击确定,则response变量将等于true。如果他们点击取消,它将是false。通过使用这个response变量,我们可以确定他们是否想要继续删除用户。如果是,我们可以从 DOM 中移除表格行。

要删除表格行,我们首先需要选择它。我们可以引用$(this),它是被点击的项目(在本例中是按钮),然后选择其父级的父级,即tr表。这是使用以下代码完成的:

$(this).parent().parent().fadeOut().remove();

然后我们使用fadeOut()函数应用效果,并使用remove()函数从 DOM 中删除元素。

还有更多...

这种简单的用户界面通常会与服务器端调用结合使用,这些调用还会从数据库中删除用户输入。回顾一下第三章,使用 jQuery 和 AJAX 加载和操作动态内容,看看如何使用 jQuery 和 AJAX 完成这项任务。

另请参阅

  • 淡入淡出元素

第五章:表单处理

在本章中,我们将探讨如何创建具有动画、验证和用户反馈的健壮而引人入胜的网络表单。我们将涵盖:

  • 实施基本表单验证

  • 添加数字验证

  • 添加信用卡号验证

  • 添加日期验证

  • 添加电子邮件地址验证

  • 实施实时表单验证

  • 添加密码强度指示器

  • 添加反垃圾邮件措施

  • 实施输入字符限制

介绍

收集用户数据是许多网站和网络应用程序的基本功能,从简单的数据收集技术,如注册或登录信息,到更复杂的情景,如付款或账单信息。重要的是只收集来自用户的相关和完整信息。为了确保这一点,Web 开发人员必须对所有数据输入进行验证。在执行数据完整性的同时提供良好的用户体验也很重要。这可以通过向用户提供有关其数据可能引起的任何验证错误的有用反馈来实现。本章将向您展示如何创建一个引人入胜的网络表单,同时保持高质量的用户体验。

非常重要的一点是,任何 JavaScript 或 jQuery 验证都容易被用户操纵。JavaScript 和 jQuery 位于 Web 浏览器中,所以用户可以轻松修改代码以绕过任何客户端验证技术。这意味着不能完全依赖客户端验证来防止用户提交无效数据。在客户端进行的任何验证都必须在服务器上进行复制,服务器不容易被用户操纵。

我们使用客户端验证来提高用户体验。因此,用户不需要等待服务器响应。

实施基本表单验证

在最基本的表单验证级别上,您需要能够阻止用户提交空值。本教程将为本章的第 1 至 8 个配方提供用于网络表单的 HTML 和 CSS 代码。

准备工作

使用您喜欢的文本编辑器或 IDE,在易于访问的位置创建一个空白的 HTML 页面,并将此文件保存为recipe-1.html。确保您已将最新版本的 jQuery 下载到与此 HTML 文件相同的位置。

这个 HTML 页面将成为本章大部分内容的基础,请在完成本教程后记得保存它。

如何做...

通过执行以下步骤学习如何使用 jQuery 实现基本表单验证:

  1. 将以下 HTML 代码添加到index.html中。确保更改包含 jQuery 库的 JavaScript 的源位置,指向您计算机上下载的 jQuery 的最新版本所在位置。

    <!DOCTYPE html>
    <html >
    <head>
       <title>Chapter 5 :: Recipe 1</title>
       <link type="text/css" media="screen" rel="stylesheet" href="styles.css" />
       <script src="img/jquery.min.js"></script>
       <script src="img/validation.js"></script>
    </head>
    <body>
       <form id="webForm" method="POST">
          <div class="header">
             <h1>Register</h1>
          </div>
          <div class="input-frame">
             <label for="firstName">First Name:</label>
             <input name="firstName" id="firstName" type="text" class="required" />
          </div>
          <div class="input-frame">
             <label for="lastName">Last Name:</label>
             <input name="lastName" id="lastName" type="text" class="required" />
          </div>
          <div class="input-frame">
             <label for="email">Email:</label>
             <input name="email" id="email" type="text" class="required email" />
          </div>
          <div class="input-frame">
             <label for="number">Telephone:</label>
             <input name="number" id="number" type="text" class="number" />
          </div>
          <div class="input-frame">
             <label for="dob">Date of Birth:</label>
             <input name="dob" id="dob" type="text" class="required date" placeholder="DD/MM/YYYY"/>
          </div>
          <div class="input-frame">
             <label for="creditCard">Credit Card #:</label>
             <input name="creditCard" id="creditCard" type="text" class="required credit-card" />
          </div>
          <div class="input-frame">
             <label for="password">Password:</label>
             <input name="password" id="password" type="password" class="required" />
          </div>
          <div class="input-frame">
             <label for="confirmPassword">Confirm Password:</label>
                <input name="confirmPassword" id="confirmPassword" type="password" class="required" />
          </div>
          <div class="actions">
             <button class="submit-btn">Submit</button>
          </div>
       </form>
    </body>
    </html>
    
  2. 在同一目录下创建名为styles.css的 CSS 文件,并添加以下 CSS 代码以为我们的 HTML 页面和表单添加样式:

    @import url(http://fonts.googleapis.com/css?family=Ubuntu);
    body {
       background-color: #FFF;
       font-family: 'Ubuntu', sans-serif;
    }
    form {
       width: 500px;
       padding: 20px;
       background-color: #333;
       border-radius: 5px;
       margin: 10px auto auto auto;
       color: #747474;
       border: solid 2px #000;
    }
    form label {
       font-size: 14px;
       line-height: 30px;
       width: 27%;
       display: inline-block;
       text-align: right;
    }
    .input-frame {
       clear: both;
       margin-bottom: 25px;
       position: relative;
    }
    form input {
       height: 30px;
       width: 330px;
       margin-left: 10px;
       background-color: #191919;
       border: solid 1px #404040;
       padding-left: 10px;
       color: #DB7400;
    }
    form input:hover {
       background-color: #262626;
    }
    form input:focus {
       border-color: #DB7400;
    }
    form .header {
       margin: -20px -20px 25px -20px;
       padding: 10px 10px 10px 20px;
       position: relative;
       background-color: #DB7400;
       border-top-left-radius: 4px;
       border-top-right-radius: 4px;
    }
    form .header h1 {
       line-height: 50px;
       margin: 0px;
       padding: 0px;
       color: #FFF;
       font-weight: normal;
    }
    .actions {
       text-align: right;
    }
    .submit-btn {
       background-color: #DB7400;
       border: solid 1px #000;
       border-radius: 5px;
       color: #FFF;
       padding: 10px 20px 10px 20px;
       text-decoration: none;
       cursor: pointer;
    }
    .error input {
       border-color: red;
    }
    .error-data {
       color: red;
       font-size: 11px;
       position: absolute;
       bottom: -15px;
       left: 30%;
    }
    
  3. 除了 jQuery 库外,先前的 HTML 页面还使用了另一个 JavaScript 文件。在保存index.html文件的目录中创建一个空白的 JavaScript 文件。将该文件保存为validation.js,并添加以下 JavaScript 代码:

    $(function(){
       $('.submit-btn').click(function(event){
          //Prevent form submission
          event.preventDefault();
          var inputs = $('input');
          var isError = false;
          //Remove old errors
          $('.input-frame').removeClass('error');
          $('.error-data').remove();
          for (var i = 0; i < inputs.length; i++) {
             var input = inputs[i];
             if ($(input).hasClass('required') && !validateRequired($(input).val())) {
                addErrorData($(input), "This is a required field");
                isError = true;
             }
    
          }
          if (isError === false) {
             //No errors, submit the form
             $('#webForm').submit();
          }
       });
    });
    
    function validateRequired(value) {
       if (value == "") return false;
       return true;
    }
    
    function addErrorData(element, error) {
       element.parent().addClass("error");
       element.after("<div class='error-data'>" + error + "</div>");
    }
    
  4. 在网络浏览器中打开index.html,您应该会看到一个类似下面截图的表单:如何操作…

  5. 如果您单击提交按钮提交一个空表单,将会在必填字段下方显示错误消息。

工作原理…

现在,让我们详细了解之前执行的步骤。

HTML

HTML 创建了一个包含各种字段的网络表单,这些字段将接受一系列数据输入,包括文本、出生日期和信用卡号码。该页面构成了本章大部分内容的基础。每个输入元素都被赋予了不同的类,具体取决于它们需要什么类型的验证。对于本示例,我们的 JavaScript 只会查看required类,该类表示必填字段,因此不能为空。其他类已添加到输入字段中,例如datenumber,这些类将在本章后续示例中使用。

CSS

已添加基本 CSS 以创建吸引人的网络表单。CSS 代码为输入字段添加样式,使其与表单本身融为一体,并添加了悬停效果。还使用了谷歌 Web 字体 Ubuntu 来改善表单的外观。

jQuery

jQuery 代码的第一部分被包裹在$(function(){});中,这将确保代码在页面加载时执行。在这个包装器内部,我们将点击事件处理程序附加到表单提交按钮,如下所示:

$(function(){
    $('.submit-btn').click(function(event){
        //Prevent form submission
        event.preventDefault();

    });
});

由于我们希望根据是否提供了有效数据来处理表单提交,所以我们使用event.preventDefault();来最初阻止表单提交,从而允许我们首先执行验证,如下所示:

var inputs = $('input');
var isError = false;

preventDefault代码之后,声明了一个inputs变量,用于保存页面内所有输入元素,使用$('input')来选择它们。此外,我们创建了一个isError变量,并将其设置为false。这将是一个标志,用于确定我们的验证代码是否在表单中发现了错误。这些变量声明如上所示。通过inputs变量的长度,我们能够循环遍历页面上的所有输入。我们为每个迭代的输入创建一个输入变量,该变量可用于使用 jQuery 对当前输入元素执行操作。使用以下代码完成此操作:

for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
}

在输入变量被声明并分配了当前输入后,使用以下代码从元素中移除任何先前的错误类或数据:

$(input).parent().removeClass('error');
$(input).next('.error-data').remove();

第一行代码从输入框的父元素(.input-frame)中移除了error类,该类将为输入元素添加红色边框。第二行代码会移除在输入数据验证检查确定该输入数据无效时在输入框下方显示的错误信息。

接下来,使用 jQuery 的hasClass()函数来确定当前输入元素是否具有required类。如果当前元素确实具有这个类,我们需要执行所需的验证以确保该字段包含数据。我们在if语句内调用validateRequired()函数,并通过当前输入的值,如下所示:

if ($(input).hasClass('required') && !validateRequired($(input).val())) {
addErrorData($(input), "This is a required field");
   isError = true;
}

我们使用感叹号 ! 前置调用validateRequired()函数来检查是否该函数的结果等于false;因此,如果当前输入具有required类且validateRequired()返回false,则当前输入的值无效。如果是这种情况,我们在if语句内调用addErrorData()函数,并传递当前输入和错误消息,该消息将显示在输入框下方。我们还将isError变量设置为true,以便在之后的代码中我们将知道发生了验证错误。

JavaScript 的for循环将对页面上选择的每个输入元素重复执行这些步骤。for循环完成后,我们检查isError标志是否仍然设置为false。如果是,我们使用 jQuery 手动提交表单,如下所示:

if (isError === false) {
   //No errors, submit the form
   $('#webForm').submit();
}

请注意,运算符===用于比较isError的变量类型(即Boolean)及其值。在 JavaScript 文件的底部,我们声明了之前在脚本中调用的两个函数。第一个函数validateRequired()简单地获取输入值并检查它是否为空。如果值为空,函数返回false,表示验证失败;否则,函数返回true。可以编码如下:

function validateRequired(value) {
    if (value == "") return false;
    return true;
}

使用的第二个函数是addErrorData()函数,它接受当前输入和错误消息。它使用 jQuery 的addClass()函数将错误类添加到输入的父级,这将使用 CSS 在输入元素上显示红色边框。然后,它使用 jQuery 的after()函数将一个<div>元素插入到 DOM 中,在当前输入字段下方显示指定的错误消息,如下所示:

function validateRequired(value) {
   if (value == "") return false;
   return true;
}
function addErrorData(element, error) {
   element.parent().addClass("error");
   element.after("<div class='error-data'>" + error + "</div>");
}

还有更多内容...

这个结构使我们能够轻松地为我们的 Web 表单添加附加的验证。因为 JavaScript 正在迭代表单中所有的输入字段,我们可以轻松地检查附加的类,比如datenumbercredit-card,并调用额外的函数来提供替代验证。本章其他的示例将详细讨论附加的验证类型,并将这些函数添加到当前的validation.js文件中。

另请参阅

  • 实施输入字符限制

添加数字验证

当从用户那里收集数据时,有许多情况下您只想允许表单字段中的数字。例如,这可能是电话号码、PIN 码或邮政编码等。本配方将向您展示如何验证前一个配方中创建的表单中的电话号码字段。

准备工作

确保您已经完成了上一个配方,并且有相同的文件可用。在您选择的文本编辑器或 IDE 中打开validation.js

如何做…

通过执行以下步骤将数字验证添加到前一个配方中创建的表单中:

  1. validation.js更新如下,添加valdiateNumber()函数并在for循环内部添加额外的hasClass('number')检查:

    $(function(){
       $('.submit-btn').click(function(event){
          //Prevent form submission
          event.preventDefault();
          var inputs = $('input');
          var isError = false;
          //Remove old errors
          $('.input-frame').removeClass('error');
          $('.error-data').remove();
          for (var i = 0; i < inputs.length; i++) {
             var input = inputs[i];
    
             if ($(input).hasClass('required') && !validateRequired($(input).val())) {
                   addErrorData($(input), "This is a required field");
                   isError = true;
                }
    /* Code for this recipe */
             if ($(input).hasClass('number') && !validateNumber($(input).val())) {
                   addErrorData($(input), "This field can only contain numbers");
                   isError = true;
                }
    /* --- */
    
          }
          if (isError === false) {
             //No errors, submit the form
             $('#webForm').submit();
          }
       });
    });
    
    function validateRequired(value) {
       if (value == "") return false;
       return true;
    }
    
    /* Code for this recipe */
    function validateNumber(value) {
       if (value != "") {
          return !isNaN(parseInt(value, 10)) && isFinite(value);
          //isFinite, in case letter is on the end
       }
       return true;
    }
    /* --- */
    function addErrorData(element, error) {
       element.parent().addClass("error");
       element.after("<div class='error-data'>" + error + "</div>");
    } 
    
  2. 在 Web 浏览器中打开index.html,在电话号码字段中输入除了有效整数以外的内容,然后单击提交按钮。您将看到一个类似以下截图的表单:如何做…

工作原理…

首先,我们在validation.js的主for循环中添加了额外的if语句,以检查当前输入字段是否具有number类,如下所示:

if ($(input).hasClass('number') && !validateNumber($(input).val())) {
   addErrorData($(input), "This field can only contain numbers");
   isError = true;
}

如果是这样,此输入值需要验证为数字。为此,在if语句内联调用validateNumber函数:

function validateNumber(value) {
   if (value != "") {
      return !isNaN(parseInt(value, 10)) && isFinite(value);
      //isFinite, in case letter is on the end
   }
   return true;
}

此函数将当前输入字段的值作为参数。它首先检查值是否为空。如果是,我们就不需要在这里执行任何验证,因为这是由本章第一个配方中的validateRequired()函数处理的。

如果有值需要验证,在return语句上执行一系列操作。首先,该值被解析为整数并传递给isNaN()函数。JavaScript 的isNaN()函数简单地检查提供的值是否为NaNNot a Number)。在 JavaScript 中,如果尝试将一个值解析为整数,并且该值实际上不是整数,则会得到NaN值。return语句的第一部分是确保提供的值是有效的整数。然而,这并不阻止用户输入无效字符。如果用户输入12345ABCDparseInt函数将忽略ABCD,只解析12345,因此验证将通过。为了防止这种情况,我们还使用isFinite函数,如果提供12345ABCD,则返回false

另请参阅

  • 添加信用卡号码验证

添加信用卡号码验证

数字验证可能足以验证信用卡号码;然而,使用正则表达式,可以检查数字组合以匹配 Visa、MasterCard、American Express 等信用卡号码。

准备工作

确保您已经打开并准备修改本章前两个配方中的validation.js

如何做…

使用 jQuery 执行以下逐步说明,为信用卡号提供表单输入验证:

  1. 更新validation.js以添加信用卡验证函数和在输入字段上进行额外的类检查:

    $(function(){
       $('.submit-btn').click(function(event){
          //Prevent form submission
          event.preventDefault();
          var inputs = $('input');
          var isError = false;
          for (var i = 0; i < inputs.length; i++) {
    
    // -- JavaScript from previous two recipes hidden            
    
             if ($(input).hasClass('credit-card') && !validateCreditCard($(input).val())) {
                addErrorData($(input), "Invalid credit card number");
                isError = true;
             }
    
          }
    // -- JavaScript from previous two recipes hidden
       });
    });
    
    // -- JavaScript from previous two recipes hidden
    
    function validateCreditCard(value) {
       if (value != "") {
          return /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/.test(value);
       }
       return true;
    }
    // -- JavaScript from previous two recipes hidden
    } 
    
  2. 打开index.html,输入无效的信用卡号。你将看到表单中呈现以下错误信息:操作步骤…

运作原理…

要添加信用卡验证,与前两个示例一样,在主for循环中添加额外的检查来查找输入元素上的credit-card类,如下所示:

if ($(input).hasClass('credit-card') && !validateCreditCard($(input).val())) {
   addErrorData($(input), "Invalid credit card number");
   isError = true;
}

此处还添加了validateCreditCard函数,该函数使用正则表达式验证输入值,如下所示:

function validateCreditCard(value) {
   if (value != "") {
      return /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/.test(value);
   }
   return true;
}

此函数的第一部分确定提供的值是否为空。如果不为空,函数将执行进一步的验证;否则,它将返回true。大多数信用卡号以前缀开头,这使我们能够在数值验证之上添加额外的验证。此函数中使用的正则表达式将允许 Visa、MasterCard、American Express、Diners Club、Discover 和 JCB 卡。

也可以参考

  • 添加数字验证

添加日期验证

日期是常见的数据项,用户能够轻松地在您的 Web 表单中输入日期非常重要。通常,您会使用包含日期验证的日期选择器来提供简单的输入方法。本示例向您展示如何手动验证英国格式的日期(即DD/MM/YYYY)。日期选择器在第九章中进行了讨论,jQuery UI,使用流行的 jQuery UI 框架。有关更多信息,请参阅本示例的也可以参考部分。

准备工作

继续本章前几个示例的趋势,确保你已经打开并准备修改validation.js,并且已经完成了前三个示例。

操作步骤…

通过以下简单的步骤为您的 Web 表单添加日期验证:

  1. 更新validation.js以添加附加的日期验证函数和在主for循环内进行类检查,如下所示:

    $(function(){
       $('.submit-btn').click(function(event){
    
    // -- JavaScript from previous three recipes hidden
    
          for (var i = 0; i < inputs.length; i++) {
    
    // -- JavaScript from previous three recipes hidden
    
             if ($(input).hasClass('date') && !validateDate($(input).val())) {
                addErrorData($(input), "Invalid date provided");
                isError = true;
             }
    
             // -- JavaScript from previous three recipes hidden
    
          }
          // -- JavaScript from previous three recipes hidden    });
    });
    
    // -- JavaScript from previous three recipes hidden
    
    function validateDate(value) {
       if (value != "") {
          if (/^\d{2}([.\/-])\d{2}\1\d{4}$/.test(value)) {
             // Remove leading zeros
             value = value.replace(/0*(\d*)/gi,"$1");
             var dateValues = value.split(/[\.|\/|-]/);
             // Correct the month value as month index starts at 0 now 1 (e.g. 0 = Jan, 1 = Feb)
             dateValues[1]--;
             var date = new Date(dateValues[2], dateValues[1], dateValues[0]);
             if (
                date.getDate() == dateValues[0] && date.getMonth() == dateValues[1] &&
                date.getFullYear() == dateValues[2]
                ) {
                return true;
             }
          }
          return false;
       } else {
          return true;
       }
    }
    // -- JavaScript from previous three recipes hidden
    
  2. 在 Web 浏览器中打开index.html,输入一个无效的日期,并点击提交以生成无效日期错误,如下图所示:操作步骤…

运作原理…

再次,在主for循环中添加一个额外的类检查,以查看当前输入是否需要应用日期验证。如果需要,将调用validateDate()函数。

就像其他验证函数一样,我们首先检查值是否为空。如果不为空,则可以验证该值。使用正则表达式来确定提供的字符串值是否是有效的日期格式,如下所示:

if (/^\d{2}([.\/-])\d{2}\1\d{4}$/.test(value)) {

如果提供的值以斜杠、连字符或句点分隔,并且前两部分由两个数字组成,最后一部分由四个数字组成,则此测试将通过。这将确保提供的值是DD/MM/YYYY,符合要求。

如果此测试通过,则下一步是删除所有前导零,以便将提供的日期字符串转换为 JavaScript 的日期对象(例如,08-08-1989 将变为 8-8-1989)。相同的代码如下所示:

value = value.replace(/0*(\d*)/gi,"$1");

之后,创建一个数组,将日期字符串分割为-/ 或:

var dateValues = value.split(/[\.|\/|-]/);

现在,可以使用这些日期值来创建 JavaScript 日期对象并测试其有效性。在此之前,我们必须转换月份值。JavaScript 月份从0开始,而我们的用户将从1开始。例如,用户将使用1表示一月,2表示二月,依此类推,而 JavaScript 使用0表示一月,1表示二月,依此类推。为此,我们只需从提供的日期值中减去1,如下所示:

dateValues[1]--;

这样做后,就可以创建 JavaScript 日期对象并检查结果是否与输入日期匹配,从而证明其有效性:

var date = new Date(dateValues[2], dateValues[1], dateValues[0]);
if (
   date.getDate() == dateValues[0] &&
   date.getMonth() == dateValues[1] &&
   date.getFullYear() == dateValues[2]
) {
   return true;
}

另请参阅

  • 在 第九章 的 快速向输入框添加日期选择器界面 配方中,jQuery UI

添加电子邮件地址验证

电子邮件地址验证是网络上最常见的验证类型之一。大多数人会认为有效的电子邮件地址只包含字母数字字符,除了@符号和句点。虽然大多数电子邮件地址通常是这种格式,但实际上有效的电子邮件地址可能包含各种其他字符。本文将向您展示如何将电子邮件验证添加到我们在过去四个配方中使用的 Web 表单中。

如何执行…

通过执行以下说明,创建可以反复使用的电子邮件验证:

  1. validation.jsfor 循环中添加额外的 hasClass 检查和 if 语句,如下所示:

    if ($(input).hasClass('email') && !validateEmail($($(input)).val())) {
       addErrorData($(input), "Invalid email address provided");
       isError = true;
    }
    
  2. validation.js 末尾添加以下 validateEmail() 函数:

    function validateEmail(value) {
       if (value != "") {
          return /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:a-z0-9?\.)+a-z0-9?/i.test(value);
       }
       return true;
    }
    
  3. 在网络浏览器中打开 index.html,输入一个无效的电子邮件地址,并提交表单。您将以与其他类型验证错误相同的方式收到适当的错误提示。

工作原理…

然而简单的电子邮件验证函数包含一个复杂的正则表达式,用于将电子邮件地址验证为 RFC 5322 标准的实用版本,该版本由 www.regular-expressions.info/email.html 提供。

validateEmail() 函数的第一部分检查是否有值可验证。如果有,它将使用复杂的正则表达式测试字符串值的有效性,并相应地返回truefalse

最后,与其他验证函数一样,主for循环中有一个类检查,用于确定哪些输入需要对电子邮件地址进行验证。如果这些输入字段未通过验证,则会在屏幕上提供相应的错误输出。

还有更多…

重要的是要理解,此电子邮件验证方法仅验证语法,以减少用户提供的垃圾数据量。要真正验证电子邮件地址,您必须实际发送电子邮件以验证其是否存在并准备接收电子邮件。

实现实时表单验证

对于用户在网页表单中输入时即时获取验证错误的反馈非常有用。如果您同时执行客户端验证和服务器端验证,那么这可以轻松实现,因为您不需要每次用户在输入时发送请求到服务器,您可以在客户端内完成所有操作。再次强调,相同的数据在服务器端进行额外验证非常重要。然后可以在用户提交表单后将服务器端验证结果反馈给网页表单。

准备工作

本示例将调整作为前五个示例的一部分创建的客户端验证。确保您在此之前已经完成了这些示例。

如何做…

通过执行以下步骤为用户提供实时验证:

  1. 首先,我们需要将for循环中的所有类检查移到它们自己的函数中,以便它们可以被重复使用。将执行requiredemailnumberdatecredit-cardhasClass检查的所有if语句移动到一个名为doValidation()的函数中,如下所示:

    // --- Hidden JavaScript from previous recipes
    
    function doValidation(input) {
       //Remove old errors
       $(input).parent().removeClass('error');
       $(input).next('.error-data').remove();
       if ($(input).hasClass('required') && !validateRequired($(input).val())) {
          addErrorData($(input), "This is a required field");
       }
       if ($(input).hasClass('email') && !validateEmail($($(input)).val())) {
          addErrorData($(input), "Invalid email address provided");
       }
       if ($(input).hasClass('number') && !validateNumber($(input).val())) {
          addErrorData($(input), "This field can only contain numbers");
       }
       if ($(input).hasClass('date') && !validateDate($(input).val())) {
          addErrorData($(input), "Invalid date provided");
       }
       if ($(input).hasClass('credit-card') && !validateCreditCard($(input).val())) {
          addErrorData($(input), "Invalid credit card number");
       }
    }
    
    // --- Hidden JavaScript
    
  2. 现在,我们需要更新主for循环以使用此函数,以便当用户单击提交按钮时仍执行表单验证,如下所示:

    for (var i = 0; i < inputs.length; i++) {
       var input = inputs[i];
       doValidation(input);
    }
    
  3. for循环后更新isError检查,以使用另一种方法来确定是否存在错误,以便仍然可以提交表单,如下所示:

    if ($('.error-data').length == 0) {
       //No errors, submit the form
       $('#webForm').submit();
    }
    
  4. 要对用户正在输入的字段执行验证,我们需要在keyup事件上调用doValidation()函数。将以下代码添加到$(function(){});块中,以将keyup事件处理程序附加到每个表单输入:

    $('input').on("keyup", function(){
       doValidation($(this));
    });
    
  5. 在 Web 浏览器中打开index.html,在电子邮件字段中开始输入,您将在输入时提供适当的错误消息,直到输入有效的电子邮件地址。

工作原理…

将之前的验证代码适应为为用户提供实时验证非常容易。将主验证触发器移动到另一个函数意味着可以重复使用代码而无需重复。包含这些触发器的函数接受一个参数,即它需要执行验证检查的输入。仍然使用for循环提供此输入,如下所示:

for (var i = 0; i < inputs.length; i++) {
   var input = inputs[i];
   doValidation(input);
}

不再依赖doValidation函数返回isError值,我们直接查看 DOM,通过查找带有error-data类的任何元素来查看屏幕上是否显示了任何错误,如下所示:

if ($('.error-data').length == 0) {
   //No errors, submit the form
   $('#webForm').submit();
}

如果没有错误,则如前所述手动提交表单。

为了提供实时验证,使用以下 jQuery 代码为每个表单输入附加一个keyup事件处理程序:

$('input').on("keyup", function(){
   doValidation($(this));
});

on()方法的回调函数将在用户在输入字段内按下并释放键时每次执行。然后可以使用$(this),它引用触发事件的输入,从而为doValidation()函数提供所需的输入对象来执行验证检查。

添加密码强度指示器

用户喜欢创建一个非常简单的密码,如 cat、john 或甚至 password,以便记住。然而,大多数人,特别是 Web 开发人员,知道这些类型的密码太不安全了,并且使用技术如字典攻击非常容易从加密数据库中解密出来。例如,密码强度指示器对于引导用户使用更复杂的密码非常有用。

准备工作

为了能够验证密码强度,我们需要创建一些规则供我们的代码使用。关于最佳密码类型有很多在线信息,但没有硬性规定。我们将为密码打分,根据以下每个规则得分一分:

  • 长度超过六个字符

  • 长度超过八个字符

  • 同时包含大写和小写字符

  • 至少包含一个数字

  • 它包含以下符号之一:@$!&^

此处的配方将在过去六个配方中创建的 Web 表单中添加密码强度指示器。在开始此步骤之前,请确保您已经获取了这些配方中的代码。

如何做…

为 Web 表单创建一个有效的密码强度指示器,需执行以下每个步骤:

  1. 更新index.html,为密码表单元素添加一些额外的类,并添加一些额外的 HTML,这将创建密码强度指示器,如下所示:

    // --- ADDITIONAL HTML HIDDEN
    <div class="input-frame">
    <label for="password">Password:</label>
    <input name="password" id="password" type="password" class="required password" />
    <div class="password-strength">
       <div class="inner"></div>
       <div class="text"></div>
    </div>
    </div>
    <div class="input-frame">
    <label for="confirmPassword">Confirm Password:</label>
    <input name="confirmPassword" id="confirmPassword" type="password" class="confirm-password" />
    </div>
    // --- ADDITIONAL HTML HIDDEN
    
  2. 将以下样式添加到styles.css的末尾,以将强度指示器定位在密码字段下方。这些样式还将允许强度指示器作为显示密码强度百分比的加载条。

    .password-strength {
       position: absolute;
       width: 150px;
       height: 20px;
       left: 69%;
       top: 35px;
       line-height: 20px;
       border: solid 1px #191919;
    }
    .password-strength .inner {
       position: absolute;
       left: 0;
       top: 0;
    }
    .password-strength .text {
       font-size: 11px;
       color: #FFF;
       text-align: center;
       position: relative;
       z-index: 10;
    }
    
  3. validatePasswords()函数添加到validation.js的末尾,用于确保输入了两个密码并确保它们匹配,如下所示:

    // --- HIDDEN JAVASCRIPT
    function validatePasswords(value) {
       var password = $('.password').val();
       if (value == "") {
          return "Both passwords are required";
       } else if (value != password) {
          return "Passwords do not match";
       }
       return true;
    }
    
  4. 将以下代码添加到doValidation()函数的末尾,以在confirm-password输入上运行validatePasswords()函数:

    function doValidation(input) {
    // --- HIDDEN JAVASCRIPT
    if ($(input).hasClass('confirm-password')) {
       var result = validatePasswords($(input).val());
          if (result != true) {
             addErrorData($(input), result);
          }
       }
    }
    
  5. validation.js 中的 $(function(){}); 块内添加以下 keyup 事件处理程序,以在用户在第一个密码字段中输入时评分密码强度:

    $('.password').on("keyup", function(){
       var score = 0;
       var password = $('.password');
       var passwordAgain = $('.confirm-password');
       //Remove any old errors for the password fields
       password.parent().removeClass('error');
       password.next('.error-data').remove();
       passwordAgain.parent().removeClass('error');
       passwordAgain.next('.error-data').remove();
       //Password is greater than 6 characters
       if (password.val().length > 6) {
          score++;
       }
       //Password is greater than 8 characters
       if (password.val().length > 8) {
          score++;
       }
       //Password has both uppercase and lowercase characters
       if (/(?=.*[A-Z])(?=.*[a-z])/.test(password.val())) {
          score++;
       }
       //Password has at least one number
       if (/(?=.*[0-9])/.test(password.val())) {
          score++;
       }
       //Password has at least one symbol (@$!&^) character
       if (/@|\$|\!|&|\^/.test(password.val())) {
          score++;
       }
       var fill = (100 - ((score * 2) * 10));
       var percent = (100 - fill);
       var level,
       colour;
       switch (score) {
       case 0:
       case 1:
       level = "Weak";
       colour = "green";
       break;
       case 2:
       case 3:
       level = "Medium";
       colour = "orange";
       break;
       case 4:
       level = "Strong";
       colour = "red";
       break;
       case 5:
       level = "Excellent";
       colour = "purple";
       break;
       }
       $('.password-strength .inner').css('right', fill + "%").css('background-color', colour);
       $('.password-strength .text').html(level + " (" + percent + "%)");
       });
    
  6. 在 Web 浏览器中打开 index.html,您会看到在第一个密码字段下方出现了一个额外的黑色框。开始输入密码,这个字段会在您输入时提供有关密码强度的信息。如下截图所示:

工作原理...

指示器本身的 HTML 具有 inner 元素和 text 元素。text 元素由 jQuery 用于显示基于输入密码的计算得分的密码强度和百分比。inner 元素用于形成彩色条。根据计算得分,jQuery 用于更改 inner 元素的颜色和定位,从而创建加载条效果,如前述截图所示。

使用的 CSS 需要很少的解释,因为它提供了基本的样式和定位。inner 元素具有绝对位置,以便在不同百分比下填充 password-strength 元素。text 分区具有设置了 z-index 参数,以确保文本始终显示在 inner 元素之上。

validatePasswords 函数是作为本篇配方的一部分创建的,它简单地为我们的应用程序添加了基本的密码验证。它检查确认密码字段是否已填写,并且该值是否与第一个密码字段匹配。在 doValdiation 函数中添加了额外的检查,以确保此验证与早期配方中创建的其他验证方法一起应用。

为了在用户在密码字段中输入时更新密码强度指示器,使用与 实施实时表单验证 配方中使用的相同方法,即使用 keyup 事件。使用 jQuery on() 函数将事件处理程序附加到 password 字段,如下所示:

$('.password').on("keyup", function(){
});

用于计算得分并更新 password-strength HTML 元素的代码随后放置在此事件处理程序的回调函数中。此代码的第一部分是删除密码字段当前显示的任何错误。

之后,有一系列的 if 语句,用于根据在本篇配方开始时定义的规则验证密码。首先是密码长度的基本验证,如下所示:

//Password is greater than 6 characters
if (password.val().length > 6) {
   score++;
}
//Password is greater than 8 characters
if (password.val().length > 8) {
   score++;
}

每次满足验证条件时,使用 score++ 将 score 变量递增 1

更复杂的规则使用正则表达式来确定密码值是否符合额外得分点的要求,如下所示:

//Password has both uppercase and lowercase characters
if (/(?=.*[A-Z])(?=.*[a-z])/.test(password.val())) {
   score++;
}
//Password has at least one number
if (/(?=.*[0-9])/.test(password.val())) {
   score++;
}
//Password has at least one symbol (@$!&^) character
if (/@|\$|\!|&|\^/.test(password.val())) {
   score++;
}

在考虑了五条规则后,最终分数用于计算填充值。填充值是需要从强度指示器右侧填充的inner元素的百分比。这允许我们创建加载条效果。除了填充值,还计算出一个普通百分比,以与强度级别文字一起显示,如下所示:

var fill = (100 - ((score * 2) * 10));
var percent = (100 - fill);

之后,分数值再次被用来确定inner元素的背景颜色和强度级别文字,如下所示:

var level,
colour;
switch (score) {
case 0:
case 1:
   level = "Weak";
   colour = "green";
break;
case 2:
case 3:
   level = "Medium";
   colour = "orange";
   break;
case 4:
   level = "Strong";
   colour = "red";
break;
case 5:
   level = "Excellent";
   colour = "purple";
break;
}

最后,使用 jQuery password-strength,HTML 代码更新为获取的信息,以向用户显示结果,如下所示:

$('.password-strength .inner').css('right', fill + "%").css('background-color', colour);
$('.password-strength .text').html(level + " (" + percent + "%)");

还有更多…

这段代码应该很容易调整,这样你就可以添加自己关于密码强度的规则。在网上有很多讨论和资源可以告诉你一个强密码应该是什么样子的。

另请参阅

  • 实现实时表单验证

添加反垃圾邮件措施

大多数网页开发者都会知道,如果你的网站上有联系表单或任何类型的网页表单公开可用,就会有网页机器人提交和大量垃圾邮件。在过去的七个配方中,我们一直在创建仅使用 JavaScript 的网页表单来阻挡大多数网页机器人,但随着浏览器自动化和网页机器人变得更加聪明,向你的网页表单添加反垃圾邮件措施仍然很重要。

准备工作

确保你已经完成了最后七个配方,并且代码随时可用。记住,如果你只想使用代码而不完全理解它是如何工作的,跳到本章末尾的*它是如何工作的...*部分,获取所有内容。

如何去做…

通过执行以下每个步骤,向你的网页表单添加简单的反垃圾邮件措施:

  1. 更新index.html,在标记为确认密码的输入下添加一个额外的表单输入,如下所示:

    <!-- HIDDEN HTML CODE -->
    <div class="input-frame">
       <label>Confirm Password:</label>
       <input type="password" class="confirm-password" />
    </div>
    <div class="input-frame">
       <label>Enter the number <span class="anti-spam-number"></span>:</label>
       <input type="text" class="required anti-spam-input" />
    </div>
    <!-- HIDDEN HTML CODE -->
    
  2. 使用 JavaScript,在validation.js顶部使用以下代码生成一个介于1100之间的随机数:

    var spamNumber = Math.floor(Math.random() * (100 - 1 + 1)) + 1;
    $(function(){
    // --- HIDDEN JAVASCRIPT CODE
    
  3. $(function(){}); jQuery 区块的最后,添加以下代码,以更新 HTML 的anti-spam-number span 元素为随机数字:

    // --- HIDDEN JAVASCRIPT CODE
    $('.anti-spam-number').html(spamNumber);
    });
    
  4. doValidation()函数的末尾添加以下附加验证检查:

    if ($(input).hasClass('anti-spam-input') && !validateAntiSpam($(input).val())) {
       addErrorData($(input), "Incorrect Anti-Spam answer");
    }
    
  5. 最后,在validation.js的末尾,添加validateAntiSpam()函数,之前的代码调用该函数:

    // --- HIDDEN JAVASCRIPT CODE
    function validateAntiSpam(value) {
       if (value != "") {
          if (parseInt(value)!= spamNumber) return false;
       }
       return true;
    }
    
  6. 在 web 浏览器中打开index.html,你会看到额外的反垃圾邮件表单输入字段。每次刷新页面,它会要求你输入不同的数字。

它是如何工作的…

通过将spamNumber全局变量声明在任何函数之外,它可供整个 JavaScript 文件使用。在每次页面加载时,生成一个介于1100之间的新数字,这样网页机器人就不能存储答案并提交表单。在 HTML 代码中,有一个具有类anti-spam-numberspan元素,使用以下代码在页面加载时更新为随机数字:

$('.anti-spam-number').html(spamNumber);

这将确保用户被告知输入正确的数字。我们创建了一个额外的验证函数,名为validateAntiSpam,并从doValidation()函数中调用所有具有anti-spam-input类的输入。然后,这将使用全局可用的spamNumber变量验证用户输入的数字,如下所示:

function validateAntiSpam(value) {
   if (value != "") {
      if (parseInt(value)!= spamNumber) return false;
   }
   return true;
}

请注意,将输入解析为整数以确保数字之间的比较。如果值不匹配,这个函数将返回false,以便doValidation()函数可以为用户在屏幕上创建适当的错误消息。

还有更多…

这种客户端垃圾邮件验证不能完全信赖。它对一般网页机器人有效,但不能对直接针对你的网站的机器人起作用。如果有人想要为你的网站编写一个特定的机器人脚本,那么绕过这个 JavaScript 并不是一个困难的过程。如果你觉得这是可能的,那么必须使用更极端的服务器端垃圾邮件预防方法。

在互联网上有许多有效的防垃圾邮件方法可以免费获得。最流行的是 CAPTCHA。最流行的 CAPTCHA 之一是谷歌在www.google.com/recaptcha上免费提供的。

另请参阅

  • 添加密码强度指示器

实现输入字符限制

到目前为止,本章中的所有示例都集中在输入验证和向用户提供适当反馈的方面。有些情况下,最好是阻止用户根本不输入无效的字符。通常不会使用这种方法,因为对于一些用户来说这可能会很令人困惑;例如,如果他们不被告知为什么不能输入*%。这种方法适用的情况是登录表单。如果你知道你的注册系统不允许用户名中含有,你就知道用户输入%*是错误的,因此阻止输入是可以接受的。这个示例提供了一种方法,可以防止用户在输入字段中输入非字母数字字符。

准备工作

这个示例不使用前八个示例中的代码;不过,CSS 代码中有相似之处。完成这个示例,你将需要三个文件。在存储最新版本的 jQuery 的同一目录中创建recipe-9.htmlrecipe-9.jsrecipe-9.css

如何做…

使用 jQuery 来防止用户通过以下步骤在文本输入中输入无效的章节:

  1. 将以下 HTML 代码添加到recipe-9.html中。这将创建一个基本的登录表单,并包括另外两个文件以及 jQuery 库:

    <!DOCTYPE html>
    <html >
    <head>
       <title>Chapter 5 :: Recipe 7</title>
       <link type="text/css" media="screen" rel="stylesheet" href="recipe-9.css" />
       <script src="img/jquery.min.js"></script>
       <script src="img/recipe-9.js"></script>
    </head>
    <body>
    <form id="webForm" method="POST">
       <div class="header">
          <h1>Register</h1>
       </div>
       <div class="input-frame">
          <label for="username">Username:</label>
          <input name="username" id="username" type="text" class="username" />
       </div>
       <div class="input-frame">
          <label for="password">Password:</label>
          <input name="password" id="password" type="text" class="required" />
       </div>
       <div class="actions">
          <button class="submit-btn">Submit</button>
       </div>
    </form>
    </body>
    </html>
    
  2. 将以下 CSS 代码添加到recipe-9.css中,为登录表单添加样式:

    @import url(http://fonts.googleapis.com/css?family=Ubuntu);
    body {
       background-color: #FFF;
       font-family: 'Ubuntu', sans-serif;
    }
    form {
       width: 500px;
       margin: 10px auto auto auto;
       padding: 20px;
       background-color: #333;
       border-radius: 5px;
       color: #747474;
       border: solid 2px #000;
    }
    form label {
       font-size: 14px;
       line-height: 30px;
       padding-bottom: 8px;
       width: 140px;
       display: inline-block;
       text-align: right;
    }
    .input-frame {
       clear: both;
       margin-bottom: 25px;
       position: relative;
    }
    form input {
       height: 30px;
       width: 330px;
       margin-left: 10px;
       background-color: #191919;
       border: solid 1px #404040;
       padding-left: 10px;
       color: #DB7400;
    }
    form input:hover {
       background-color: #262626;
    }
    form input:focus {
       border-color: #DB7400;
    }
    form .header {
       margin: -20px -20px 25px -20px;
       padding: 10px 10px 10px 20px;
       position: relative;
       background-color: #DB7400;
       border-top-left-radius: 4px;
       border-top-right-radius: 4px;
    }
    form .header h1 {
       line-height: 50px;
       margin: 0;
       padding: 0;
       color: #FFF;
       font-weight: normal;
    }
    .actions {
       text-align: right;
    }
    .submit-btn {
       background-color: #DB7400;
       border: solid 1px #000;
       border-radius: 5px;
       color: #FFF;
       padding: 10px 20px 10px 20px;
       text-decoration: none;
       cursor: pointer;
    }
    
  3. 将以下 JavaScript 代码添加到recipe-9.js中,以监视username字段上的用户输入,并确保不输入非字母数字字符:

    $(function(){
        $('.username').on("keypress", function(event){
            //Get key press character code
            var key = String.fromCharCode(event.which);
            if (/[^a-zA-Z\d\s:]/.test(key)) {
                event.preventDefault();
                return false;
            }
        });
    });
    
  4. 在 Web 浏览器中打开 recipe-9.html 并尝试在 username 字段中输入非字母数字字符(例如,$)。你会发现它不会被放置在字段中。

工作原理…

页面加载时将键按下事件处理程序附加到 username 字段。此事件处理程序的回调函数有一个参数,即 event 对象。此 event 对象提供对用户按下的键的键码的访问。当 username 字段具有焦点并且用户按下键时,将执行回调函数。

首先,String.fromCharCode(event.which); 用于获取按下键的字符串值;例如,DH4。然后使用正则表达式来确定该字符是否是字母数字字符。如果不是,则使用以下代码阻止该字符输入到表单字段中:

if (/[^a-zA-Z\d\s:]/.test(key)) {
   event.preventDefault();
   return false;
}

更多内容…

确保此示例中使用的事件是 keypress 事件。如果使用了替代事件,如 keydown,可能无法达到预期的结果。如果使用 keydown 事件,当用户按下 Shift + 4 来输入 $ 符号时,keydown 事件将以 4 而不是 $ 提供其事件处理程序,因此未通过验证。