链式风格
也叫jQuery风格,window.jQuery()是我们提供的全局函数
jQuery(选择器)用于获取对应的元素,但它却不返回这些元素,它返回一个对象(jQuery构造出来的对象以下简称jQuery对象),这个对象可以操作对应的元素
准备工作
这是一个图片阵




接受一个选择器,根据这个选择器得到一些元素,然后返回一个对象,这个对象有方法可以操作这个元素

本来返回的应该是elements,但是这里jQuery返回的是一个对象
api是个对象,有个key叫addclass,有个value是function
简化 es6提供了新的语法
addClass() { console.log(elements) }
方法实现

让每个class="test"的元素的classList都加一个red




那继续,可不可以返回这个api呢,把return null换成return api

api调用一次addclass返回api,继续调用再返回

神奇的操作
函数如果用一个对象来调用,那么这个函数里面的this就是前面的那个对象。例如:
obj.fn(p1) 等价
obj.fn.call(obj,p1) //函数里的 this 就是 obj
那上面的this是不是就是api,那是不是可以直接返回this

结果不变
最后一下简化,我们声明了一个对象(api),然后返回了这个对象,那可不可以直接返回这个对象呢

- 总结一下:jQuery核心思想大概就是
- (1)它提供一个函数,这个函数接受一个选择器,给它这个选择器它就会获取到这个元素,但是它不会返回这个元素,它返回的是一个对象,这个对象有些方法或者函数来操作获取到的元素(用闭包来维持这个elements,只要函数存在,elements就不能消失)
- (2)通过
return this来传递.addClass前面的这个对象,每次传递调用,实现了一个链式操作,叫什么都无所谓,甚至可以直接省略
查
(一) jQuery('#xxx')
返回值并不是元素,而是一个api对象
(二)查找#xxx里的.red元素
jQuery('#xxx').find('.red')
首先find是一个函数,它接受一个selector,然后要在这个elements里找selector,这里的闭包变量是elements,有多个变量,其实是个数组,数组是不支持querySelectorAll的
搞一个新的数组储存新查找的元素,然后遍历elements的每一项

array,jQuery操作的对象是elements,就不能进行链式操作了

那return this呢

red加在了test身上,它操作的是elements,而不是array


api1是操作test的,api2是操作child的,那最后一个api1加到了child身上是怎么回事!之后改elements的时候会影响所有保留了这个api对象的引用,用的是同一个elements
重新封装一个jQuery函数,jQuery不就是获取一些元素嘛,那就把这些元素(数组)递给jQuery,让它返回一个新的api,这个api和上一个api结构一样但是保存的elements是不一样的

jQuery只接受一个选择器,这里给它的是一个数组,那就让jQuery接受数组,采用重载

- 这里做了几步操作
- 1.获取一个新的
api,由jQuery另外构造的 - 2.
jQuery不能只接受一个选择器,还要接受一个数组 - 3.重载,如果是选择器,是
elements元素,如果是数组,就把数组赋值给elements - 4.作用域的提升,在
if{}里的声明作用域只在{}的范围里,且const一旦声明不能更改
- 1.获取一个新的
简化代码

接下来操作完child再返回去操作test,使用一个end方法实现



这里的end是放到数组身上的,不是放到api身上的,api是要操作数组的

运行结果:

(九)遍历并操作
jQuery('#xxx').each(fn) 遍历并对每个元素执行fn,把遍历提前,可以直接用了

each()接受一个函数,然后遍历elements的每一项,然后传两个参数elements[i],i给fn,调用这个函数

打印出.test里的.child里的div

打个中断,用each()重写addClass和find
-
find

-
addClass

(三)获取爸爸
jQuery('#xxx').parent()


array的api,不是我们要的数组好办,增加一个print方法把elements打印出来就好了

test,对应三个body是正确的,改进一下,多个相同的爸爸只打印一个

if语句进行一个判断,就是当(父亲节点不在这个数组里===父亲节点的下标小于0===父亲节点的下标===-1)才push,否则什么都不做
(四)获取儿子
jQuery('#xxx').children()

push children会得到一个由数组组成的数组,是一个有结构的数组,而不是一个由所有child组成的数组


(...node.children) === (node.children[0],node.children[1],node.children[2]...node.children[i])

(五)获取兄弟
jQuery('#xxx').siblings()

(六)获取排行
jQuery('#xxx').index()
(七)获取弟弟
jQuery('#xxx').next()
(八)获取哥哥
jQuery('#xxx').prev()
window.$ = window.jQuery
jQuery太长了,给它一个别名,所有用到jQuery的地方都可以用$代替
下文有$的都是jQuery对象
增
$('<div><span>1</span></div>')返回值并不是新增的元素,而是api对象$('<div><span>1</span></div>').appendTo(...)appendTo可以把新增的元素放到另一个元素里
(一)获取document.body
$('body')
(二)添加小儿子
$('body').append($('<div>1</div>'))$('body').append('<div>1</div>')更方便
(三)添加大儿子
$('dody').prepend(div或$div)
(四)添加弟弟
$('#test').after(div或$div)
(五)添加哥哥
$('#test').before(div或$div)
删
$div.remove()$div.empty()
改
$div.text(?)读写文本内容$div.html(?)读写html内容$div.attr('title',?)读写属性$div.css({color:'red'})读写style$div.style更好$div.addClass('blue')/removeClass/hasClass$div.on('click',fn)$div.off('click',fn)
使用原型
最后一步把所有的对象都放到$.prototype,每个对象都只需要存储原型的地址就好了,节省内存