Web前端+移动端工程师全栈教程

06-老马jQuery教程-jQuery高级

2017-12-05  本文已影响572人  IT老马

1.jQuery原型对象解密

jQuery里面的大部分API都是在jQuery的原型对象上定义的。jQuery源码中对原型对象做了简写的处理。也就是说:jQuery.fn === jQuery.prototype,参考jQuery源码:

...
jQuery.fn = jQuery.prototype = {

// The current version of jQuery being used
jquery: version,

constructor: jQuery,

// The default length of a jQuery object is 0
length: 0,

toArray: function() {
  return slice.call( this );
},
...

1.1 each函数

jQuery的包装对象封装了each(callback)方法,以每一个匹配的元素作为上下文来执行一个函数。
意味着,每次执行传递进来的函数时,函数中的this关键字都指向一个不同的DOM元素(每次都是一个不同的匹配元素)。而且,在每次执行函数时,都会给函数传递一个表示作为执行环境的元素在匹配的元素集合中所处位置的数字值作为参数(从零开始的整型)。 返回 'false' 将停止循环 (就像在普通的循环中使用 'break')。返回 'true' 跳至下一个循环(就像在普通的循环中使用'continue')。

实例:

// 迭代两个图像,并设置它们的 src 属性。注意:此处 this 指代的是 DOM 对象而非 jQuery 对象。
// HTML 代码:
// <img/><img/>
$("img").each(function(i){
  this.src = "test" + i + ".jpg";
  // this 指向当前的变量的dom对象。 i是当前dom对象在选择器返回数组中的索引。
 });

1.2 获取元素的个数

两种方法可以获取选择器匹配的元素的个数。

第一种方法:$('p').size();
第二种方法:$('p').length

以上两种方法都可以。推荐使用length属性

1.3 其他属性和方法

属性/方法名 用法 介绍
selector $('p').selector 返回选择器的字符串
get() $('p').get(); 返回所有的选择的dom对象的集合
get(index) $('p').get(1); 返回第2个dom对象,索引从0开始
toArray() $('p').toArray(); 把jQuery集合中所有DOM元素恢复成一个数组。

上课代码

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>

<script src="./lib/jquery-1.12.4.js"></script>
<script>
  // 数组的方法forEach, ie9+ 
  var arr = ['a', 'b', 3, 4];
  // value数组的元素, index数组元素的索引
  arr.forEach(function(value, index) {
    console.log('index:',index, 'value',value)
  });

  //jQuery原型上提供了each
  $(function() {
    // jQuery.fn上提供了each方法,类似for循环遍历。推荐使用each替代for
    // 参数:第一个参数是:索引,第二个参数是dom元素。
    $('li').each(function(index, elem) {
      console.log(index, elem);
    });

    // jQuery原型:获取元素个数。
    console.log('size:', $('li').size())
    console.log('length:', $('li').length)
    console.log($('li').get());
  });
</script>

2.jQuery构造函数解密

2.1 构造函数的each方法

2.2 构造函数的map方法

2.3 数组的过滤方法grep

2.4 转换数组方法jQuery.makeArray

2.5 数组包含校验inArray

2.6 合并数组方法merge

2.7 数组去重unique

2.8 jQuery构造函数的扩展对象方法(继承)

上课代码

// 深拷贝
var target = {name: 'laoma'};
var obj1 = {age: 18, cellphone: '18911865673', mail: 'malun666@126.com'};
var p1 = {k: 123, m: 'abc'};
var obj2 = {run: function() { console.log(1); }, p: p1};

var newObj = jQuery.extend(true, target, obj1, obj2);
console.log(newObj, target);
console.log(newObj === target)

// console.log(newObj.p === p1);
console.log(newObj.p.k); //123
p1.k = 444; //newObj.p.k
console.log(newObj.p.k); //123
console.log('p1.k', p1.k); //444

2.9 其他构造函数上的方法和属性

属性名 实例 说明
noop var f = jQuery.noop; 一个空函数
isArray $.isArray([1,3,4]) 测试对象是否为数组。
isFunction jQuery.isFunction(obj) 测试对象是否为函数。
isNumeric jQuery.isNumeric(value) 确定它的参数是否是一个数字。
isWindow jQuery.isWindow(obj) 测试对象是否是窗口
error jQuery.error(message) 接受一个字符串,并且直接抛出一个包含这个字符串的异常
trim jQuery.trim(str) 去掉字符串起始和结尾的空格

3.链式编程和隐式迭代

3.1 链式编程

由于大部分jQuery的api方法内部返回值都是jQuery的包装对象自身。所以我们可以在jQuery的api调用之后继续调用jQuery的方法,这样就称作是链式编程。

例如代码:

$('#p1').css('color', 'red').height(200).hide('slow');
// 等价于
$('#p1').css('color', 'red');
$('#p1').height(200);
$('#p1').hide('slow');

由于css方法、height、hide方法都返回jQuery包装对象自身。所以就可以继续链式调用。

链式编程的原理

//链式编程的原理:对象调用了方法后,方法返回当前对象。
var cat = {
  run: function() {
    console.log('runing');
    return this; // 核心:方法内部又把当前对象返回了。
  },
  sayHi: function() {
    console.log('hi');
    return this;
  },
  jump: function() {
    console.log('jump');
    return this;
  }
};

cat.run().sayHi().jump(); 

有些方法可以破坏链式的结构,比如:
nextAll(),prevAll(),sibilings(),find(),children(),parent(),parents()...

如果想回到最近一次破坏链式结构之前的代码可以使用end方法。

$('#p1').nextAll().hide().end().css('color', 'red');

3.2 隐式迭代

jQuery包装对象本身就是一个伪数组,匹配的元素有多个的时候,要做设置操作的时候,jQuery内部会隐式的变量所有的匹配元素调用设置操作,所以称为隐式迭代。

评分控件案例

<ul class="list">
  <li>☆</li>
  <li>☆</li>
  <li>☆</li>
  <li>☆</li>
  <li>☆</li>
</ul>
<script src="./lib/jquery-1.12.4.js"></script>
<script>
  $(function() {
    // 第一个效果: 当鼠标移入 五角星时候。之前的五角星和自己都变成实心的五角星
    $('.list li').hover(function(e) {
      // 鼠标移入:当鼠标移入 五角星时候。之前的五角星和自己都变成实心的五角星
      $(this).text('★').prevAll().text('★'); // 隐式迭代。
    }, function(e) {
      // 鼠标移出: 把自己变成空心五角星,而且后面的也都变成空心五角星
      $(this).text('☆').nextAll().text('☆');
    }).on('click', function(e) {
      // 点击之后,记录当前点击的是谁
      $(this).addClass('cur').siblings().removeClass('cur');
    });

    // 给整个ul标签绑定一个mouseleave事件。
    $('.list').on('mouseleave', function(e) {
      // 拿到当前 cur 类的li标签。
      $('.list li.cur').text('★')
          .prevAll().text('★').   // 前面的节点都设置成实心
        end().nextAll().text('☆');// 点击元素后面的节点设置成空心
    });
  });
</script>

4.jQuery的插件封装

4.1 给jQuery包装对象扩展方法属性

(function(jQuery) {
  jQuery.fn.logText = function() {
    console.log(this.text());
  };
})(jQuery);

4.2 给构造函数扩展方法和属性

$.extend({
    log: function(message) {
        var now = new Date(),
            y = now.getFullYear(),
            m = now.getMonth() + 1, //!JavaScript中月分是从0开始的
            d = now.getDate(),
            h = now.getHours(),
            min = now.getMinutes(),
            s = now.getSeconds(),
            time = y + '/' + m + '/' + d + ' ' + h + ':' + min + ':' + s;
        console.log(time + ' My App: ' + message);
    }
});

$.log('initializing...'); //调用
(function(jQuery) {
  jQuery.appName = 'laoma Extend';
})(jQuery);

上课案例:自定义插件演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>列表切换案例</title>
  <style>
    html, body, div,  ul, li {
      padding: 0;
      margin: 0;
    }

    ul, ol {
      list-style: none;
    }

    .tab-wrap {
      border: 1px solid #ccc;
      width: 606px;
      height: 340px;
      overflow: hidden;
    }

    .tab-wrap .tab-hd {
      overflow: hidden;
    }

    .tab-wrap .tab-hd .tab-hd-item {
      float: left;
      width: 200px;
      height: 30px;
      line-height: 30px;
      background-color: #f0f0f0;
      border: 1px solid #ccc;
      text-align: center;
      cursor: pointer;
    }

    .tab-wrap .tab-hd .tab-hd-item:hover {
      background-color: #fafafa;
    }

    .tab-wrap .tab-bd .tab-bd-item {
      width: 600px;
      display: none;
    }

    .tab-wrap .tab-bd .on {
      display: block;
    }
  </style>
</head>
<body>
  <div class="tab-wrap">
    <ul class="tab-hd">
      <li class="tab-hd-item">商品1</li>
      <li class="tab-hd-item">商品2</li>
      <li class="tab-hd-item">商品3</li>
    </ul>

    <ul class="tab-bd">
      <li class="tab-bd-item on">
        <img src="./img/1.png" alt="">
      </li>
      <li class="tab-bd-item">
        <img src="./img/2.png" alt="">
      </li>
      <li class="tab-bd-item">
        <img src="./img/3.png" width="600" height="300" alt="">
      </li>
    </ul>
  </div>
  <script src="./lib/jquery-1.12.4.js"></script>
  <script>
    (function ($) {
      $.fn.lmTab = function () {
        var $hdItems = $(this).find('.tab-hd-item'),
            $bdItems = $(this).find('.tab-bd-item');
        $hdItems.on('mouseenter', function (e) {
          // 拿到当前鼠标移入的hd部分li的索引。
          var index = $hdItems.index(this); // 获取元素的索引。
          var bdLiDom = $bdItems.get(index); // 可以获得第index个元素的dom对象。
          $(bdLiDom).addClass('on').siblings().removeClass('on');
        });
      };
    })(jQuery);


    $(function () {
      // 自定义插件
      $('.tab-wrap').lmTab();  
    });
  </script>
</body>
</html>

5.jQuery常用插件

.....


对应视频地址:http://qtxh.ke.qq.com
老马qq: 515154084
老马微信:请扫码

微信:Flydragon_malun
上一篇下一篇

猜你喜欢

热点阅读