DOM常用操作与Demo
蓦然回首
本文算是《JavaScript DOM编程艺术》这本书的学习记录,回想起来,刚开始学前端的时候就是在实验室看这本书,后来接触了库和框架,原生的这些DOM操作就很少使用了,去年年底的时候 winter 在极客时间开了专栏:重学前端,一时间传的沸沸扬扬。现在一年多过去了,确实有必要停下脚步来回头看看。
DOM
DOM (Document Object Model),对文档的内容进行抽象和概念化的方法,主要功能就是处理网页内容。DOM包含着许多不同类型的节点,主要讨论以下三种:
- 元素节点,标签名即为元素名
- 文本节点,总是被包含在元素节点的内部
- 属性节点,对元素进行更具体的描述
获取元素
- getElementById,调用后返回一个(元素)对象
- getElementsByTagName,调用后返回一个对象数组,用document.getElementsByTagName(“li”).length查看个数,通过循环来遍历数组,也可以配合getElementById进行二次精确查询:
let ul = document.getElementById('flowers');
let items = ul.getElementsByTagName('li');
- getElementsByClassName,要指定多个类名时,用空格分隔即可,而且类名添加的顺序不会影响查询结果
元素属性
- object.getAttribute(‘title’),只能通过元素节点对象来调用
- object.setAttribute(‘src’,value),做出的修改不会反映在文档的源码中,这和DOM的工作模式有关,先加载文档静态内容,再动态刷新,后者不会影响前者。
- element.childNodes,获取元素的所有子元素,返回一个数组
- node.nodeType,元素=1 / 属性=2 / 文本=3
- node.nodeValue,改变文本节点的值
- node.firstChild
// 元素内容为: <p id = 'description '> hah </p>
// <p>元素包含的文本是它的第一个子节点
let description = document.getElementById('description');
description.firstChild.nodeValue = 'hello world'
创建元素
两种传统方法
- document.write,把字符串插入到文档中
- x.innerHTML,原有内容将被全部替换
// 元素内容为: <p id = 'description '> hah </p>
// <p>元素包含的文本是它的第一个子节点
document.write('<p> hah has been inserted</p>');
x.innerHTML = '<p> text has been repalced </p>'
DOM方法
- document.createElement(‘x’),第一步创建新元素
- node.appendChild(x),第二步把新元素插入节点树
- document.createTextNode(‘some text’),创建文本节点
// 通过appendChild把文本节点赋给<p>元素
let textContent = document.createTextNode('some text');
let para = document.getElementById('para');
para.appendChild(textContent)
- parentElement.insertBefore(newElement,targetElement),在指定元素前插入新元素。在元素后插入需要自定义函数来实现。
function insertAfter(newElement, targetElement) { //参数均为元素节点名称
//insert的使用要有parent
let parent = targetElement.parentNode;
if(parent.lastChild == targetElement){
parent.appendChild(newElement)
}else{
let xElement = targetElement.nextSibling; //目标元素的下一个兄弟元素
parent.insertBefore(newElement,xElement)
}
}
图片库DEMO
DEMO的需求是点击上方的缩略图,可以在下面显示大图和图片描述。其中图片显示区域和文字描述区域都是用上面所讲的DOM方法动态插入的
效果图:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Gallery</title>
<link rel="stylesheet" href="main.css">
<script type="text/javascript" src="main.js"></script>
</head>
<body>
<h1>赏花指南</h1>
<ul id="gallery">
<li>
<a href="./images/lihua.png" title="梨花 - 花香宜人">
<img src="./images/li-s.png" width="100px" height="100px"></a>
</li>
<li>
<a href="./images/meihua.png" title="梅花 - 花香浓郁">
<img src="./images/mei-s.png" width="100px" height="100px"></a>
</li>
<li>
<a href="./images/taohua.png" title="桃花 - 花开有叶">
<img src="./images/tao-s.png" width="100px" height="100px"></a>
</li>
<li>
<a href="./images/xinhua.png" title="杏花 - 先花后叶">
<img src="./images/xin-s.png" width="100px" height="100px"></a>
</li>
</ul>
<!--
查找:ctrl f 替换:ctrl r
-->
</body>
</html>
main.js
//自定义函数,功能为在元素后插入新元素
function insertAfter(newElement, targetElement) { //参数均为元素节点名称
//insert的使用要有parent
let parent = targetElement.parentNode;
if(parent.lastChild == targetElement){
parent.appendChild(newElement)
}else{
let xElement = targetElement.nextSibling;
parent.insertBefore(newElement,xElement)
}
}
//创建图片展示区和文字说明区并插入DOM文档中
function palceHolder() {
let picHolder = document.createElement('img');
picHolder.setAttribute('id','demo');
picHolder.setAttribute('src','./images/placeholder.jpg');
let description = document.createElement('p');
description.setAttribute('id','description');
let textContent = document.createTextNode('Choose an image');
description.appendChild(textContent);
let gallery = document.getElementById('gallery');
insertAfter(picHolder,gallery);
insertAfter(description,picHolder);
}
//绑定点击事件
function galleryEvent() {
//要进行二次get
let gallery = document.getElementById('gallery');
let liElements = gallery.getElementsByTagName('a');
for(let i=0; i<liElements.length;i++){
liElements[i].onclick = function (){
showPic(this); //this 当前的元素标签
return false;
}
}
}
//替换函数
function showPic(whichPic) {
let src = whichPic.getAttribute('href');
let picHolder = document.getElementById('demo');
picHolder.setAttribute('src',src);
let text = whichPic.getAttribute('title');
let description = document.getElementById('description');
description.firstChild.nodeValue = text;
}
window.onload = function () {
palceHolder();
galleryEvent();
}
后记
国外的技术书都是以需求为导向来讲的,产生新的需求,进而提出新的解决办法,这样比很多教材枯燥地列出各种API要好很多。
这段时间身体一直不是很好,不过最近状态有所恢复,简历写好了准备找实习,狗哥也开始找工作了,过程很艰难,希望能有好的结果吧。在校的时间也不多了,认真一点,时间是金。