领先

探索丰富客户端脚本与 jQuery,部件 2

Dino Esposito

内容

jQuery 事件模型
绑定事件处理程序
以编程方式触发事件
特殊的相关事件的方法
事件的帮助
可视化效果
自定义动画
AJAX 功能
客户端缓存
设置汇总

功能强大的 Web 应用程序需要强大的客户端功能。Web 开发人员具有传统指望 JavaScript,以便提供该功能。但是,原始的 JavaScript 具有通过库和对象的方向可解决其中一些的其限制。

没有可用的许多 JavaScript 库,但不久它们所有具有相同外观。如果您不能决定要开始,我建议右此处启动与 jQuery。如我讨论了上个月,jQuery 具有包括选择器、 筛选器、 换行的集和关键功能某些方便功能链接功能。(请参阅"探索丰富客户端脚本与 jQuery,第 1 部分.") 本月,我将介绍在其他一些人,包括事件模型、 视觉效果、 缓存,和 AJAX 功能。

jQuery 事件模型

更经常个,浏览器没有自己的事件的表示形式。与 Firefox 和 Safari,Internet Explorer 具有自己的事件模型。因此,事件实现跨浏览器兼容性是库的不容易的任务不好的帮助。随后,几乎所有 JavaScript 库必须都提供一个抽象模型处理事件。jQuery 库也不例外。

处理 API jQuery 事件分为两个组的功能。有一些一般事件方法,添加和删除处理程序,以及帮助器函数长列表。一般的方法提供的帮助者工作 ; 基础,并帮助进行编程的 jQuery,种便捷而且有效。

图 1列出了可以用绑定,并取消绑定事件处理程序匹配元素换行集的方法。

事件的图 1 的常规 jQuery 方法
方法 说明
绑定 关联给定的函数的每个元素包含在换行集中的一个或多个事件。
Live 将绑定引入 jQuery 1.3 函数到指定的事件处理程序换行集的所有当前和将来的元素。这意味着如果新的 DOM 元素被添加的符合换行集的条件,元素将自动绑定该处理程序。骰子方法执行反向,并从一换行组中删除一个 Live 的事件处理程序。
一个 Works 喜欢绑定,在于已一次运行后,任何事件处理程序将自动删除。
触发器 触发换行集中的每个元素指定的事件。
triggerHandler 触发换行的集合中的一个元素上给定的事件,并取消默认浏览器操作。
取消绑定 移除绑定换行的集合中的每个元素中的事件。

顺便,值得注意在 jQuery vernacular 方法用来处理换行集的内容的代码。函数,另一方面,是集的执行不专门旨在处理换行的内容的操作的代码。

绑定事件处理程序

Bind 方法将给定的事件处理程序附加到换行的集合中的所有元素中。Bind 方法的完整签名是:

bind(eventName, eventData, eventHandler)

第一个参数是字符串,表示该事件处理。第二个参数表示任何输入的数据,来自与该事件。最后,第三个参数是 JavaScript 函数绑定。

因为 jQuery 提供了一个抽象的事件模型,很重要查看受支持的事件列表。图 2 正在完整列表。

图 2 支持 Events in jQuery
事件 触发时
beforeunload 浏览器窗口被卸载或由用户关闭。
模糊 元素失去焦点,因为用户单击外部的或离开选项卡。
更改 元素失去焦点并由于其获得焦点进行其值有了修改。
单击 用户单击元素上。
dblclick 在用户双击元素上。
错误 Window 对象表示发生错误,通常一个 JavaScript 已检测到错误。
焦点 在元素收到焦点通过鼠标或选项卡的导航。
Keydown 按下某个键。
Keypress 按下并释放某个键。一个 Keypress 定义为连续 Keydown 和 Keyup 事件。
Keyup 释放键。此事件遵循 Keypress。
加载 元素和所有其内容已完成加载。
mousedown 按下了鼠标按钮。
mouseenter 鼠标进入元素的区域中。
mouseleave 鼠标离开的元素的区域。
mousemove 元素上时,移动鼠标。
Mouseout 鼠标移出的元素。与 mouseleave,不同此也会事件当鼠标移入或移出子元素。
Mouseover 鼠标移动到元素。与 mouseenter,不同此事件时,也会鼠标移动到或缩小子元素。
mouseup 发布鼠标按钮。此事件遵循单击。
调整大小 元素会调整大小。
滚动 滚动元素。
选择 用户在文本字段中选择一些文本。
提交 提交表单。
卸载 浏览器窗口是卸载。

