jQuery不仅支持所有现代浏览器,包括IE、Firefox、Safari、Opera和Chrome等,还可以在编写代码和浏览器API冲突时隐藏不一致性(和错误)。

1. jQuery

jQuery擅长在HTML文档中查找、遍历和操纵HTML元素。一旦找到元素,jQuery就可以方便的在其上进行操作,如连接事件处理程序、使其具有动画效果以及围绕它的Ajax交互等。

1.1 jQuery函数

jQuery函数对象可以用来访问jQuery特性。

 $(function (){
     $("#album-list img").mouseover(function(){
         $(this).animate({ height: '+=25', width: '+=25'})
                .animate({ height: '-=25', width: '-=25'});
     });
 });
  • 第一行代码调用了jQuery函数($),并向其中传递了一个匿名的JavaScript函数作为第一个参数:
$(function (){

当传递一个函数作为第一个参数时,jQuery就会假定这个函数是要在浏览器完成构建(由服务器提供的)HTML页面中的文档对象模型(Document Object Model, DOM)后立即执行,换句话说,这个函数在从服务器端加载完HTML页面之后执行。这样就可以安全的执行函数中与DOM冲突的脚本,这种情况称为“DOM准备”事件。

  • 第二行代码向jQuery函数传递一个字符串“#album-list img”:
 $("#album-list img").mouseover(function(){

jQuery把这个字符串解释为选择器。选择器会告知jQuery需要在DOM中查找的元素。我们可以使用像类名和相对位置这样的特性值来查找元素。这一行代码的意图是告知jQuery查找id值为“album-list”的元素中的所有图像

当执行选择器时,它会返回一个包含零个或多个匹配元素的封装集(wrapped set)。我们可以调用其他任何jQuery方法来操作封装集中的元素。例如,上面的代码调用mouseover方法为与选择器匹配的每个图像元素的onmouseover事件连接处理程序。

  • jQuery利用JavaScript的函数式编程特性,经常把创建的或传递的函数作为jQuery方法的参数。为了表达事件触发时想进行的处理,就向mouseover方法传递了一个包含事件处理代码的函数参数:
 $(this).animate({ height: '+=25', width: '+=25'})
        .animate({ height: '-=25', width: '-=25'});

上面的例子实现了在触发mouseover事件时,匹配选择器的img元素会产生动画效果。在上面的代码中,之所以使用this关键字来引用要做动画效果的元素,是因为this是指向的是触发事件的元素

注意代码第一次将元素传递给jQuery函数的方法($(this))。jQuery将该参数看成一个元素的引用参数,并返回一个包含有该元素的封装集。

一旦将某个元素包含在jQuery封装集中,就可以调用jQuery方法(如animate)来操纵这个元素。示例中的代码首先将图像放大,然后在缩小的效果。

1.2 jQuery选择器

选择器是指传递给jQuery函数的,用来在DOM中选择元素的字符串。

例子 意义
$("#header") 查找id值为“header”的元素
$(".editor-label") 查找class名为“.editor-label的所有元素”
$("div") 查找所有<div>元素
$("#header div") 查找id值为“header”元素的所有后代<div>元素
$("#header>div") 查找id值为“header”元素的所有子<div>元素
$("a:even") 查找编号为偶数的锚标签

“#album-list img”用来选择id为album-list的<img>标签。

作为选择器的字符串看起来像层叠样式表(Cascading Style Sheet,CSS)中的项,是因为jQuery选择器的语法派生自CSS3.0选择器的语法,并在其基础上做了一些补充。

1.3 jQuery事件

jQuery的另一个优势在于,它提供了用来订阅DOM中事件的API。尽管使用一个通用的on方法可以捕获指定名称的任何事件,但jQuery也为一般的事件提供了专门的方法,比如click、blur和submit

可以通过传进一个函数来告知jQuery在事件触发时进行的处理。传递进的函数可以是匿名的,也可以是一个作为事件处理程序的命名函数,如下所示:

 $("#album-list img").mouseover(function(){
     animateElement($(this));
 });

 function animateElement(element){
         element.animate({ height: '+=25', width: '+=25'})
                .animate({ height: '-=25', width: '-=25'});
     });
 }

一旦选择了一些DOM元素或是在一个事件处理程序内,jQuery就可以很容易的操纵页面上的元素,读取或设置他们的特性值,添加或移除他们的CSS类等。下面的代码演示了当用户的鼠标移过元素时,如何向一个页面上的锚标签添加或从中删除highlight类。当用户在标签上移动鼠标时,锚标签就会改变外观(假如有一个合适的highlight样式设置):

 $("a").mouseover(function(){
     $(this).addClass("highlight");
 }).mouseout(function(){
     $(this).removeClass("highlight");
 })

注意:

  • 代码中用到的所有依赖于封装集的jQuery方法,像mouseover方法,都返回同样的jQuery封装集。这就是说可以继续在选择的元素上调用jQuery方法,而不用再重新选择这些元素。这称为方法链
  • 许多常用操作在jQuery中都有与其对应的捷径方法(shortcut)。设置mouseover和mouseout效果是一种常见的操作,切换样式类型也是一种常见的操作。可以使用jQuery捷径方法重写上面的代码:
 $("a").hover(function(){
     $(this).toggleClass("highlight");
 })

jQuery包含了向Web服务器回发异步请求所需要的所有功能。可以利用jQuery来生成POST请求或GET请求,并且当请求完成(或出现错误)时jQuery会发出通知。

非侵入式JavaScript:

在Web早期阶段,jQuery出现以前,在同一个文件中混杂JavaScript代码和HTML标记是非常流行的做法。将JavaScript代码作为某个特性的值放入HTML元素中是很常见的,如以下代码:

<div onclick="javascript:alert('click');">Testing, testing</div>

当时在标记中嵌入JavaScript代码,是因为没有更简单的方法可以用来捕获单击事件,尽管嵌入的JavaScript代码可以实现事件捕获,但是这样的代码不够简洁。jQuery改变了这种情况,因为jQuery提供了查找元素和捕获单击事件更好的方法。现在可以从HTML特性中移除JavaScript代码了。事实上,可以将javascript代码与HTML完全分离。

非侵入式javascript很好的实践了javascript代码和标记的分离,可将所有需要的脚本代码打包到js文件中。如果查看视图的源代码,将不会看到有javascript代码嵌入在标记中。即使查看视图渲染的HTML标记,也看不到任何的javascript代码,脚本留下的唯一的痕迹是一个或多个引用javascript文件的<script>标签。

 1.4 jQuery的用法

     因为jQuery非常常用,站点布局(/Views/Shared/_Layout.cshtml)的footer部分包含了一个jQuery脚本引用。因此,默认情况下,站点的任何视图中都可以使用jQuery。在没有使用默认布局的任何视图中,或者如果我们在站点布局中删除了jQuery脚本引用,添加jQuery脚本引用和删除jQuery脚本引用是很容易的,只需要直接脚本引用或者使用预配置的jQuery捆绑。

要添加脚本引用,可包含如下的代码:

<script src="~Scripts/jquery-1.10.2.js"></script>

注意:ASP,NET MVC的Razor视图引擎会把这里的~操作符解析为当前网站的根目录,即便它出现了src特性。另外,HTML5不需要指定类型特性为text/javascript。

但这种方法依赖于版本,更好的在驶入中包含jQuery引用的方法是使用内置的、版本无关的jQuery脚本捆绑。

 @Scripts.Render(~/bundles/jquery)

上面的调用将渲染/App_Start/BundleConfig.cs中预定义的“jquery”脚本捆绑,这种捆绑利用了ASP.NET中的捆绑和微小特性,该特性利用版本号中包含的通配符匹配,自动优先使用jQuery的轻量版本。

  public static void RegisterBundles(BundleCollection bundles)
  {
     bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                 "~/Scripts/jquery-{version}.js"));

         //......
  }

