- docoment object model 文档对象模型
- DOM操作
- 1.1【常见的获取DOM的方式】
- 1)getElementById:通过元素的id获取元素
- 2)[context].getElementsByTagName:HTMLCollection 元素集合【类数组集合】
- 在特定的上下文中,通过标签名,获取一组元素。
- 3) [context].getElementsByCalssName:通过类名获取元素集合【类数组集合】
- 4)document.getElementsByName:通过name名字获取一组 【节点集合 类数组】
- 5)[context].querySelector(“选择器”)
- 6) [context】.querySelectorAll(“选择器”) 【节点集合 类数组】
- 7)document.head
- 8) document.body
- 9) document.documentElement
- 1.2 【练习题】
- 2.【修改DOM元素的样式】
- 3.【给DOM元素设置内容innerHTML/innerText/value】
- 4【节点】
- 5【节点的关系关系属性】
- 6【dom 的增删改】
- 7.【练习题】
- 3.获取当前节点的所有元素哥哥节点 兼容所有浏览器
- 4获取所有的弟弟节点
- 5.获取所有的兄弟节点
- 6.获取当前节点的索引 他在所有兄弟中的排行
docoment object model 文档对象模型
DOM操作
【dom树】:浏览器在加载页面的时候,首先就是dom的结构计算,它形式就像是一颗大树,有很多的分支,所以被称为 “dom tree”
1.1【常见的获取DOM的方式】
//ID=>submit 默认不写 docoument 浏览器可以渲染<br />
<body>
<button id="submit">更改Body的背景眼色</button>
</body>
<script>
console.log(submit);
</script>
</html>
1)getElementById:通过元素的id获取元素
//DOM元素对象
document.getElementById("box");
【document】:
document 是上下文,限制范围的意思:在哪个范围下的 id名字是box的这个元素,不过这个上下文只能是 document
【id名字唯一性】:
id名字是唯一的,一个document文档中不能同时出现多个相同的id名字,如果设置了多个相同的id,只能获取到第一个。
[兼容性注意]:不要让name 和id的名字一样。因为在ie6-ie7 的时候,如果设置了name属性,通过id也可以获取到
<body>
<input type="text" name="text">
</body>
</html>
<script>
console.log(document.getElementById("text"));
// 在ie6或者ie7的时候可以获取到
</script>
2)[context].getElementsByTagName:HTMLCollection 元素集合【类数组集合】
在特定的上下文中,通过标签名,获取一组元素。
- 得到的是一个集合,如果想要操作其中的某一项,可以基于索引获取。
var omain=document.getElementById("main");
var olis=omain.getElementsByTagName("li");
// 想要获取到第二个li:olis[1]
3) [context].getElementsByCalssName:通过类名获取元素集合【类数组集合】
- 此方法在ie6—ie8下不兼容
4)document.getElementsByName:通过name名字获取一组 【节点集合 类数组】
- 它的上下文也只能是document
- 另外,正常的规范中,咱们只会给表单元素起name值,如果给其它元素设置name,在ie9以下版本浏览器不兼容,是获取不到的,所以为了这种情况,咱们以后养成习惯,只给表单元素用name,非表单元素不用name
5)[context].querySelector(“选择器”)
通过选择器获取指定的元素,即使匹配的有多个,也只会对第一个起作用,获取到的是一个对象(给咱们平时写样式时候写选择器是一样的)
<div class="main">
<div class="box1"></div>
</div>
document.querySlector(".main>div")
6) [context】.querySelectorAll(“选择器”) 【节点集合 类数组】
通过指定的选择器获取一组节点集合
注意:querySelector 和querySelector 在ie6-ie8 下不兼容
7)document.head
获取Head元素对象
8) document.body
获取body元素对象
9) document.documentElement
【需求:】获取一屏幕的宽度或者高度,兼容所有的浏览器
// 获取一屏幕的高度
var vH=document.documnentElement.clientHeight || document.body.clientHeight;
// 偶去一屏幕的宽度
var vW=document.documentElement.clientWidth || document.body.clientWidth;
1.2 【练习题】
获取页面中所有name属性值为 “hehe” 的元素标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
</style>
</head>
<body>
<div class="box1">
<input type="text" name="he1">
</div>
<input class="box1" name="he1">
</body>
</html>
<script>
function getElementsByName(value){
var allTag=document.getElementsByTagName("*");
var names=[];
for(var i=0;i<allTag.length;i++){
var item=allTag[i];
if(item.name==value){
names.push(item);
}
}
return names;
}
var ary=getElementsByName("he1")
</script>
2.【修改DOM元素的样式】
1.元素.style.xxx 修改(获取)当前元素的行内样式
操作的都是行内样式,哪怕把样式写在样式表中 只要没有写在行内上,也获取不到
2.元素.className
存储/操作元素的样式类名,基于样式类的管理给予其不同的样式
<!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>
.active{
color:red;
background: pink;
}
</style>
</head>
<body>
<div class="box">
<h2 class="title"></h2>
<ul class="item" id="itembox">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<script>
var itembox=document.getElementById("itembox"),
lilist=itembox.getElementsByTagName("li");
// console.dir(itembox); =>是一个DOM元素对象
// console.dir(lilist);=>是一个元素集合
// ======》设置样式
/* 方式1 */
// itembox.style.color='Red';
// itembox.style.backgroundColor='pink';
//简写
//itembox.style.cssText=`color:red; background: pink;`;
//或者样式类
//itembox.className='active';//这样操作会把之前的样式类名覆盖
//itembox.className+=' active';//这样也可以 加空格区分
itembox.classList.add('active');//向指定样式集合中新增一个样式 兼容差
</script>
</body>
</html>
3.【给DOM元素设置内容innerHTML/innerText/value】
- innerHTML:存储当前元素的所有内容,包含标签
- innerText:存储当前元素的文本内容
- value: 操作表单元素
4【节点】
一个文档中包含的所有内容都是节点node
元素节点 | 文本节点 | 注释节点 | 文档节点 | |
---|---|---|---|---|
nodeType | 1 | 3 | 8 | 9 |
nodeName | 大写的标签名 | “#text” | “#comment” | “#document” |
nodeValue | null | 文本内容 | 注释的内容 | null |
1)元素节点 [“HTML标签”]
- nodeType:1
- nodeName:”大写的标签名”
- nodeValue:null ```
<a name="lFZyH"></a>
### 2)文本节点 [文本内容/空格/换行]
- nodeType:3
- nodeName:"#text"
- nodeValue:文本内容
- 在标准浏览器中,换行和空格也属于文本节点
```
var res=a1.childNodes[0];
console.log(res.nodeType);//3
console.log(res.nodeValue);//"百度";
console.log(res.nodeName);//"#text";
3)注释节点 “注释的内容”
- nodeType:8
- nodeName:”#comment”
- nodeValue:注释的内容
<a href="http://www.baidu.com" id="a1"> <!--a标签 --> 百度 </a>
a1.childNodes; //NodeList(3) [text, comment, text]
a1.childNodes[1].nodeName;//"#comment"
a1.childNodes[1].nodeType;//8
a1.childNodes[1].nodeValue;//"a标签 "
4)文档节点 “document”
- nodeType:9
- nodeName:”#document”
nodeValue:null
document.nodeType; document.nodeName document.nodeValue;
5)属性节点
nodeType:2
- nodeName:属性名
- nodeValue:属性值
<a href="http://www.baidu.com" id="a1">百度</a>
var a1=a1.getAttributeNode("href");// 获取属性节点 console.log(a1.nodeType);//2 console.log(a1.nodeName);//"href"; 属性名 console.log(a1.nodeValue);//"http://www.baidu.com"; 属性值
5【节点的关系关系属性】
描述和获取节点之间关系的属性 已知一个节点 我们基于这些属性可以获取到任何一个跟其相关的节点
1)childNodes 集合 [NodeList]
获取当前节点所有的子节点{包含各种类型}
获取的是节点集合 空格换行是文本节点
兼容问题 在IE6-8 因为在这浏览器中,不会把空格和换行当做文本节点 不认为这是个节点
<ul id="main">
<!-- 我是注释 -->
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
</ul>
<script>
console.log(main.childNodes);
// NodeList(11) [text, comment, text, li, text, li, text, li, text, li, text]
</script>
2) children
获取当前元素所有的元素子节点,获取的是一个元素集合
但是在ie6—ie8下不兼容 会把注释节点当成元素节点 [HTMLCollection]
console.log(main.children);
HTMLCollection(4) [li, li, li, li]
3)parentNode
获取当前节点唯一的父亲节点
4) previousSibling
获取上一个哥哥节点 {只获取一个,紧挨着的这一个,而且不一定是元素节点}
main.previousSibling
//#text
5) previousElementSibling
获取其元素哥哥节点 在ie 678 不兼容
ie6-ie8 不兼容
<span>1</span>
<ul id="main">
<!-- 我是注释 -->
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
</ul>
<script>
console.log(main.previousElementSibling);
//<span>1</span>
<script>
6)nextSibling
获取当前节点的下一个兄弟节点
<span id="span1">1</span>
<ul id="main">
<!-- 我是注释 -->
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
</ul>
<span>2</span>
// console.log( span.nextSibling)
7) nextElementSibling
获取当前节点的下一个元素兄弟节点
ie6-ie8 不兼容
8) firstChild
获取其所有子节点的第一个{大儿子}
9)firstElementChild
获取当前节点的第一个元素子节点
ie6-ie8 不兼容
10)lastChild
11)lastElementChild
获取当前节点的最后一个元素子节点{小儿子}
ie6-ie8 不兼容
6【dom 的增删改】
1)createElement:动态创建一个元素节点【元素标签】
var link=document.createElement('a');
link.href="http://www.baidu.com"; //增加href属性
2)createTextNode: 创建一个文本节点
var text=document.createTextNode('我是文本的内容');
3) appendChild:把元素追加到一个容器的末尾
+容器.appendChild(元素对象) 把元素对象放置容器的末尾
【context】.appendChild([元素]);
var odiv=documment.createElement("div");
document.body.appendChild(odiv);
4)insertBefore: 把一个元素插入到另一个元素的前面
insertBefore 把A{新增的}放到B{现有的}的前面 (B.parentNode).insertBefore(A,B)
把新元素添加到原有元素的前面
【context】.insertBefore(newEle,oldEle);
5) cloneNode:把某一个节点进行克隆
- 【ele】.cloneNode(false/true);浅克隆: 只是克隆了一个节点,里面的内容还有样式都没克隆
【ele】.cloneNode(true);深克隆:把节点包含的所有内容进行克隆
6)removeChild:移除某个节点
7)set/get/removeAttribute
设置/获取/删除 当前元素的某一个自定义属性
setAttribute
- getAttribute
- removeAttribute
<div id="box"></div>
//=======> setAttribute 设置
box.setAttribute("index",1);
box.getAttribute("index");
box.removeAttribute("index");
//========> 基于键值对操作
// 设置
box["aa"]=22;
// 获取
box["aa"]
//移除
delete box[aa];
基于键值对方式 增删改:修改当前对象的堆内存空间完成的(在堆内存空间可以看到)
基于Attribute dom方法增删改,是修改html结构来完成的(此种方法设置的在结构上可以看到)
以上两种方式不能混用
7.【练习题】
1) 自己手动封装一个获取节点下面的所有子元素,要求考虑兼容性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
</style>
</head>
<body>
<span id="span1">1</span>
<ul id="main">
<!-- 我是注释 -->
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
</ul>
<span>2</span>
</body>
</html>
<script>
function children(element){
var nodeLists=element.childNodes;
var result=[]
for (var i = 0; i < nodelist.length; i++) {
var itemNode=nodelist[i];
if(itemNode.nodeType===1){
result.push(itemNode);
}
}
return result;
}
console.log(children(main));
</script>
2) 自己手动封装一个perviousElementSibling,要兼容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
</style>
</head>
<body>
<span id="span1">1</span>
<ul id="main">
<!-- 我是注释 -->
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
<li>选择珠峰的,都是明智的!</li>
</ul>
<span id="span2">2</span>
</body>
</html>
<script>
function previousElmentSibling(ele){
var pre=ele.previousSibling;
while(pre&&pre.nodeType!==1){
pre=pre.previousSibling;
}
return pre;
}
previousElmentSibling(span2)
</script>
3.获取当前节点的所有元素哥哥节点 兼容所有浏览器
JQ中的prevAll这个方法 就是干这个的
方式1
function prevAll(node){
var result=[];
// 获取父节点
var parent=node.parentNode;
//获取子节点 自己和他所有子节点
var nodelist=parent.childNodes;
// 循环所有节点 元素类型是我们想要的 并且找到当前节点后就不在循环了
for(var i=0;i<nodelist.length;i++){
var item=nodelist[i];
if(item===node){
// 找到的是自己
break;
}
// 找的不是自己 我们把元素节点存储起来
if(item.nodeType===1){
result.push(item);
}
}
return result;
}
方式2
function prevAll2(node){
var prev=node.previousSibling;
var result=[];
while(prev!== null){
if(prev.nodeType===1){
result.unshift(prev);
}
prev=prev.previousSibling;
}
return result;
}
4获取所有的弟弟节点
方式1
function nextAll(node){
var nodelist=node.parentNode.childNodes;
var result=[];
//倒着从最后一项开始循环
for(var i=nodelist.length-1;i>=0;i--){
var item=nodelist[i];
if(item===node){
// 找到的是自己
break;
}
// 找的不是自己 我们把元素节点存储起来
if(item.nodeType===1){
result.unshift(item);
}
}
return result;
}
方式2
function nextAll2(node){
var result=[];
var next=node.nextSibling;
while(next!==null){
if(next.nodeType===1){
result.push(next);
}
next=next.nextSibling;
}
return result;
}
5.获取所有的兄弟节点
方式1
function silbings(node){
//所有的儿子中 一定包含了我和我的兄弟们
var nodelist=node.parentNode.childNodes;
var result=[];
//依次遍历每一项节点 除了非元素和我本身除外 其余的存储起来
for (var i = 0; i < nodelist.length; i++) {
var item=nodelist[i];
if(item.nodeType!==1||item===node){
continue;
}
result.push(item);
}
return result;
}
方式2
function silbings2(node){
// 分别调用两个方法所有的哥哥和所有弟弟 就是所有的兄弟
return prevAll2(node).concat( nextAll2(node));
}
6.获取当前节点的索引 他在所有兄弟中的排行
function index(node){
//他有几个哥哥 那么它的索引就是几
return prevAll2(node).length;
}