1. 配置环境
在终端用 yarn 安装 parcel: yarn global add parcel
启动服务器: parcel src/index.html
2. 对象风格(命名空间风格)封装 DOM 操作
window.dom
是我们提供的全局对象,在src目录中创建index.html, dom.js 和 main.js
3. 功能:获取 / 查找节点
(1) 获取标签
- dom.js 中调用
document.querySelectorAll
获取所有标签
find(selector){
return document.querySelectorAll(selector)
} // 不管选择器里有几个元素,全部都返回
- main.js 中运行
dom.find
,获取所有div id为test的元素,并打印出这个div
const testDiv = dom.find('#test')[0]
console.log(testDiv)
效果图⬇️
- 适配
在 dom.js 中设定 (scope || document)
如果有scope
的话,就在scope
中调用querySelectorAll
,如果没有就在document
中调用。
find(selector, scope){
return (scope || document).querySelectorAll(selector)
}
例如在index.html中
<div id="test">
<span>test</span>
<p class="red">红色的test</p>
</div>
<div id="test2">
<span>test2</span>
<p class="red">红色的test2</p>
</div>
更新main.js,在 class='red'
的元素中,只获取id名为test2的,不获取test
const testDiv = dom.find('#test')[0]
const test2 = dom.find('#test2')[0]
dom.find('.red', test2)
console.log(dom.find('.red', test2)[0])
控制台打印内容如下 ⬇️
(2) 获取父 / 子元素(parent/children)
- dom.js
parent(node){
return node.parentNode
} // 获取父元素
children(node){
return node.children
} // 获取子元素
- main.js
console.log(dom.parent(test));
获取到了 test 的父元素
(3) 获取所有兄弟姐妹元素(siblings)
- dom.js 中调用
.parentNode.children
查找父母的所有孩子(包括自己),然后filter
掉自己,得到所有兄弟姐妹
siblings(node){
return Array.from(node.parentNode.children)
.filter(n => n !== node)
}
- 在 index.html 中添加
<div id="family">
<div id="bro">bro</div>
<div id="sis">sis</div>
<div id="target">target</div>
</div>
- 在 main.js 中获取 target 的兄弟姐妹,并打印出他们如图 ⬇️
const findSib = dom.siblings(dom.find('#target')[0])
console.log(findSib)
(3) 获取同父母的上一个 / 下一个元素
- dom.js 中使用
.nextSibling
获取节点类型为文本(nodeType === 3
)的元素,如果节点存在下一个 / 存在弟弟,且类型为文本,则返回该节点,并继续找下一个弟弟;查找上一个节点同理,使用.previousSibling
next(node){
let x = node.nextSibling
while(x && x.nodeType === 3){
x = x.nextSibling
}
return x
},
previous(node){
let x = node.previousSibling
while(x && x.nodeType === 3){
x = x.previousSibling
}
return x
}
其他节点类型的对应数字,详见 MDN文档-节点类型常量
- main.js 中寻找sis的下一个元素
const preSib = dom.previous(dom.find('#sis')[0])
console.log(preSib)
const nextSib2 = dom.next(dom.find('#sis')[0])
console.log(nextSib2)
如图,控制台打印出 sis 上面的 bro 和下面的 target ⬇️
- ⚠️ 这里不能直接用
.nextSibling
,因为节点后面有回车,返回的是文本 ⬇️
// dom.js ❌ 实例
next(node){
return node.nextSibling
}
此时返回的是文本 #text
(4) 遍历所有节点
- 在 index.html 中新增
div
<div id="travel">
<div id="t1">杭州~</div>
<div id="t2">西雅图~</div>
<div id="t3">慕尼黑~</div>
</div>
- dom.js 中用
.call()
调用并返回 nodeList (this的位置用null占位)
each(nodeList, fn){
for(let i = 0; i< nodeList.length; i++){
fn.call(null, nodeList[i])
}
}
- main.js 中对于找到 travel 的所有子元素,对其进行
dom.each
操作遍历,将style
属性更改为color: blue'
const t = dom.find('#travel')[0]
dom.each(dom.children(t), (n)=> dom.style(n, 'color', 'blue'))
得到的页面效果如图 ⬇️
(5) 获取排名
- dom.js
index(node){
const list = dom.children(node.parentNode)
let i
for(i=0; i<list.length; i++){
if(list[i] === node){
break
}
}
return i
}
- main.js 中 调用
dom.find
获取 sis 的排名
const sis = dom.find('#sis')[0]
console.log(dom.index(sis));
如图⬇️ , 所以 sis 的排名是第2名 (第一名index为0,第二名为1,etc.)
手写 DOM 库系列结束,完结撒花~
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!