2.1 自定义脚本

自定义的JavaScript代码,一般放置在“Scripts/App”目录下。

此处创建一个新的MusicScripts.js文件,并添加以下代码:

 $(function () {
     $("#album-list img").mouseover(function () {
         $(this).animate({ height: '+=25', width: '+=25' })
                .animate({ height: '-=25', width: '-=25' });
     });
 });

2.2 在节中放置脚本

 @section Scripts{
      <script src="~/Scripts/App/MusicScripts.js"></script>
  }

2.3 Scripts目录下的其他文件

  • Bootstrap.js:

包含一组基于jQuery的插件,他们通过添加额外的交互行为来增强Bootstrap。例如,Modals插件可显示简单的、使用Bootstrap样式的模态化界面,他使用jQuuery管理事件和动态页面显示。

  • Respond.js:

是一个很小的JavaScript库,包含的原因是因为Bootstrap要用到。

  • Modernizr.js:

通过改造老版本浏览器来帮助我们构建富有现代气息的应用程序。其中一个重要工作就是在老版本浏览器中启动新的HTML5元素(比如header、nav和menu),也可以检测特定浏览器是否支持一些高级功能,像定位位置(geolocation)和绘画画布(drawing canvas)。

 3 Ajax

3.1 Ajax辅助方法

