实现下面功能:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.blue {
color: blue
}
</style>
<script src="./test.js"></script>
</head>
<body>
<div class="p-con">
<p>111</p>
<p>222</p>
<p>333</p>
<p class="p4">444</p>
</div>
<script>
$('.p4').addClass('blue')
$('p').setText('hello world')
</script>
</body>
</html>
初级版:
// 匿名自执行函数
// 1 自执行
// 2 防止变量污染 (涉及到AO,函数自执行完后会被销毁)
(function (window) {
window.$ = jquery = function (nodeSelector) {
// 1 判断传入的是不是string
const nodes = {}
if (typeof nodeSelector !== 'string') {
throw new Error('必须输入字符串')
}
let temp = document.querySelectorAll(nodeSelector)
for (let i = 0; i < temp.length; i++) {
nodes[i] = temp[i]
}
nodes.length = temp.length
// 添加方法
nodes.addClass = function(classes) {
let className = classes.split(' ')
className.forEach(value => {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(value)
}
})
}
// 修改text
nodes.setText = function(text) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
return nodes
}
}) (window)
进阶版:
// 优化一: 优化外部结构的调用
// 优化二: 方法太散漫
// 优化三: for循环封装
const $ = jQuery = (function(){
const JqFn = function(nodeSelector) {
this.nodes = document.querySelectorAll(nodeSelector)
}
JqFn.prototype = {
each: function(callback) {
for (let i = 0; i < this.nodes.length; i++) {
callback.call(this, this.nodes[i], i)
}
},
addClass: function(classes) {
const classNameArray = classes.split(' ')
classNameArray.forEach(value => {
this.each((item, index) => {
item.classList.add(value)
})
})
},
setText: function(text) {
this.each((item, index)=> {
item.textContent = text
})
}
}
return function(selector) {
return new JqFn(selector)
}
})()
终极版:(还没学明白)
调用:
let pCon = $('.p-con')
pCon.find('p').eq(1).remove()
let aa = function() {
}
console.log($.isFunction(aa))
实现:
let $ = jQuery = (function(window) {
// dom存储
function Query (dom, selector) {
let i, len = dom ? dom.length : 0
for (i = 0; i < len; i++) this[i] = dom[i]
this.length = len
this.selector = selector || ''
return this
}
// 生成jquery对象
function Z (elements, selector) {
return Query.call(this, elements, selector)
}
// 具体dom查找
function qsa(element, selector) {
return element.querySelectorAll(selector)
}
Z.prototype = {
each(callback) {
[].every.call(this,function(el, index) {
return callback.call(el, index, el) !== false
})
},
find(selector) {
let doms = []
this.each(function(index, el) {
let childs = this.querySelectorAll(selector)
doms.push(...childs)
})
return new Z(doms, selector)
},
eq(i) {
let doms = []
this.each(function(index, el) {
if (i === index) {
doms.push(this)
}
})
return new Z(doms, this.selector)
},
remove() {
this.each(function(index, el) {
this.remove()
})
}
}
function isFunction(value) {
return typeof value == 'function'
}
function $(nodeSelector) {
let doms = qsa(document, nodeSelector)
return new Z(doms, nodeSelector)
}
$.isFunction = isFunction
return $
})()