AjaxjQuery基础教程

1、使用$()函数

  $()函数其实是创造了一个jQuery对象.
这个函数接受CSS选择符合作为参数,充当一个厂子,
返回包含页面被针对应元素的jQuery对象.
所有能够以体制表中使用的取舍符都可以传染被这函数,
随后便可本着郎才女貌的要素集合应用jQuery方法.

  于jQuery中,美元符号$其实就是标志符jQuery的”别名”. 

2、选择符

1. 基本选择符
    $('p')          //取得所有标签为p的元素
    $('.class')     //取得所有类为class的元素
    $('#id')        //取得id为id的元素
                    //以及其他css中的选择符
2. 属性选择符
    $('img[alt]')   //选择带有alt属性的所有图像元素
    //^表示值在字符串的开始, $表示值在字符串的结尾. *表示要匹配的值可以出现在字符串的任意位置, !表示对值取反
    $('a[href^="mailto:"]')     //选择页面中所有mailto:链接
    $('a[href$=".pdf"]')        //选择页面中所有pdf文档链接
    $('a[href^="http"][href*="henry"]') //选择href属性以http开头且在任意位置包含henry的元素

3. 自定义选择符
    $('div.horizontal:eq(1)')   //取得集合中的第二个元素
    $('tr:even')                //选择奇数行. 之所以是奇数行是因为第一行的编号是0    还可以写作:  $('tr').filter(':even')


    $('tr:nth-child(odd)')      //选择奇数行. :nth-child()是jq中唯一从1开始计数的选择符
    $('tr:contains(Henry)')     //根据上下文内容选择元素. contains选择符区分大小写

4. 基于表单的选择符
    $('input[type="radio"]:checked')    //可以选择所有选中的单选按钮
    $('input[type="text"]:disabled')    //选择禁用的文本输入字段

重复多之冲表单的挑选适合

    :input
    :button
    :enabled
    :disabled
    :checked:selected

3、 DOM遍历方法

filter方法

    $('tr').filter(':even')
    $('a').filter(function(){
        return this.hostname && this.hostname!=location.hostname;
    })                          //选择包含带有域名的href属性的,且域名不等于页面当前所在域的名称的a元素

 

    .next()     //选择下一个最接近的同辈元素
    $('td:contains(Henry)').next()

    .nextAll()  //选择后面的全部同辈元素

    //对应方法
    .prev()
    .prevAll()

    .siblings()     //选择处于相同DOM层次的所有其他元素,无论这些元素处于当前元素之前还是之后
    .parent().children()        //另一种方法

 

联网方法的原理:

  几乎有的jQuery方法都见面回一个jQuery对象,
因而而连缀调用几近个jQuery方法.

 

4. 访问DOM元素

    .get()
    var myTag = $('#my-element').get(0).tagName;    //获取带有id为my-element属性的元素的标签名
    var myTag = $('my-element')[0].tagName;         //一种简写方式

            

函数 描述
.add() 将元素添加到匹配元素的集合中。
.andSelf() 把堆栈中之前的元素集添加到当前集合中。
.children() 获得匹配元素集合中每个元素的所有子元素。
.closest() 从元素本身开始,逐级向上级元素匹配,并返回最先匹配的祖先元素。
.contents() 获得匹配元素集合中每个元素的子元素,包括文本和注释节点。
.each() 对 jQuery 对象进行迭代,为每个匹配元素执行函数。
.end() 结束当前链中最近的一次筛选操作,并将匹配元素集合返回到前一次的状态。
.eq() 将匹配元素集合缩减为位于指定索引的新元素。
.filter() 将匹配元素集合缩减为匹配选择器或匹配函数返回值的新元素。
.find() 获得当前匹配元素集合中每个元素的后代,由选择器进行筛选。
.first() 将匹配元素集合缩减为集合中的第一个元素。
.has() 将匹配元素集合缩减为包含特定元素的后代的集合。
.is() 根据选择器检查当前匹配元素集合,如果存在至少一个匹配元素,则返回 true。
.last() 将匹配元素集合缩减为集合中的最后一个元素。
.map() 把当前匹配集合中的每个元素传递给函数,产生包含返回值的新 jQuery 对象。
.next() 获得匹配元素集合中每个元素紧邻的同辈元素。
.nextAll() 获得匹配元素集合中每个元素之后的所有同辈元素,由选择器进行筛选(可选)。
.nextUntil() 获得每个元素之后所有的同辈元素,直到遇到匹配选择器的元素为止。
.not() 从匹配元素集合中删除元素。
.offsetParent() 获得用于定位的第一个父元素。
.parent() 获得当前匹配元素集合中每个元素的父元素,由选择器筛选(可选)。
.parents() 获得当前匹配元素集合中每个元素的祖先元素,由选择器筛选(可选)。
.parentsUntil() 获得当前匹配元素集合中每个元素的祖先元素,直到遇到匹配选择器的元素为止。
.prev() 获得匹配元素集合中每个元素紧邻的前一个同辈元素,由选择器筛选(可选)。
.prevAll() 获得匹配元素集合中每个元素之前的所有同辈元素,由选择器进行筛选(可选)。
.prevUntil() 获得每个元素之前所有的同辈元素,直到遇到匹配选择器的元素为止。
.siblings() 获得匹配元素集合中所有元素的同辈元素,由选择器筛选(可选)。
.slice() 将匹配元素集合缩减为指定范围的子集。