ASP.NET MVC框架中包含一组Ajax辅助方法,他们可以用来创建表单和指向控制器操作的链接,但不同的是它们是异步进行的。当然使用这些辅助方法时,不需要编写任何脚本代码来实现程序的异步性。

这些Ajax辅助方法依赖于非侵入式MVC的jQuery扩展,如果使用这些辅助方法,需要引入脚本文件jquery.unobtrusive-ajax.js,并在视图中添加此脚本引用

 3.2 在项目中添加非侵入式Ajax脚本

Nuget --> Microsoft jQuery Unobtrusive Ajax --> 安装

脚本引用可以添加到程序的_Layout视图中,也可以仅添加到使用Ajax辅助方法的视图中。除非在网站中发出大量的Ajax请求,否则建议添加到单独的视图中。

脚本的添加可以拖拽。

 3.3 Ajax的ActionLink方法

与HTML辅助方法类似,Ajax属性上的大部分Ajax辅助方法都是扩展方法(出了AjaxHelper类型之外)。

Ajax属性的ActionLink方法可创建一个具有异步行为的锚标签,代码实现:

 1  <div id="dailydeal">
 2      @Ajax.ActionLink("Click here to see today's special!",
 3            "DailyDeal",
 4            null,
 5            new AjaxOptions
 6            {
 7                UpdateTargetId = "dailydeal",
 8                InsertionMode = InsertionMode.Replace,
 9                HttpMethod = "GET"
10            },
11            new {@class = "btn btn-primary"})
12  </div>

ActionLink

  • 第一个参数指定了链接文本;
  • 第二个参数是要异步调用的操作的名称,类似于同名的HTML辅助方法,Ajax辅助方法ActionLink也提供了各种重载版本,用来传递控制器的名称、路由值和HTML特性。
  • AjaxOptions参数指定了发送请求和处理服务器返回的结果的方式。参数中还包括用来处理错误、显示加载元素、显示确认对话框等的选项。

在这个示例中,AjaxOptions参数的选项指定了要使用来自服务器的响应元素来替换id值为“dailydeal”的元素

  • 最后的htmlAttributes参数指定了为链接使用的HTML类,以应用一个基本的Bootstrap按钮样式

为得到服务器的响应,需要在控制器的HomeController上添加一个DailyDeal操作:

  public ActionResult DailyDeal()
  {
      var album = GetDailyDeal();

      return PartialView("_DailyDeal",album);
  }

  private Album GetDailyDeal()
  {
      var album = storeDB.Albums
                  .OrderBy(a => System.Guid.NewGuid())
                  .First();
      album.Price *= 0.5m;
      return album;
  }

 Html5特性

非侵入式JavaScript的显著特点是在HTML中不包含任何JavaScript代码,也就是在HTML中看不到脚本代码。Ajax代码中指定的所有设置被编码成了HTML元素的特性,并且大多数的编码特性都有data-前缀,通常称为data-特性。

