jQuery思想运用

135 阅读2分钟

全世界大约有80~90%的网站直接或间接地使用了jQuery。鉴于它如此流行,所以每一个入门JavaScript的前端工程师都应该了解和学习它。

jQuery能帮我们干这些事情:

  • 消除浏览器差异:你不需要自己写冗长的代码来针对不同的浏览器来绑定事件,编写AJAX等代码;

  • 简洁的操作DOM的方法:写$('#test')肯定比document.getElementById('test')来得简洁;

  • 轻松实现动画、修改CSS等各种操作。

jQuery的思想

  • jQuery的基本设计思想就是:选择某个网页元素,对其进行某种操作。

  • 选取元素,对其操作

选择网页元素

选择器是jQuery的核心。一个选择器写出来类似$('#dom-id')。

  • 为什么会出现jQuery选择器?看下面的代码
 // 按ID查找:
var a = document.getElementById('dom-id');

// 按tag查找:
var divs = document.getElementsByTagName('div');

// 查找<p class="red">:
var ps = document.getElementsByTagName('p');
// 过滤出class="red":
// TODO:

// 查找<table class="green">里面的所有<tr>:
var table = ...
for (var i=0; i<table.children; i++) {
    // TODO: 过滤出<tr>
}
  • 这些代码实在太繁琐了
  • jQuery的选择器就是帮助我们快速定位到一个或多个DOM节点。
  $(document) //选择整个文档对象

  $('#myId') //选择ID为myId的网页元素

  $('div.myClass') // 选择class为myClass的div元素

  $('input[name=first]') // 选择name属性等于first的input元素

改变结果集

jQuery设计思想之二,就是提供各种强大的过滤器,对结果集进行筛选,缩小选择结果。

 $('div').has('p'); // 选择包含p元素的div元素

  $('div').not('.myClass'); //选择class不等于myClass的div元素

  $('div').filter('.myClass'); //选择class等于myClass的div元素

  $('div').first(); //选择第1个div元素

  $('div').eq(5); //选择第6个div元素

链式操作思想

链式操作: 选中网页元素以后,可以对它进行一系列操作,并且所有操作可以连接在一起,以链条的形式写出来.

$('div')
  .find('h3')
  .addClass('red')
  .text('hi 我是新加的内容');
// 找到所有的div元素,在所有的div元素里找到h3标签,给h3标签增加'red'类,并且替换文本内容

实现思想: 原理在于于每一步的jQuery操作,返回的都是一个新的jQuery对象。

  • 代码:
  find(selector) {
    let array = []
    for (let i = 0; i < this.elements.length; i++) {
      const elements2 = Array.from(this.elements[i]
        .querySelectorAll(selector))
      array = array.concat(elements2)
    }
    //  将当前的对象存放在array里
    array.oldThis = this
    // 然后在返回一个新的jQuery对象, 防止污染
    // 如果直接把数组赋值给elements返回的话,会污染到addClass方法
    return jQuery(array)
  },

getter, setter设计模式

jQuery的设计思想之三就是使用同一个函数,来完成取值(getter)和赋值(setter)。到底是取值还是赋值,由函数的参数决定,这也是函数的重载。

$('h1').html(); //html()没有参数,表示取出h1的值

$('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值

把方法放在原型上的实现思想

  • 为什么方法放在原型上?
    • 把方法都移到jQuery原型身上,这样每次创建一个jQuery对象时,就不会再去开一块内存存放方法了。
    • 所有创建的jQuery对象中的方法都放在原型上,这样省内存。
window.$ = window.jQuery = function (selectorOrArray) {
  let elements = null
  if (typeof selectorOrArray === 'string') {
    elements = document.querySelectorAll(selectorOrArray)
  } else if (selectorOrArray instanceof Array) {
    elements = selectorOrArray
  }

  const api = Object.create(jQuery.prototype) // 创建一个对象,这个对象的__proto__为括号里的
  // Object.assign方法就是把{}中的对象都赋值给api
  // 相当于 api.elements = elements
  Object.assign(api, {
    elements: elements,
    // 把oldThis 存在这个对象里。 要不然别的方法访问不到
    // find中返回的是新的jQuery对象,而selectorOrArray是有oldThis这个属性的
    oldThis: selectorOrArray.oldThis,
  })
  return api
}

jQuery.prototype = {
  constructor: jQuery,
  addClass(className) {
    for (let i = 0; i < this.elements.length; i++) {
      this.elements[i].classList.add(className)
    }
    // 要求返回this 的原因是因为能够链式操作
    return this
  },
  find(selector) {},
  end() {},
  each(fn) {},
  print() {},
  parent() {},
  children() {},
  siblings() {},
  next() {,
  prev() {},
}

常见API

  • $('div').append(选择器/ jQuery对象) 在div的子元素里,在最后一个位置添加元素,通俗来说就是加一个小儿子
  • $('<h2>哈哈哈</h2>').appendTo(选择器/ jQuery对象) 在选择器选中的元素的子元素里,从尾部添加“哈哈哈”
  • $('div').prepend('h2') 在div的所有子元素里,从头插入h2,通俗来说就是加一个大儿子
  • 类似的还有$('h2').prependTo($('div'))
  • $('#test').after($div) 加一个弟弟
  • $('#test').before($div) 加一个哥哥

  • $div.remove()
  • $div.empty()

查改

$div.text(?) 读写文本内容 div.html(?) 读写HTML内容 $div.css({'color': 'red'}) 读写css $div.on('click', fn) $div.off('click', fn)

jQuery是构造函数吗?

  • jQuery是一个不需要加new的构造函数
  • jQuery不是常规上的够着函数
  • 这是因为jQuery用了一些技巧