因为的浏览器差异和库提供的抽象级别,列表是太明显比第一个快速可能看起来。是例如更改,并选中事件地址非常不同方案。更改事件引用包括文本框和下拉列表的 input 元素的值发生更改。选择的事件只是指在输入或 textarea 元素中的文本选择。

Mouseout / mouseleave 对事件 Mouseover / mouseenter 和之间也存在细微的差异。它们有说明几乎相同,并且不同只是因为 Mouseover 和 Mouseout 也触发当用户移动进出子元素时。对于没有子元素,这些事件是等效的。

有可能要注册相同的 JavaScript 处理程序的多个事件。可以用空格分隔事件名称的方法执行的。下面的示例在鼠标进入或离开 DIV 标记与给定的样式时切换 CSS 样式:

$("div.sensitiveArea").bind("mouseenter mouseleave", 
   function(e) {
        $(this).toggleClass("hovered");
    }
);

绑定方法的第二个参数是可选的如果指定,表示要传递给该处理程序的任何用户定义数据。 图 3 说明了如何则可以切换使用而不是泛型的 JavaScript 处理程序的一个文本框的 CSS 样式。

图 3 切换文本框样式

<script type="text/javascript">
  $(document).ready( 
     function() {
       $("#TextBox1").bind("focus", 
                           {cssStyle: "focusedTextBox"}, 
                           setCSS);
       $("#TextBox1").bind("blur", 
                           {cssStyle: "focusedTextBox"}, 
                           setCSS);
     }
  );

  function setCSS(e)
  {
     var name = "#" + e.target.name;
     $(name).toggleClass(e.data.cssStyle);
  }
</script>

请注意上面的代码是绑定函数的仅仅是说明,并可能无法正常工作作为一种方式切换样式。最好使用该: 集中 pseudo-class 元素具有焦点时,将特殊的样式将添加到的元素。最新的浏览器将支持它。JavaScript 处理程序是声明和接收的事件数据结构的函数。此对象具有 图 4 中列出的成员。

图 4 成员 jQuery 事件对象
成员 说明
类型 返回事件,如"单击"的名称
目标 返回对 DOM 元素发出事件的引用
pageX 返回 X 鼠标坐标,相对于文档
page 返回 Y 鼠标坐标,相对于文档
preventDefault 取消在浏览器将执行在事件之后该默认操作
stopPropagation 停止在冒泡,但不能防止浏览器的操作

值得注意是在于目标属性返回一个 DOM 的引用对象不在 jQuery 包装组。要确定该元素的 ID,必须调用其 ID 或名称的属性。该处理程序检索通过其数据的 expando 属性传递任何自定义数据。

两种方法完成事件数据对象的定义。preventDefault 方法停止浏览器从采取默认操作将通常需要在事件之后。例如,如果您在提交处理程序中调用 preventDefault 将会不出现任何表单提交。preventDefault 方法不会停止,冒泡通过在对象的堆栈,事件的但是。

相反,stopPropagation 方法停止事件冒泡,但不会阻止该操作。如果您想要停止事件传播,并防止默认操作,则执行不调用这些方法之一 ; 只是从事件处理程序中返回 False。

可以使用拆散方法能分离通过绑定方法附加任何处理程序。该方法有两个可选的参数,事件和该处理程序的名称。如果却没有指定所有处理程序将删除从换行的集合中的所有元素中。

以编程方式触发事件

方法触发器 (请参见 图 1 ) 指示 jQuery 调用指定的事件所注册的任何处理。要模拟用户单击指定按钮上,使用此:

$("#Button1").trigger("click");

该代码不会执行任何操作如果没有 JavaScript 处理程序注册元素的 Click 事件。

方法 triggerHandler 与触发器以两种方式。 首先,方法 triggerHandler 还阻止在浏览器的默认操作。 第二个,该方法会影响只有一个元素有一个元素不整个换行集。 如果换行的集合包含多个匹配元素,仅第一个需要触发指定的事件处理程序。

如果您在接下来会看到来以编程方式触发焦点事件的输入的字段上使用 triggerHandler 方法,任何已注册处理程序执行,但将输入的焦点移动到该字段的默认操作不会发生。

 $("#TextBox1").triggerHandler("focus");

图 5 显示了什么外观类似于。

esposito.cuttingedge.gif

图 5 以编程方式触发焦点事件

特殊的相关事件的方法

jQuery 库提供三种常用的事件方法: 准备、 悬停、 切换。 该准备好的方法采用一个函数,并 DOM 为可以遍历和操作代码时,请运行它:

$(document).ready(
  function() {
...
  }
);

库需要此功能的替换浏览器的 Window 对象的 onload 事件。onload 事件发生太晚,当所有图像已同时都加载。页和库已被完全初始化时,另一方面,会准备好的事件中。

在悬停函数中您将的代码放要执行当用户输入,并将一组页元素。悬停函数接受两个处理程序。鼠标悬停换行的设置中和第二个域中的元素,当鼠标离开该元素的区域时,将运行第一个。

最后,切换函数将执行一个甚至更智能的任务。它采用两个或多个处理程序,并为用户单击可以选择运行。换句话说,匹配的元素中的第一个单击运行在第一个处理程序,第二次单击运行第二个处理程序和等等。当到达时处理程序列表的底部时,所有后续单击重新从运行列表中第一个函数。

事件的帮助

若要强化的极端的可用性的理念,jQuery 库附带的帮助器方法来简化常见事件处理程序的绑定列表。helpers 有两种形式: 带和不带函数参数。

接受一个参数的 helpers 收到一个 JavaScript 函数在触发该事件时执行。如果不指定任何参数,该方法将只触发换行的集合中的任何元素上给定的事件。图 6 显示支持 helpers 的列表,并且区分活页夹方法和触发器的方法。

图 6 联编程序,并触发事件的帮助
Trigger 方法 (触发上述的事件换行集上)。 活页夹方法将绑定 (到指定的函数匹配元素的相关事件)。
模糊 blur(Fn)
更改 change(Fn)
单击 Click(Fn)
dblclick dblclick(Fn)
错误 error(Fn)
焦点 focus(Fn)
Keydown Keydown(Fn)
Keypress Keypress(Fn)
Keyup Keyup(Fn)
  load(Fn)
  mousedown(Fn)
  mousemove(Fn)
  mouseout(Fn)
  Mouseover(Fn)
  mouseup(Fn)
  resize(Fn)
  scroll(Fn)
选择 Select(Fn)
提交 submit(Fn)
  unload(Fn)

下面的代码注册为给定的按钮的 Click 事件。绑定事件和处理程序之间发生如后该文档已完全加载且可以以编程方式操作。

$(document).ready( function() {
   $("#btnProcess").click(
       function(e) {
this.text("Please wait ... ");
       }
   );
});