第3章 事件

1. $(document).ready()和window.onload事件

  • $(document).ready()注册是事件处理程序会以DOM完全就绪并得以用时调用.这意味有因素对剧本而言都是足以看的,但是连无代表有涉的公文都曾生充斥了毕.
    即当HTML下充斥完成并分析成DOM树后,代码就可以运行.
  • 如果window.onload意味着文档完全下充斥到浏览器中了.
  • 一般的话,使用$(document).ready()要优于onload.
    但是因支撑文件或者还未曾加载成功,所以类似图像的可观和增幅这样的性能不自然有效.
    如果需要看这些性, 可能得选择实现一个onload事件处理程序,
    使这有限种机制能和平共存.

(document).ready()而简写为:();
即:

    $(function(){
        //code here
    });

为避免的冲,可以设置出让标示符控制权

jQuery.noConflict();        //之和就通过jQuery来调用jQuery的方法

这种气象下,可以当.ready()函数中采用的技艺     
 

  传递让ready函数的回调函数可以接纳一个参数

  jquery对象自我,利用这参数,可以重新命名ready,而不用顾虑导致冲突

   jQuery(function($){
        //使用$的代码
    });

2、 事件添加

    //.on绑定事件
    $(this).on('click',function(){});
    //.click
    $(this).click(function(){})

    //添加类
    $('btn').addClass('classname');
    //移除类
    $('btn').removeClass('classname');
    //根据相应的类是否存在而添加或删除类
    $('btn').toggleClass('classname');

.hover()方法:
接受两个函数参数,第一个见面以鼠标指针进入被增选的因素时实施,而第二只函数会当鼠标指针离开该因素时触法

//设定事件目标
    $('#switcher').click(function(event){
        if(event.target = this){
            $('#switcher button').toggleClass('hidden');
        }

    });
    //停止事件传播
    event.stopPropagation();        //避免其他DOM元素响应事件
    //阻止默认操作
    .preventDefault();

同时调用.stopPropagation()和preventDefault()的同等栽简写方式: 在事件处理程序中回到false

    $(function(){
        $('#switcher').click(function(event){
            if($(event.target).is('button')){       //.is()方法接收一个选择符表达式,然后用选择符来测试当前jQuery对象. 如果集合中至少有一个元素与选择符匹配,.is()返回true
                var bodyClass = event.target.id.split('-')[1];
                $('body').removeClass().addClass(bodyClass);
                $('#switcher button').removeClass('selected');
                $(event.target).addClass('selected');   //这里this引用的都是"#switch"对象,因此要访问被单击的按钮斗殴要通过event.target来引用
                event.stopPropagation();
            }
        });
    });

.on()方法也可以收到相应参数实现事件委托.
如果叫.on()方法传入的次独参数是一个选择符表达式,jQuery会把click事件处理程序绑定到#switch对象,同时于event.target和挑选切合表达式.
如果匹配, jQuery会把this关键字映射到相当的素,
否则无会见执行事件处理程序.

4、移除事件处理

.off(‘click’)

尚可为事件处理程序上加命名空间

    $('#switcher').on('click.collapse', function(){});
    $('#switcher').off('click.collapse');

对此事件处理系统而言, 后缀.collapse是不可见的.

使非采用匿名函数,则就是可免行使事件命名空间,
.off()会拿命名函数作为第二单参数, 结果只是会免去对一定处理程序的深的.

 

次、4章节 样式与动画

1、 通过.css()来取得或改动元素样式属性之值.

  为了取得有样式属性的价, 可以吗这法子传递一个字符串形式的属于性名,
然后一致获得一个字符串形式之属性值. 要博多单样式属性之值,
可以传属性名的反复组, 得到的则是性与值勾搭的对象.

  对于由于多只单词构成的属于性名,