HTML5规范为私有应用程序状态保留了data-特性。换句话说,Web浏览器不会尝试解释data-特性的内容。因此可放心的把数据交给它,这些数据不会影响页面的显示或渲染。

向应用程序中添加jquery.unobtrusive-ajax文件的目的是查找特定的data-特性,然后操纵元素使其表现出不同行为。如果知道使用jQuery可以很容易地查找元素,那么非侵入式JavaScript文件中出现如下所示的代码也就很容易理解了

 $(function)(){
     $("a[data-ajax]=true").  //do something
 });

这段代码将使用jQuery查找data-ajax特性值为true的所有锚元素。元素上的data-ajax特性用来标识该元素需要实现异步行为。一旦非侵入式脚本识别了异步元素,它就可以读取该元素的其他设置(像替换模式、更新目标以及HTTP方法),还可以通过使用jQuery连接事件和发送请求来修改该元素的行为。

所有ASP.NET MVC Ajax特性都使用data-特性。

3.4 Ajax表单

使用Ajax在页面上放置一个异步表单

 1 <div class="panel panel-default">
 2     <div class="panel-heading">Artist search</div>
 3     <div class="panel-body">
 4         @using (Ajax.BeginForm("ArtistSearch", "Home",
 5            new AjaxOptions
 6            {
 7                InsertionMode = InsertionMode.Replace,
 8                HttpMethod = "GET",
 9                OnFailure = "searchFailed",
10                LoadingElementId = "ajax-loader",
11                UpdateTargetId = "searchresults",
12            }))
13         {
14             <input type="text" name="q" />
15             <input type="submit" value="search" />
16             <img id="ajax-loader"
17                  src="@Url.Content("~/Images/ajax-loader.gif")"
18                  style="display:none" />
19         }
20         <div id="searchresults"></div>
21     </div>
22 </div>
  • 当用户单击提交按钮时,浏览器就会向控制器HomeController的ArtistSearch操作发送异步的GET请求
  • LoadingElementId作为其中的一个选项。当执行异步请求时,客户端框架会自动的显示这个元素。此处为一个等待的动画。
  • OnFailure选项包括许多参数,可以设置这些参数以捕获来自Ajax请求的各种客户端事件,如OnBegin、OnComplete、OnSuccess和OnFailure等。可以给这些参数赋予一个JavaScript函数的名称,当事件触发时,调用该函数

上面的代码为OnFailure事件指定了一个名为searchFailed的函数,因此需要使用运行时能够访问到这个函数。此处将函数存放在MusicScript.js文件中。

 function searchFailed() {
     $("#searchresults").html("Sorry, there was a problem with the search.");
 }

如果服务器返回一个错误,就意味着Ajax辅助方法执行失败,此时可以捕获OnFailure事件。

  • 最后,当用户单击提交按钮提交表单时,服务器会收到一个Ajax请求,并可能以任意格式的内容做出响应。当客户端收到来自服务器端的响应时,非侵入式脚本就会将相应内容放入DOM中。

此处,新内容要替换的是一个id值为searchresults的元素

控制器中的代码为:

    public ActionResult ArtistSearch(string q)
    {
        var artists = GetArtists(q);

        return PartialView("_ArtistSearch", artists);
    }

    private List<Artist> GetArtists(string searchString)
    {
        return storeDB.Artists
              .Where(a => a.Name.Contains(searchString))
              .ToList();
    }

渲染的部分视图利用模型构建列表。该部分视图的名称是ArtistSearch.cshtml,位于项目的Views/Home文件夹下。

 @model IEnumerable<MvcMusicStore.Models.Artist>

 <div id="searchresults">
     <ul>
         @foreach (var item in Model)
         {
             <li>@item.Name</li>
         }
     </ul>
 </div>

4客户端验证

对于数据注解特性来说,ASP.NET MVC框架的客户端验证是默认开启的,下面介绍Album类的Title和Price属性:

     [Required]
     [StringLength(, MinimumLength = )]

     public string Title { get; set; }

     [Required]
     [Range(0.01, 100.00)]

     [DataType(DataType.Currency)]
     public decimal Price { get; set; }

