一、封装两个函数
相关内容:
<ul>
<li id = "item1">选项1</li>
<li id = "item2">选项2</li>
<li id = "item3">选项3</li>
<li id = "item4">选项4</li>
<li id = "item5">选项5</li>
</ul>
1. 需求:获取到一个节点的兄弟姐妹,并放到一个伪数组里。
document.body.nextElementSibling
//获取节点的弟弟
document.body.previousElementSibling
//获取节点的哥哥
初步思路:
var allChildren = item3.parentNode.chiledren //获取节点的所有兄弟姐妹
var array = {length:0} //创建一个空对象
for(let i = 0; i < alllChildren.length; i++){ //遍历
if(allChildren[i] !== item3){
array[array.length] = allChildren[i]
array.length += 1
}
}
console.log(array) //{0:li#itme1, 1:li#itme2, 2:li#itme4, 3:li#itme5, length: 4}
- 为什么
array[array.length]
中用array.length
不用i
,因为它中间有可能跳过一个,跳过之后序号就不一致 - 为什么不用push?因为这是一个伪数组(伪数组就是哈希)。
封装函数:function 起个好用又好听的名字(){}
function getSiblings(node){ //外部输入一个节点 API
var allChildren = node.parentNode.chiledren //获取节点的所有兄弟姐妹
var array = {length:0} //创建一个空对象
for(let i = 0; i < alllChildren.length; i++){ //遍历
if(allChildren[i] !== node){
array[array.length] = allChildren[i]
array.length += 1
}
}
retuen array
}
console.log(getSiblings(item3)) //{0:li#itme1, 1:li#itme2, 2:li#itme4, 3:li#itme5, length: 4}
2. 需求:给节点添加class
,既能add
也能remove
。
初步思路:
item3.classList.add('a')
item3.classList.add('b')
item3.classList.add('c')
var classes = ['a', 'b', 'c']
classes.forEach((value) => item3.classList.add(value))
var classes = {'a':ture, 'b':false, 'c':ture}
var value = classes[key]
for(let key in classes){
if(value){
item3.classList.add(key)
}else{
item3.classList.remove(key)
}
封装函数:
function addClass(node,classes){ //classes有使用者提供
var value = classes[key]
for(let key in classes){
if(value){
node.classList.add(key)
}else{
node.classList.remove(key)
}
}
用法: addClass(item3, {'a':ture, 'b':false, 'c':ture})
优化代码:
function addClass(node,classes){
var value = classes[key]
for(let key in classes){
var methodName = value ? 'add':'remove'
node.Classlist[methodName](key)
}
}
优化守则:
- 如果出现类似的代码,就存在优化的可能。
3. 需求:有什么办法让别人知道这两个API有关联性,因为这两个API都是在操作节点
命名空间:
window.ffdom = {}
ffdom.getSibilings = getSiblings
ffdom.addClass = addClass
ffdom.getSibilings(item3)
ffdom.addClass(item3, {'a':ture, 'b':false, 'c':ture})
不命名空间的缺点:
- 别人不知道你的库叫什么
- 不知不觉把全局变量覆盖
4. 需求:我想写成item.getSibilings
Node.prototype.getSibilings = function(){
var allChildren = this.parentNode.chiledren
var array = {length:0}
for(let i = 0; i < alllChildren.length; i++){
if(allChildren[i] !== this){
array[array.length] = allChildren[i]
array.length += 1
}
}
retuen array
}
Node.prototype.addClass = function(classes){
var value = classes[key]
for(let key in classes){
var methodName = value ? 'add':'remove'
this.Classlist[methodName](key)
}
}
console.log(item3.getSiblings()) //{0:li#itme1, 1:li#itme2, 2:li#itme4, 3:li#itme5, length: 4}
- 因为我们篡改了所有Node的公有属性,添加了一个getSiblings的方法。
-
this
就是.
前面的东西(这里就是item3) - 调用call
item3.getSiblings.call(item3)
- 我自己写一个更好的Node2版本,用新的版本去调用第一个版本