jQuery既可解释并字符版的css表示拟(background-color),
也可以分解驼峰大小写形式之DOM表示拟(backgroundColor)

  对于带动浏览器前缀的属于性值(比如-webkit-property-name,
-ms-property-name), 用jQuery不需要超前检测, 而可以一直下正式的性质名.
比如:

 

.css('propertyName','value'). //如果样式对象中不存在这个属性,jQuery就会依次检测所有带前缀(Webkit, o, Moz, ms)的属性, 然后使用第一个找到的那个属性.

2、 隐藏和展示元素

  • .hide()方法会将匹配的元素集合的内联style属性设置为display:none.
    它可以拿display的价值变为none之前, 记住原先的display值
  • .show()方法会将相当的元素集合的display属性,恢复也使用display:none之前的可见属性

  可以啊hide()和show()方法吃指定时长参数, 产生动画效果.比如

  .hide(‘duration’)方法会同时减少元素的可观, 宽度和莫透明度,
直到三个属性之值都也0. 而会吗该因素采用display:none.
而show(‘duration’)方法相反.

  此外,还可指定两栽预设的速度参数 ‘slow’ 和 ‘fast’
,分别在600ms和200ms内就效果.
如果传入的是另外字符串,jQuery就会在默认的400ms内到位效果.要指定更纯粹的速度,可以下毫秒数值.
数值不待为此引号.

  有其他显示/隐藏元素的函数:

//参数: 1. speed(毫秒/'slow'/'normal'/'fast')
//       2. callback[执行完的回调参数]

//淡入淡出 只是改变不可见性
.fadeIn();     //逐渐增大不透明度, 淡入
.fadeOut();    //逐渐减少不透明度, 淡出

//滑上和滑下
.slideDown()
.slideUp()

//切换可见性
.slideToggle();

3、创建于定义动画

  .animate():两种植形式

先是种植形式. 接收四单参数  

  1. 一个富含样式属性及值的对象: 与前方议论的.css()方法被之参数近似
  2. 可选的时长参数: 既可以是预置的字符串, 也堪是毫秒数值
  3. 可选的缓动(easing)类型
  4. 可选的转调函数

    .animate({

    property1:'value1',
    property2:'value2'
    

    }, {

    duration:'value',
    easing: 'value',
    specialEasing: {
        property1: 'easing1',
        property2: 'easing2'
    },
    complete: function(){
        //...
    },
    queue: true,
    step: callback
    

    });

当使用 animate() 时,必须以 Camel
标记法书写有的属于性名,比如,必须使 paddingLeft 而非是
padding-left,使用 marginRight 而无是 margin-right,等等。

   还可用.animate()为同样组元素应用多重复力量,
可以经过联网这些效应来兑现排队

   简单概括:

  1. 平组元素上之功能
    1. 当当一个.animate()方法中盖差不多个属性之章程应用时, 是同时发生的
    2. 当为艺术连缀的花样以时,
      按顺序发出的(排队效果)除非queue选项值为false
  2. 大多组元素上的效果
    1. 默认情况下是同时发生的
    2. 当以任何一个力量方法还是当.queue()方法的回调函数中运用时,
      是按梯次来的(排队效果)

第5章  操作DOM

1、 操作属性

  1) .attr()  .removeAttr()

//操作非类属性
.attr();    //和.css()方法类似, 可以接收一对属性名/属性值参数 或者是一个包含键值对的对象
.removeAttr();

//还可以使用值回调为每个元素设置不同的属性值
$(document).ready(function() {
  // Use attr() to add an id, rel, and title.
  $('div.chapter a[href*="wikipedia"]').attr({
    rel: 'external',
    title: function(){                  return  'Learn more about ' + $(this).text()    //利用值回调的上下文          + ' at Wikipedia.';     },
    id: function(index, oldValue) {  //值回调
      return 'wikilink-' + index;
    }
  });
});

 

每次触发值回调, 都见面于她传到两只参数. 第一只参数是整数, 表示迭代潮数.
第二个参数保存之是修改前的性能的价, 这里并不曾就此到.

  2) DOM元素属性

  HTML属性和DOM属性:

  • HTML属性是靠页面标记中居引号中的值
  • DOM属性则是因经JavaScript能够存取的价

 在jQuery中, 可以由此.prop()方法取得和安装DOM属性:

//取得"checked"属性的当前值
var currentChecked = $('.my-checkbox').prop('checked');
//设置"checked"属性的值
$('.my-checkbox').prop('checked', false);

 

  3) 表单控件的值  

  HTML属性和DOM属性差别最可怜就是反复表单控件的值.