某些事件 (例如,滚动、 调整和鼠标事件意义仅当触发的显式的用户操作。这样的事件缺少一个 Trigger 方法,如 图 6 所示。

可视化效果

最负责 jQuery 库的普及因素之一是,内置引擎的视觉效果。在库,您会发现用于构建自定义动画以及几个功能迅速实现常用效果 (如淡入淡出和滑动的有效引擎。

预定义的效果可分为三个组它们作用于 CSS 属性: 可见性,滑动,和淡化。图 7 列出本地可用的所有效果。

图 7 视觉效果
可见性效果 说明
显示 打开换行的集合中的任何元素的可见性
隐藏 关闭换行的集合中的任何元素的可见性
切换 切换换行的集合中的任何元素的可见性
滑动效果 说明
slideDown 显示通过逐步增加其高度的任何匹配的元素
slideUp 隐藏任何匹配的元素逐渐减小其高度
slideToggle 显示或隐藏所有的匹配元素反转当前滑动设置
淡入淡出效果 说明
fadeIn 通过逐渐减少其不透明度淡入的任何匹配的元素
FadeOut 通过逐步增加其不透明度淡出的任何匹配的元素
fadeTo 淡所有匹配元素指定的不透明度的不透明度

图 7 中的所有方法都用于在换行集中的任何匹配元素。可见性的方法操作该显示 CSS 属性显示和隐藏元素使用一个很好的内置动画。是例如下面的代码在用户单击按钮 unveils 的 HTML 面板:

$("btnShowOrders").click(
   function(e) {
      $("#panelOrders").show(2000);
   }
);

动画需要完成的两秒钟。 您可以指定可见性的方法的可选参数包括动画和回调完成时调用的速度。 动画的类型是硬编码,并且逐渐发现内容从左上角。

滑动方法处理匹配的元素的 CSS height 属性。 slideDown 方法增加在循环中元素的高度,以便显示发生的逐渐显示该元素。 slideUp 方法执行反向,并通过从实际的高度为零滑动它最中, 隐藏元素中。

淡入淡出方法采用类似于滑动方法的一个模型。 它们支持可选的速度和完成回调和循环 CSS Opacity 属性上的显示/隐藏元素 (请参见 图 8 )。

图 8 淡入淡出

$("#btnShowOrders").click(
   function(e) 
   {
      // Hide the current panel.
      $("#panelOrders").fadeOut(1000);

      populateOrderPanel();

      // Show new content and when done 
      //apply some CSS styles
      // to denote the new content.
      $("#panelOrders").fadeIn(2000, 
         function() {
            $("#panelOrders").css(...);
         }
      );
   }
);

前面的示例演示如何淡出一个现有的 HTML 面板中,刷新它隐藏状态时,然后再次使用 fade-in 动画地显示。 请注意您可以指示所需的速度用毫秒的显式的持续时间或求助于代表三个预定义的速度的一个字符串: 慢速、 正常,或快速。

自定义动画

图 6 中列出的所有视觉效果实现 jQuery 动画引擎的顶部。 该引擎的核心是动画的函数:

function animate( prop, speed, easing, callback ) 
{ 
  …
}

函数在第一个参数是属性 / 值对的数组将属性的引用一个 CSS 属性。 此函数只是动画显示其当前值为指定的值每个匹配元素在 CSS 属性。

您可以指定的附加的可选参数包括动画和完成回调的速度。 easing 参数指示要在转换期间使用 easing 效果的名称。 有两个内置的值: 线性和 swing。 使用一个插件,可添加其他 easing 选项。

以下是示例调用动画的方法:

$("#Element1").animate(
   { width: "70%",
     opacity: 0.4,
     borderWidth: "10px"
   }, 
   3000);

动画末尾匹配的元素将具有所指定的宽度、 不透明度和边框宽度。 该动画将在三秒内完成并改变 CSS 属性从其当前值,向上或向下到目标值。

请注意必须使用 camelCase 指定 CSS 属性,即第一个字符是小写并每个以下的单词的第一个字符是大写。 例如,动画元素的边框您应使用"borderWidth"而不是 CSS 原始属性名称的边框宽度。

该动画的方法还支持如增加的相对动画 (或减少) 属性值按百分比或一个固定值。 是例如,下面的代码段显示如何 20%的增加的元素的宽度和值的 0.4 加深其内容。 我也已经指定应该在两秒应用所有更改。

$("#Panel1").animate(
   { width: "+=20%",
     opacity: "-=0.4"
   }, 
   2000);

最后,注意 jQuery 中的所有动画自动排在一个接一个下的顺序执行。 排队的动画是能够链接在换行集中的元素上的多次调用所需的前提条件。 排队的动画但是,是只是默认行为。 作为一的名开发人员系统会提供该工具,可使并行运行某些动画。

若要能够某些并行性,您创建使用动画的方法的重载的动画队列:

function animate( prop, options )
{
   …
}

为在以前的签名在第一个参数将指示一的组要动画显示的样式属性和要到达该值。

第二个参数指示要配置该动画的选项的一个集。 选项包括持续时间、 减少、 完成回调和一个 Boolean 类型的值,指示是否已排队的动画 True 为默认值。

通过将队列属性设置为 False 动画调用的选项中,您运行立即没有队列动画。 让我们考虑下面的代码段:

$("#div1").animate({ width: "90%" }, {queue:false, duration:5000 });
$("#div1").animate({ fontSize: '10em' }, 1000);
$("#div1").animate({ borderWidth: 5 }, 1000);

第一个动画不排队,,立即运行。 无法排队第二个但以便同时运行,它被视为在队列中的第一个。 在实际效果是前两个动画一起启动的。 第三个动画在排队,并开始为第二个动画终止 1 秒。 由于第一个动画采用五秒钟,边框动画也运行和更改元素的宽度的动画。

AJAX 功能

将一个流行的 JavaScript 库是什么不可靠的基础结构 AJAX 异步调用的? 在 jQuery,AJAX 支持基于通过它可以控制 Web 请求的所有方面,ajax 函数。 下面是调用 ajax 函数的一个常见种方法:

$.ajax(
 {
   type: "POST",
   url: "getOrder.aspx",
   data: "id=1234&year=2007",
   success: function(response) {
     alert( response );
   }
 }
);

该函数接受一个对象中的分组的参数列表。 可行的选项是类型、 URL、 数据、 数据类型、 缓存、 异步、 用户名、 密码、 超时和 ifModified。

数据类型参数在指示在预期的响应的类型而采用的特别,缓存参数 (如果设置为 False) 强制请求资源不以浏览器缓存。 其他参数,如类型、 密码、 用户名和 URL 是容易理解的。

ajax 函数的选项也包括可选的回调调用任何基础的 XMLHttpRequest 对象的生命周期中最相关的步骤前的许多。 成功回调指示完成回调。 回调函数作为其唯一参数接收响应。 其他回调被错误,beforeSend,并完成。 在调用成功或错误的回调时完成的回调运行在请求结束。

有趣的是,ajax 函数列出了回调预处理 Web 响应,它返回到调用代码之前。 此回调是 dataFilter,并处理原始响应通过 XMLHttpRequest 下载。 回调旨在筛选响应,以便仅符合预期数据类型净化的数据返回到调用方。 回调函数接收两个参数: 从服务器和分配给该数据类型参数的值返回的原始数据。

如果使用 jQuery 库,您几乎不使用 ajax 函数直接。 您将更频繁地最终使用某些 AJAX 帮助程序,如 getScript、 负载或 getJSON。

下面的代码演示如何加载根据的脚本文件。 该脚本将在加载时自动执行:

$.getScript("sample.js");

另一个非常有用段代码是加载函数。 加载函数下载 HTML 标记,并自动将它会在当前 DOM。 下面的代码说明如何以编程方式填充菜单:

$("#menu").load("menu.aspx");

URL 的内容连接到 DOM 子树匹配选择器的任何元素中的根级。 Load 方法将默认为一个 GET 请求但可以更改它以 POST 通过只添加一个数据参数如下所示:

$("#links").load(
   "menu.aspx", 
   { topElement: "Books" },
   function() 
   {
       // completion callback code
   }
);

如上所示回调也可以指定完成下载后执行。

也可能是在 URL 中指定 jQuery 选择器,,以便传入的标记是 pre-filtered 选择唯一的匹配元素。 语法只需要将一个选择器表达式添加到 URL。 以下是从名为 menuItems <ul> 元素中提取所有 <li> 元素的一个示例:

$("#links").load("/menu.aspx ul#menuItems li");

最后,您必须获得,张贴内容,和 getJSON 函数直接执行 GET 和 POST 和获得 JSON 内容从 URL。

客户端缓存

客户端缓存至关重要重要的 JavaScript 代码中。 在此上下文中,缓存是一个数组,开发人员可以存储与特定 DOM 元素的数据。 在下面的代码 URL 调用确定是否一个文本框的内容无效并且然后响应缓存在名为 IsValid 数组元素中。

var url = "...";
var contentIsValid = $.get(url);
$("#TextBox1").data("IsValid", contentIsValid);

每个 DOM 元素可能有其自己本地的缓存。 在 jQuery,请换行集中元素中使用数据方法。

若要读取返回存储的内容,您使用相同的数据函数,只有一个参数,该元素的名称:

alert($("#grid").data("Markup"));

可以使用 removeData 函数删除添加到缓存中的元素。

那是好了解为什么最好使用数据函数比 expando 属性。 expando 属性使用非标准的 HTML 属性的 DOM 元素中添加自定义的信息。 确实是一种客户端缓存,但是某些浏览器可能不希望自定义属性。 在这种情况下您通常求助于以一个非标准的方式使用标准的属性,例如 alt 或关系。 如数据函数的客户端缓存框架在普通旧的 JavaScript 对象中存储数据,并维护一个指向目标 DOM 元素使用一个词典。 完成这种方式,有可能与浏览器没有冲突。

设置汇总

JavaScript 在保持大约十年几乎不变。 语言的一个重要改进处于订单时, 的人的猜测时它将被完全定义和,更是重要是否浏览器将支持它。 最后一年,一个达成共识达到周围位于当前的语言和建议新的 ECMAScript 4 语言是明显不同,从今天的 JavaScript 中之间的语言的版本。 应生成 JavaScript 2.0 的新项目称为 Harmony。

您看,任何方式跨浏览器库似乎是至少计划有效和有效客户端开发未来的几年,仅可靠方法。 在这种情况 jQuery 是将集成到即将发布的 Microsoft Web 开发工具的极好库。 看关闭一下 ; 您会很高兴您 ! 快乐的 jQuery 编码 !

将向 Dino 您想询问的问题和提出的意见提出发送至 cutting@Microsoft.com.

Dino Esposito 是 IDesign 和的 Microsoft .NET: Architecting Applications for the Enterprise (Microsoft Press, 2008) co-author 架构师。 基于在意大利,Dino 是世界各地的业内活动中发表演讲。 您可以加入在他的博客 weblogs.asp。 net / despos.