jQuery 通过 return this 的操作,将调用 xxx() 函数的对象再次返回,使得下一次能够继续调用
但是这样有一个问题,比如 $('div').find('h3').parent() 操作,其中的 parent() 作用的并不是 h3 而是 div ,原因在于 find('h3') 返回了 this ,即与 div 有关联的对象,而不是与 h3 关联的对象。
本来想是以修改 elements 来使得链式操作能够正常进行,但是这样同样也会出现问题,比如
let temp1 = $('div')
let temp2 = temp1.find('h3')
temp1.find('h4')
这时候再对 temp1 进行操作,那么操作的就不是 div ,而是 h3 ,其原因就在于所有返回的对象关联的都是同一个 elements ,一旦通过一个对象修改了 elements ,那么其他对象访问的 elements 也会是被修改过后的 elements 。为对应更新元素,jQuery 有了如下解决方法
window.$ = window.jQuery = function(parameters) {
...
return {
find(selector) {
let array = []
for (let i = 0; i < elements.length; i ++) {
array.push(...Array.from(elements[i].querySelectorAll(selector)))
}
return $(array)
}
}
}
letlet elements
if (typeof parameters === 'string') {
elements = document.querySelectorAll(parameters)
} else if (parameters instanceof Array) {
elements = parameters
}
回退一步结果集
jQuery 中有一个 end() 函数,可以使得结果集回退一步,例如:
$('div').find('.hello').addClass('world').end().addClass('helloworld')
// 为 div 中的类名为 hello 的元素添加 world 类名,然后为 div 添加 helloworld 类名
end() 的实现需要其他函数的配合,例如,需要更换结果集的时候,需要将原结果集添加到新结果集中
find(selector) {
let array = []
for (let i = 0; i < elements.length; i ++) {
array.push(...Array.from(elements[i].querySelectorAll(selector)))
}
array.oldApi = this
return $(array)
}
jQuery 神奇操作
简化操作
曾经写过
DOM
库,具体是将包括操作的函数的对象放在了window
对象的dom
属性中,调用dom
库获取元素时可以直接使用dom.xxx(parameters)
就可以,而调用jQuery
库获取元素竟然只需要使用$(parameters)
即可,相比之下更加简洁jQuery
通过函数对传入的parameters
进行一定的处理得到elements
API
对象API
对象中有对elements
的引用,导致elements
并不会被js
的垃圾回收机制回收掉,从而在保留获取指定元素的前提下获得各种操作dom
的方法链式操作
jQuery
可以做到$('div').find('h3').parent()
,找到div
元素中的h3
元素的父元素。在前一个.xxx()
后可以继续使用.xxx()
对对象进行操作jQuery
通过return this
的操作,将调用xxx()
函数的对象再次返回,使得下一次能够继续调用但是这样有一个问题,比如
$('div').find('h3').parent()
操作,其中的parent()
作用的并不是h3
而是div
,原因在于find('h3')
返回了this
,即与div
有关联的对象,而不是与h3
关联的对象。本来想是以修改
elements
来使得链式操作能够正常进行,但是这样同样也会出现问题,比如这时候再对
temp1
进行操作,那么操作的就不是div
,而是h3
,其原因就在于所有返回的对象关联的都是同一个elements
,一旦通过一个对象修改了elements
,那么其他对象访问的elements
也会是被修改过后的elements
。为对应更新元素,jQuery
有了如下解决方法这里可以发现传入
$(parameters)
的参数已经不是一个普通的String
了,而是一个Array
,故需要对parameters
进一步处理回退一步结果集
jQuery
中有一个end()
函数,可以使得结果集回退一步,例如:end()
的实现需要其他函数的配合,例如,需要更换结果集的时候,需要将原结果集添加到新结果集中如此的话,
end()
函数就更好实现了原型链
上述的实现其实有一个很大的问题,每调用一次函数都会返回一个全新而内容又完全相同的对象,极大程度的浪费了内存,但是利用
js
的原型链可以极好的解决这个问题模仿 jQuery 实现一个小 dom 库
通俗易懂版
2333 版