比如,文本输入框的value属性在DOM中的性质被defaultValue,
DOM中虽从来不value值. 而选择列表(select)元素,
其选择的值当DOM中司空见惯是由此selectedIndex属性,
或者经过其选择元素的selected属性来取得.

  由于在这些差异, 在赢得跟装表达控件值时,最好不用用.attr()方法.
而对此选择列表, 最好呢毫无用.prop()方法. 建议用jQuery提供的val()方法:

//取得文本输入框的当前值
var inputValue = $('#my-input').val();
//取得选项列表的当前值
var selectValue = $('#my-select').val();
//设置单选列表的值
$('#my-single-select').val('value3');
//设置多选列表的值
$('#my-multi-select').val(['value1','value2']);

2. DOM树操作

  1. ####  $() 可以创建新因素

  2. #### 插入新因素

    1. .insertBefore():   在现有元素表, 之前增长内容
    2. .prependTo():      在现有元素中, 之前增长内容
    3. .appendTo():       在现有元素中, 之后续加内容
    4. .insertAfter():       在现有元素表, 之后上加内容
      1
      2
      3
      // Add "back to top" links.
      $('<a href="#top">back to top</a>').insertAfter('div.chapter p');
      $('<a id="top"></a>').prependTo('body');
  3. #### 移动元素

    1
    2
    // Create footnotes.
    $('span.footnote').<strong>insertBefore</strong>('#footer');
  4. #### 包装元素

    1
    2
    3
    4
    5
    // Create footnotes.
    $('span.footnote')
      .insertBefore('#footer')
      .<strong>wrapAll</strong>('<ol id="notes"></ol>')    //把所有脚本都包含在一个<ol>中
      .<strong>wrap</strong>('<li></li>')                  //把每一个脚注分布包装在自己的<li>中

    用.each()方法作为显式迭代器, 啊提脚注的职加标记和编码

    1. // Create footnotes.

    2. var $notes = $(‘<ol
      id=”notes”></ol>’).insertBefore(‘#footer’);

    3.   $(‘span.footnote’).each(function(index) {

    4.     $(‘<sup>’ + (index + 1) + ‘</sup>’).insertBefore(this);

    5.     $(this).appendTo($notes).wrap(‘<li></li>’);

    6. });

  5. #### 使用反向插入方法

    对应之反向方法: 

    1
    2
    3
    $('<p>Hello</p>').appendTo('#container');
    //与下面的代码结果一样
    $('#container').append('<p>Hello</p>');

    故地方的代码还可以做:

    1
    2
    3
    4
    5
    6
    7
    8
    // Create footnotes.
    var $notes = $('<ol id="notes"></ol>').insertBefore('#footer');
    $('span.footnote').each(function(index) {
      $(this)
        .before('<sup>' + (index + 1) + '</sup>')
        .appendTo($notes)
        .wrap('<li></li>');
    });  
  6. #### 复制元素

    .clone()

    1
    $('div.chapter p:eq(0').clone().insertBefore('div.chapter');
  7. #### 元素内容

    1. .html()     //返回匹配元素的html标记, 或调换元素内容(如果发参数)
    2. .text()    
      //也可以收获匹配元素的始末,或者用新字符替换匹配元素的内容.
      但是.text()始终会获或者安装纯文本内容. 所有html标签都用为忽视掉,
      而所有html实体也会见受转正为对应之字符
  8. #### DOM操作方法的简单总结

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    //要在html中创建新元素, 使用$()标签
     
    //要在每个匹配的元素中插入新元素:
    .append()
    .appendTo()
    .prepend()
    .prependTo()
     
    //要在每个匹配的元素相邻的位置上插入新元素
    .after()
    .insertAfter()
    .before()
    .insertBefore()
     
    //要在每个匹配的元素外部插入新元素
    .wrap()
    .wrapAll()
    .wrapInner()
     
    //要用新元素或文本替换每个匹配的元素
    .html()
    .text()
    .replaceAll()
    .replaceWith()
     
    //要移除每个匹配的元素中的元素
    .empty()
     
    //要从文档中移除每个匹配的元素及其后代元素, 但不实际删除它们
    .remove()
    .detach()

第6章节 通过Ajax发送数据

  Ajax实质:
就是同种植无需刷新页面即可从服务器(或客户端)上加载数据的招数  

Ajax 1

$(document).ready(function() {
  $('#letter-a a').click(function(event) {
    event.preventDefault();

    $.ajaxSetup({               //$.ajaxSetup()函数可以修改调用Ajax方法时每个选项的默认值. 
                                //这个函数与$.ajax()接受相同的选项对象参数. 之后所有Ajax请求都使用传递给该函数的选项, 除非明确覆盖
      url: 'a.html',
      type: 'POST',
      dataType: 'html'
    });

    $.ajax({
      type: 'GET',
      success: function(data) {
        $('#dictionary').html(data);
      }
    });
  });

  $('#letter-b a').click(function(event) {
    event.preventDefault();
    $.getJSON('b.json', function(data) {            //$.getJSON()方法会在取得相应文件后对文件进行处理. 在数据从服务器返回后, 它只是一个简单的JSON格式的文本字符串. 
                                                    //$.getJSON()方法会解析这个字符串, 并将处理得到的JavaScript对象提供给调用代码
                                                    //接受两个参数, 第2个参数是当加载完成时调用的函数
                                                    //$.getJSON()函数: 没有该方法适用的DOM元素;作为结果的对象只能提供给脚本,而不能插入到页面中.
                                                    //getJSON()是作为全局jQuery对象(由jQuery库定义的jQuery或$对象)的方法定义的, 而不是个别jQuery对象实例的方法
                                                    //可把getJSON()方法看做类方法, 称其为全局函数. 这些全局函数使用的是jQuery命名空间.
      var html = '';
      $.each(data, function(entryIndex, entry) {    //$.each()函数不操作jQuery对象, 它以数组或对象作为第一个参数,以回调函数作为第二个参数. 
                                                    //此外还需要将每次循环中数组或对象的当前索引和当前项作为回调函数的两个参数
        html += '<div class="entry">';
        html += '<h3 class="term">' + entry.term + '</h3>';
        html += '<div class="part">' + entry.part + '</div>';
        html += '<div class="definition">';
        html += entry.definition;
        if (entry.quote) {
          html += '<div class="quote">';
          $.each(entry.quote, function(lineIndex, line) {
            html += '<div class="quote-line">' + line + '</div>';
          });
          if (entry.author) {
            html += '<div class="quote-author">' + entry.author + '</div>';
          }
          html += '</div>';
        }
        html += '</div>';
        html += '</div>';
      });
      $('#dictionary').html(html);
    });
  });

  $('#letter-c a').click(function(event) {
    event.preventDefault();
    $.getScript('c.js');        //$.getScript()也是一个全局函数. 接受一个url参数以查找脚本文件. 
                                //以这种方式取得的脚本会在全局环境下执行. 这意味着脚本有权访问在全局环境中定义的函数和变量, 当然也包括jQuery自身
  });

  $('#letter-d a').click(function(event) {
    event.preventDefault();
    $.get('d.xml', function(data) {     //加载xml文档. 
                                        //通常,$.get()函数只是取得由url指定的文件, 然后将纯文本格式的数据提供给回调函数. 但是在根据服务器提供的mine类型知道相应的是xml的情况下, 提供给回调函数的将是xml dom树
      $('#dictionary').empty();
      $(data).find('entry').each(function() {
        var $entry = $(this);
        var html = '<div class="entry">';
        html += '<h3 class="term">' + $entry.attr('term');
          html += '</h3>';
        html += '<div class="part">' + $entry.attr('part');
          html += '</div>';
        html += '<div class="definition">';
        html += $entry.find('definition').text();   //jQuery内部的选择符引擎, 对查找xml文档元素也有效
        var $quote = $entry.find('quote');
        if ($quote.length) {
          html += '<div class="quote">';
          $quote.find('line').each(function() {
            html += '<div class="quote-line">';
              html += $(this).text() + '</div>';
          });
          if ($quote.attr('author')) {
            html += '<div class="quote-author">';
              html += $quote.attr('author') + '</div>';
          }
          html += '</div>';
        }
        html += '</div>';
        html += '</div>';
        $('#dictionary').append($(html));
      });
    });
  });

  $('#letter-e a').click(function(event) {
    event.preventDefault();                             //为了防止单击这些链接时打开新的url.
                                                        //当默认动作是重新加载页面或重新打开新页面时, 推荐使用preventDefault()而不是return false结束该处理程序.
                                                        //return false意味着同时调用event.preventDefault()和event.stopPropagation(), 因此想要阻止事件冒泡, 还得调用后者
    var requestData = {term: $(this).text()};
    $.get('e.php', requestData, function(data) {        //向服务器传递数据. 第二个参数是一个用来构建查询关键字符串的键和值的对象.
      $('#dictionary').html(data);
    }).fail(function(jqXHR) {
      $('#dictionary')
      .html('Sorry, but an error occurred: ' + jqXHR.status)
      .append(jqXHR.responseText);
    });
  });

  $('#letter-f form').submit(function(event) {
    event.preventDefault();
    var formValues = $(this).serialize();
    $.get('f.php', formValues, function(data) {
      $('#dictionary').html(data);
    });
  });

  var url = 'http://examples.learningjquery.com/jsonp/g.php';
  $('#letter-g a').click(function(event) {
    event.preventDefault();
    $.getJSON(url + '?callback=?', function(data) {     //使用JSONP加载远程数据, 实现跨域
                                  //可以通过使用 JSONP 形式的回调函数来加载其他网域的 JSON 数据,如 "url?callback=?"。jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。 注意:此行以后的代码将在这个回调函数执行前执行。
                                  //该函数是简写的Ajax函数. 等价于: $.ajax({url:url, data: data, success: callback, dataType: json});  

      var html = '';
      $.each(data, function(entryIndex, entry) {
        html += '<div class="entry">';
        html += '<h3 class="term">' + entry.term + '</h3>';
        html += '<div class="part">' + entry.part + '</div>';
        html += '<div class="definition">';
        html += entry.definition;
        if (entry.quote) {
          html += '<div class="quote">';
          $.each(entry.quote, function(lineIndex, line) {
            html += '<div class="quote-line">' + line + '</div>';
          });
          if (entry.author) {
            html += '<div class="quote-author">' + entry.author + '</div>';
          }
          html += '</div>';
        }
        html += '</div>';
        html += '</div>';
      });
      $('#dictionary').html(html);
    });
  });

  $('#letter-h a').click(function(event) {
    event.preventDefault();
    $('#dictionary').load('h.html .entry');
  });

  var $loading = $('<div id="loading">Loading...</div>')
    .insertBefore('#dictionary');
                                                //jQuery提供的一组观察员函数, 来为各种与Ajax相关的事件注册回调函数.
                                                //这些观察员都是全局性的,且只能由$(document)调用
  $(document).ajaxStart(function() {            //当Ajax请求开始且尚未进行其他传输时出发.ajaxStart()的回调函数
    $loading.show();
  }).ajaxStop(function() {                      //最后一次活动请求终止时出发
    $loading.hide();
  });                                           //全局观察员函数还有.ajaxError()

  $('body').on('click', 'h3.term', function() {
    $(this).siblings('.definition').slideToggle();  //事件委托
  });
});

Ajax 2

 

 

第7段 使用插件

第8章节 开发插件

1. 在插件中行使$别名

  为了防止jQuery的别名$已经给让渡出去,
可以当插件的企图域内定义之快捷方式, 使用即时调用的函数表达式(IIFE,
Immediately Invoked Function Expression)

1
2
3
(function($){
    //code here
})(jQuery);

2. 补偿加新的全局函数  

  所谓全局函数, 实际上就是是jQuery对象的法门,
但从实践的角度达看,它们是位于jQuery命名空间内的函数. 比如Ajax 3Ajax 4Ajax 5Ajax 6Ajax 7Ajax 8Ajax 9Ajax 10.ajax(),.each(),
$.map(). 

  给jQuery添加新的全局方法就是如以首先节约被的IIFE内部定义一个方式,
在函数外部就得调用了. 因为她曾经是jQuery的靶子方法了. 比如:  

Ajax 11

/******************************************************************************
  Our plugin code comes first in this document. Normally, plugins would
  appear in separate files named jquery.plugin-name.js, but for our examples
  it's convenient to place this plugin code in the same JavaScript file as
  the code that calls it.
******************************************************************************/

/******************************************************************************
  $.sum()
  Return the total of the numeric values in an array/object.
******************************************************************************/
(function($) {
  $.sum = function(array) {
    var total = 0;

    $.each(array, function(index, value) {
      value = $.trim(value);
      value = parseFloat(value) || 0;

      total += value;
    });
    return total;
  };

  $.average = function(array) {
    if ($.isArray(array)) {
      return $.sum(array) / array.length;
    }
    return '';
  };
})(jQuery);


/******************************************************************************
  End plugin code; begin custom script code.
******************************************************************************/
$(document).ready(function() {
  var $inventory = $('#inventory tbody');
  var quantities = $inventory.find('td:nth-child(2)')
    .map(function(index, qty) {
      return $(qty).text();
    }).get();

  var sum = $.sum(quantities);
  $('#sum').find('td:nth-child(2)').text(sum);
});

Ajax 12

 

  此外, 还可以采用$.extend()函数通过其它一样栽语法定义全局函数:

Ajax 13

(function($) {
  $.extend({
    sum: function(array) {
      var total = 0;

      $.each(array, function(index, value) {
        value = $.trim(value);
        value = parseFloat(value) || 0;

        total += value;
      });
      return total;
    },
    average: function(array) {
      if ($.isArray(array)) {
        return $.sum(array) / array.length;
      }
      return '';
    }
  });
})(jQuery);

Ajax 14

 

  为了避免冲突, 可以把属于一个插件的大局对象都打包到一个目标中.
即使用取名空间隔离函数 .比如:

Ajax 15

(function($) {
  $.mathUtils = {
    sum: function(array) {
      var total = 0;

      $.each(array, function(index, value) {
        value = $.trim(value);
        value = parseFloat(value) || 0;

        total += value;
      });
      return total;
    },
    average: function(array) {
      if ($.isArray(array)) {
        return $.mathUtils.sum(array) / array.length;
      }
      return '';
    }
  };
})(jQuery);

Ajax 16

  调用时索要:

  var sum = $.mathUtils.sum(quantities);
  var average = $.mathUtils.average(prices);

 

3. 填补加jQuery对象方法

  1. 扩展jQuery.fn对象. jQuery.fn是jQuery.prototype的别名
  2. 坐jQuery的挑符表达式可能会见匹配零,一个或者多独要素,
    所有以筹划插件时该考虑隐式迭代
    Ajax 17

    (function($) {
      $.fn.swapClass = function(class1, class2) {
        this.each(function() {
          var $element = $(this);
          if ($element.hasClass(class1)) {
            $element.removeClass(class1).addClass(class2);
          }
          else if ($element.hasClass(class2)) {
            $element.removeClass(class2).addClass(class1);
          }
        });
      };
    })(jQuery);
    

    Ajax 18

  3. 方法连缀. 因此要当具备插件方法吃归一个jQuery对象,
    除非相应的措施肯定用于获取不同的信息.
    返回的jQuery对象日常就是this所引述的对象.
    如果使用.each()迭代全部历this, 那么好仅回去迭代的结果. 比如:

    Ajax 19

    (function($) {
      $.fn.swapClass = function(class1, class2) {
        return this.each(function() {
          var $element = $(this);
          if ($element.hasClass(class1)) {
            $element.removeClass(class1).addClass(class2);
          }
          else if ($element.hasClass(class2)) {
            $element.removeClass(class2).addClass(class1);
          }
        });
      };
    })(jQuery);
    

    Ajax 20

     这样, 就好在插件方法齐连内置方法了

4. 资灵活的章程参数

  • 恰的时刻, 利用回调函数支持灵活地修改插件行为, 从而不必修改插件代码
  • 若是插件是为贯彻用户界面元素, 或者需要跟元素的状态, 使用jQuery
    UI部件工厂来创造

 

附录A JavaScript闭包

1. 其中函数

  所谓中函数, 就是概念在另外一个函数中的函数. 可以避污染命名空间. 

  而JS中之其中函数可以规避定义其的表函数. 逃脱的道发生多:

  1. 可以为里函数指定给一个全局变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var globalVar;
      
    function outerFn() {
      console.log('Outer function');
      function innerFn() {
        console.log('Inner function');
      }
      globalVar = innerFn;
    }
    console.log('outerFn():');
    outerFn();
    console.log('globalVar():');
    globalVar();
  2. 好经在父函数吃返回值来赢得其中函数的援:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function outerFn() {
      console.log('Outer function');
      function innerFn() {
        console.log('Inner function');
      }
      return innerFn;
    }
    console.log('var fnRef = outerFn():');
    var fnRef = outerFn();  //Outer function
    console.log('fnRef():');
    fnRef();//Inner function

  当其中函数在概念其的作用域的外部为唤起发生时,
就创办了该内部函数的一个闭包.

  这种情景下, 我们遂既是非是中间函数局部变量,
也未是其参数的变量为随意变量
,
标函数的调用环境为封闭闭包的环境. 从精神上将,
如果内部函数引用了坐落外部函数中的变量, 相当给授权该变量能够让延迟使用.
因此, 当外部函数引用得后, 这些变量的内存不会见叫放走,
因为闭包仍然需要采用它们.

2. 在jQuery中创造闭包

  依然要注意以下是题目:

1
2
3
4
5
6
7
8
9
$(document).ready(function($) {
    // Stuff to do as soon as the DOM is ready;
    for(var i=0; i<5; i++){
        $('<div>Print ' + i + '</div>')
        .click(function(){
            console.log(i);
        }).insertBefore('body');
    }
});

  这里单击其中同样桩并无见面看出相应的号子输出, 而是都见面来得数值5.
 即即使在绑定程序时i的价每次都未一致,
每个click处理程序最终引用的i都相同.
都相当单击事件其实产生时i的最终价值(5).

  要缓解者问题, 方法时有发生:

  1. #### 使用jQuery的$.each()函数来代表for循环:

    Ajax 21

        $(document).ready(function() {
            // Stuff to do as soon as the DOM is ready;
            $.each([0,1,2,3,4], function(index, value) {
                $('<div>Print ' + value + '</div>')
                .click(function(){
                    console.log(value);
                }).insertBefore('body');
            });
        });
    

    Ajax 22

     这是以函数的参数近似于以函数中定义之变量,
    所以每次循环的value值实际上还是不同之变量. 结果,
    每个click处理程序都针对一个不一的value变量,
    因而每次单击输出的值会与素的标签文本匹配.

  2. #### 在for循环内部, 可以定义并施行一个新函数: 即使用即时调用的函数表达式(IIFE)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $(document).ready(function() {
        for(var i=0; i<5; i++){
            (function(value){
                $('<div>Print '+ value + '</div>')
                .click(function(){
                    console.log(value);
                }).insertBefore('body');
            })(i);
        }
    });
  3. #### 使用jQuery的波系, 利用.on()方法.

    该方式接受一个目标参数, 该参数为event.data的形式传播事件处理函数中

    Ajax 23

        $(document).ready(function() {
            for(var i=0; i<5; i++){
                $('<div>Print '+ i + '</div>')
                .on('click', {value: i}, function(event){
                        console.log(event.data.value);
                }).insertBefore('body');
            }
        });
    

    Ajax 24

     因为event是函数的参数, 每次调用处理程序时她都是一个单身的实例,
    而不是以颇具调用中共享的一个值. 