数据注解特性使得这两个属性值必须键入,并且还对Title属性值限定了长度,对Price属性值范围限定了范围。ASP.NET MVC的模型绑定器在设置这些属性时会执行服务器端验证。这些内置的特性也触发客户端验证。客户端验证依赖于jQuery验证插件。

4.1 jQuery验证

jQuery验证插件(jquery.validate)默认情况下在MVC5应用程序项目的Scripts文件夹下。如果想实现客户端验证,那么在相应的视图中就需要包含jqueryval捆绑的引用。如果引用放到_Layout中,所有的视图上都会加载脚本,而不是仅在需要jQuery验证的视图上加载脚本,性能会受到影响。

 4.2 自定义验证

编写的MaxWordsAttribute验证特性代码如下:

   public clsaa MaxWordsAttribute : ValidationAttribute
   {
         public MaxWordsAttribute(int maxWords) : base("{0} has too many words.")
         {
          _maxWords = maxWords;
         }

         protected override ValidationResult IsValid(object value,
                                                        ValidationContext validationContext)
         {
            var valueAsString = value.ToString();
            if( valueAsString.Split(' ').Length > _maxWords)
            {
               var errorMessage = FormatErrorMessage(validationContext.DisplayName);
               return new ValidationResult(errorMessage);
             }
            return ValidationResult.Success;
         }
        private readonly int _maxWords;
   }

该特性只支持服务器端的验证,使用方法如下:

     [MaxWords()]
     public string Title { get; set; }

4.2.1 IClientValidatable

IClientValidatable接口定义了单个方法:GetIClientValidationRules。当ASP.NET MVC框架使用这个接口查找验证对象时,它会调用GetClientValidationRules方法来检索ModelClientValidationRule对象序列。这些对象携带有框架发送给客户端的元数据和规则。

可使用下面的代码为自定义验证器实现该接口:

 public clsaa MaxWordsAttribute : ValidationAttribute,IClientValidatable
      {
         public MaxWordsAttribute(int maxWords) : base("{0} has too many words.")
         {
              _maxWords = maxWords;
         }
         public int WowrdCount { get; set; }
         protected override ValidationResult IsValid(object value, ValidationContext validationContext)
         {
            var valueAsString = value.ToString();
            if( valueAsString.Split(' ').Length > _maxWords)
            {
               var errorMessage = FormatErrorMessage(validationContext.DisplayName);
               return new ValidationResult(errorMessage);
             }
            return ValidationResult.Success;
         }

         public IEnumerable<ModelClientValidationRule> GetClientValidationRules(MdelMetadata metadata,ControllerContext context)
         {
             var rule = new ModelClientValidationRule();
             rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
             rule.ValidationParameters.Add("wordcount", WordCount);
             rule.ValidationType = "maxwords";
             yield return rule;
         }
      }

要实现客户端验证,需要提供如下几点信息:

  • 如果验证失败,要显示的提示消息
  • 允许的单词数的范围
  • 一段用来计算单词数量的JavaScript代码标识。

这些信息就是嗲吗放进返回规则中的内容。请注意,如果需要在客户端触发多种类型的验证,代码可以返回多个规则。

ASP.NET MVC框架在客户端上利用GetClientValidationRules方法返回的规则将信息序列化为data-特性。

