jQuery 了解下
封装两个函数
<ul>
<li id="item1">item1</li>
<li id="item2">item2</li>
<li id="item3">item3</li>
<li id="item4">item4</li>
</ul>
复制代码
.a{color:red}
.b{font-size:20px}
复制代码
//获取节点的所有兄弟节点
function getSiblings(node){
let all = node.parentNode.children;
let array = {length:0};
for(let i = 0,len = all.length; i < len; i++){
if(all[i] !== node){
array[array.length] = all[i];
array.length += 1;
}
}
return array
}
//添加多个类
function addClass(node,classes){
for(let i in classes){
classes[i]?
node.classList.add(i):node.classList.remove(i)
}
}
addClass(item3,{'a':true,'b':true,'c':false})
console.log(getSiblings(item2))
复制代码
给个命名空间
如果没有命名空间会有两个缺点
- 1 别人不知道你的库叫什么
- 2 可能会覆盖全局变量
let dom = {}
dom.getSiblings = getSiblings;
dom.addClass = addClass;
//当然 你也可以 let $ = {}
dom.getSiblings(item2)
dom.addClass(item3, {a: true, b: false})
复制代码
能不能把 node 放在前面
item2.getSiblings() 这种调用方式会不会更优雅些?
方法1 扩展 Node 接口
直接在 Node.prototype 上加函数
Node.prototype.getSiblings = function(){
let all = this.parentNode.children;
let array = {length:0};
for(let i = 0,len = all.length; i < len; i++){
if(all[i] !== this){
array[array.length] = all[i];
array.length += 1;
}
}
return array
}
复制代码
上述代码中 this 指代什么?
item2.getSiblings()
Node.prototype.getSiblings.call(item2)
复制代码
- 如果你理解上面两行代码的含义,你就会明白 this 指的就是 item2
- this 就是call 的第一个参数
方法2 新的接口 BetterNode
- 上述方法有个缺点,你在Node.prototype上声明的方法很容易被别人覆盖
- 第二种叫做「无侵入」
window.jQuery = function (nodeOrSelector) {
let nodes = {}
if (typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector)
for (let i = 0; i < temp.length; i++) {
nodes[i] = temp[i]
}
nodes.length = temp.length
} else if (nodeOrSelector instanceof Node) {
nodes = {
0: nodeOrSelector,
length: 1
}
}
nodes.addClasses = function (value) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(value)
}
}
nodes.setText = function (text) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
return nodes
}
jQuery(item2).getSiblings()
jQuery('#item3').getSiblings()
jQuery('ul>li').addClasses(['a','b'])
复制代码
上述代码已经初步模拟了jQuery
- 1 输入一个参数
- 2 判断参数 为 选择器字符串 还是 dom节点
- 3 jquery 根据参数获取 dom节点 或 NodeList
- 4 执行原生DOM api
再给个缩写吧 alias
window.$ = jQuery
//jQuery('ul>li') 就可以改成
$('ul>li')
复制代码
建议
在jQuery 变量前尽量加个$用于和原生DOM对象区分
let $node = $('#item2')
$node.addClass('a');
//这样我就不会分不清node到底是jquery对象还是DOM对象
//就不会错用 node.classList.add('a')
复制代码