3. 应内存泄露的高风险

1) 避免不测的援循环

  闭包可能会见导致在非经过意间创造引用u型拟合. 比如:

1
2
3
4
5
6
7
8
function outerFn() {
  var outerVar = {};
  function innerFn() {
    console.log(outerVar);
  }
  outerVar.fn = innerFn;
  return innerFn;
};

  这里innerFn()创建了一个引用outerVar的闭包,
而outerVar又引述了innerFn()

  而再暗藏的状态是:

1
2
3
4
5
6
7
8
function outerFn() {
  var outerVar = {};
  function innerFn() {
    <strong>console.log('hello');</strong>
  }
  outerVar.fn = innerFn;
  return innerFn;
};

  这里则innerFn()没有引用outerVar. 但是仍然没断开循环.
即使innerFn()不再引用outerVar, outerVar也还在innerFn()的封环境中.
由于闭包的缘故, 位于outerFn()中之具有变量都包含地被innerFn()所引用.
因此, 闭包会如意外地开创这些引用循环变得容易.

2) 控制DOM与JavaScript的循环

  以上这种情景便容易处理,
因为js能够检测到这些情形并当其孤立时将该清除.

  旧本子IE中是的同种植难以处理的援循环问题.
当一个循环往复中又寓DOM元素以及常规JS元素时,
IE无法释放其他一个对象—-因为当时简单像样对象是由不同的内存管理程序负责管理的.
即只有关闭浏览器, 否则这种循环在IE中永远得不顶释放. 比如:

1
2
3
4
5
6
7
$(document).ready(function() {
  var button = document.getElementById('button-1');
  button.onclick = function() {
    console.log('hello');
    return false;
  };
});

  当指定单击事件处理程序时,
就创办了一个于该封的条件中带有button变量的闭包. 而且,
现在之button也饱含一个对准闭包(onclick属性自身)的引用. 这样,
就招了当IE中不怕离开时页面也不见面释放这个循环.

  为了释放内存, 就得断开循环引用, 例如以关闭窗口关删除onclick属性.
另外, 可以望如下重写代码来避免:

1
2
3
4
5
6
7
8
function hello() {
  console.log('hello');
  return false;
}
$(document).ready(function() {
  var button = document.getElementById('button-1');
  button.onclick = hello;
});

  这样,因为hello函数不再包含button, 引用就改为了单向的(从button到hello),
不在的大循环, 就无见面招内存泄露了.

3) 用jQuery化解引用循环

1
2
3
4
5
6
7
$(document).ready(function() {
  var $button = $('#button-1');
  $button.click(function(event) {
    event.preventDefault();
    console.log('hello');
  });
});

  即使这还会创一个闭包, 并且也会见招同前一样的轮回,
但这里的代码却休见面使IE发生内存泄露.
由于jQuery考虑到了内存泄露的秘密危害,
所以它见面手动释放自己指定的有着事件处理程序. 

  另一样种植避免泄露的家伙—–使用.data()方可以像用扩展属性一样,
将消息附加到DOM元素. 由于此的数据并非直接保存在扩张属性被,
因此永远也非见面组成引用循环.

 

 http://www.cnblogs.com/haoyijing/p/5815647.html

相关文章