用js自己封装一个jQueryAPI要能实现以下要求:
var $div = $('div')
$div.addClass('red') // 需求1:可将所有 div 的 class 添加一个 red
$div.setText('hi') // 需求2:可将所有 div 的 textContent 变为 hi
html部分代码如下
<body>
<div id="wow1">1</div>
<div id="wow2">2</div>
<div id="wow3">3</div>
<div id="wow4">4</div>
</body>
内容要点:
- 首先写一个函数让其能够通过传参找到节点(组),由于不知道传参是什么,所以要人为分类,可将其分为传入的节点或者是字符串,字符串的话用dom里querySelcetorAll方法.并且为了二者统一,将返回一个伪数组.
tips:在拷贝一个伪数组给另一个伪数组时要依次遍历赋值,并且不能忘了长度.
function findNodes(nodeOrSelector){
var nodes={}//这里先声明一个伪数组,因为传参获取到的不是伪数组,所以这里统一标准,让其都成为伪数组
if(typeof nodeOrSelector==='string'){ //判断传参是否是字符串,如果是用querySlectorAll方法
var temp = document.querySelectorAll(nodeOrSelector) //生成临时伪数组,只是为了复制给nodes
for(let i=0;i<temp.length;i++){ //将一个(伪)数组里的值复制给另一个(伪)数组的值常用方法
nodes[i]=temp[i]
}
nodes.length=temp.length //长度也复制
}else if(nodeOrSelector instanceof Node){ //判断传参是否是节点,如果是,直接传入nodes
nodes={ //为了统一让nodes成为了伪数组
0:nodeOrSelector,
length:1
}
return nodes //这里统一返回一个伪数组
}
- 在第一个函数的内部再写一个函数通过遍历nodes来实现需求1,同理并不知道传参是什么,所以要分类,
传入的是数组代表需要添加多个类,这时需要先遍历数组,再在遍历里遍历依次赋值给选取的多个节点(有点绕),可以理解为循环嵌套,并在最后需要将nodes传出去,这里函数和外面的nodes形成了一个闭包.
tips:数组的foreach用法array.forEach(function(value,key){执行内容})
value和key对应数组的value和key
function addClass(addingClass){
if(typeof addingClass==='string'){
for(let i=0;i<nodes.length;i++){
nodes[i].classList.add(addingClass)
}
}else if(addingClass instanceof Array){
addingClass.forEach((value)=>{
for(let i=0;i<nodes.length;i++){
nodes[i].classList.add(value)
}
})
}else{alert('请在addClass()里传入字符或数组')}
return nodes
}
- 在第一个函数的内部再写一个函数通过遍历nodes来实现需求2,最后将nodes传出去,这里函数和其作用域外面的nodes形成了闭包.
function setContent(content){
for(let i=0;i<nodes.length;i++){
nodes[i].textContent=content
}
return nodes
}
- 将上面三组函数合并到一起,
tips:函数内部可以返回多个函数,实质是返回的一个hash表,注意中间需要逗号隔开
function a(){
return{
b:function(){},
c:function(){}
}
}
以下是合并后的代码
//首先在全局对象window内构建内部函数
var myjQuery = function(nodeOrSelector) {
var nodes={}
if(typeof nodeOrSelector==='string'){ //判断传参是否是字符串,如果是用querySlectorAll方法
var 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
nodes={ //因为为了统一让nodes成为了伪数组
0:nodeOrSelector,
length:1
}
}
return{
addClass:function (addingClass){
if(typeof addingClass==='string'){
for(let i=0;i<nodes.length;i++){
nodes[i].classList.add(addingClass)
}
}else if(addingClass instanceof Array){
addingClass.forEach((value)=>{
for(let i=0;i<nodes.length;i++){
nodes[i].classList.add(value)
}
})
}
else{alert('请在addClass()里传入字符或数组')}
return nodes
} ,
setText:function (content){
for(let i=0;i<nodes.length;i++){
nodes[i].textContent=content
}
return nodes
}
}
}
- 由于要用
var $div = $('div')
的方式传参,所以需要用alias方式,所以还需写上
window.$=myjQuery
代码:http://js.jirengu.com/keleg/1/edit?html,js,output
网友评论