ASP.NET MVC5高级编程 之 Ajax的更多相关文章

  1. ASP.NET MVC5 高级编程 第5章 表单和HTML辅助方法

    参考资料<ASP.NET MVC5 高级编程>第5版 第5章 表单和HTML辅助方法 5.1 表单的使用 5.1.1 action 和 method 特性 默认情况下,表单发送的是 HTT ...

  2. ASP.NET MVC5 高级编程 第3章 视图

    参考资料<ASP.NET MVC5 高级编程>第5版 第3章 视图 3.1 视图的作用 视图的职责是向用户提供界面. 不像基于文件的框架,ASP.NET Web Forms 和PHP ,视 ...

  3. ASP.NET MVC5 高级编程 第2章 控制器

    参考资料<ASP.NET MVC5 高级编程>第5版 第2章 控制器 控制器:响应用户的HTTP 请求,并将处理的信息返回给浏览器. 2.1 ASP.NET MVC 简介 MVC 模式中的 ...

  4. ASP.NET MVC5 高级编程-学习日记-第一章 入门

    1.1 ASP.NET MVC 简介 ASP.NET是一种构建Web应用程序的框架,它将一般的MVC(Model-View-Controller)模式应用于ASP.NET框架. 1.1.1 MVC模式 ...

  5. ASP.NET MVC5高级编程 之 模型

    1. 为MVC Music Store建模 Models文件夹(右击) --> 添加 --> 类 为类添加对应的属性: public class Album { public virtua ...

  6. 学习《ASP.NET MVC5高级编程》——基架

    基架--代码生成的模板.我姑且这么去定义它,在我学习微软向编程之前从未听说过,比如php代码,大部分情况下是我用vim去手写而成,重复使用的代码需要复制粘贴,即使后来我在使用eclipse这样的IDE ...

  7. ASP.NET MVC5高级编程 之 视图

    1.1理解视图约定 当创建一个项目模版时,可以注意到,项目以一种非常具体的方式包含了一个结构化的Views目录.在每一个控制器的View文件夹中,每一个操作方法都有一个同名的视图文件与其对应.这就提供 ...

  8. ASP.NET MVC5高级编程 之 HTML辅助方法

    Html属性调用HTML辅助方法,Url属性调用URL辅助方法,Ajax属性调用Ajax辅助方法. HTML辅助方法 1.Html.BeginForm @using (Html.BeginForm(& ...

  9. ASP.NET MVC5高级编程 之 路由

    每个ASP.NET MVC应用程序都需要路由来定义自己处理请求的方式.路由是MVC应用程序的入口点.路由的核心工作是将一个请求映射到一个操作 路由主要有两种用途: 匹配传入的请求(该请求不匹配服务器文 ...

随机推荐

  1. Git与GitHub学习笔记(一)如何删除github里面的文件夹?

    按照以下步骤即可(本地删除) 1. git pull you git url2. git checkout 3. rm -r dirName4. git add --all5. git commit  ...

  2. 自学python 1.

    1.变量命名规范 1.数字,字母,下划线 2.不能数字开头和纯数字 3.要有意义 4.不要太长 5.驼峰和下划线 6.不要用中文 7.不能用关键字 8.区分大小写2.name = input(&quo ...

  3. npm scripts 脚本基础指南

    什么是npm脚本? npm 允许在package.json文件里面,使用scripts字段定义脚本命令. 初始化package.json -> npm init -> 经历一系列的问答即可 ...

  4. VS2017 15.6之后支持直接反编译了

    在 15.6 预览版 2 中,增加了导航到反编译源功能. 启用后,在任何引用的类型或成员上调用转到定义或查看定义时,将显示其通过 ILSpy 反编译使用重新构造方法主体的定义. 要打开此功能,请转到“ ...

  5. C语言编程程序的内存如何布局

    重点关注以下内容: C语言程序在内存中各个段的组成 C语言程序连接过程中的特性和常见错误 C语言程序的运行方式 一:C语言程序的存储区域 由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过 ...

  6. Coursera, Deep Learning 4, Convolutional Neural Networks, week3, Object detection

    学习目标 Understand the challenges of Object Localization, Object Detection and Landmark Finding Underst ...

  7. java时间计算

  8. Python问题:UnboundLocalError: local variable 'xxx' referenced before assignment

    参考链接: http://blog.csdn.net/onlyanyz/article/details/45009697 https://www.cnblogs.com/fendou-999/p/38 ...

  9. 什么是openstack

    什么是openstack OpenStack是一个云平台管理的项目,它不是一个软件. 这个项目由几个主要的组件组合起来完成一些具体的工作. 想要了解openstack,第一步我们可以观察他的概念图: ...

  10. CF1095E Almost Regular Bracket Sequence

    题目地址:CF1095E Almost Regular Bracket Sequence 真的是尬,Div.3都没AK,难受QWQ 就死在这道水题上(水题都切不了,我太菜了) 看了题解,发现题解有错, ...