1、认识DOM
文档对象模型(document Object model),由W3C提出的标准,是一个使用脚本动态的访问和更新文档的内容、结构以及样式;
DOM 提供了相应的API(接口),可以对文档进行增删改查,以实现js对网页元素的静态(进行)控制,实现动态网页的功能
2、HTML 节点树
DOM 的原理是将文档装入内容,并以节点的形式解析为一棵节点树
HTML 文档就是一种树状的结构化文档
3、节点类型
- 元素节点:就是指标签
- 属性节点:就是指标签上的属性
- 文本节点:就是指标签之间的文本内容 4、获取节点的辅助方法
- childNodes: 返回该节点下所有的子节点列表【包含空白符】(集合)【类似数组结构】 语法:父节点.childNodes
- .hasChildNodes(); --判断是否有子节点 语法:父元素.hasChildNodes();
- firstChild --返回第一个子节点 语法:父元素.firstChild
- lastChild --返回最后一个子节点 语法:父元素.lastChild
- .previousSibling --返回上一个兄弟节点 语法:父元素.previousSibling
- .nextSibling --返回下一个兄弟节点 语法:父元素.nextSibling
parentNode(靠谱) 语法:子节点.parentNode --返回父节点
children --返回所以子节点(靠谱,不包含空白符) 语法:父元素.children
5、节点属性
5.1 节点名字:nodeName
- 元素节点的 nodeName 与标签名字一样;
- 属性节点的 nodeName 与属性名一样;
- 文本节点的 nodeName 固定值为 #text;
5.2 节点值: nodeValue
- 元素节点的 nodeValue 为Undefined 或者 null
- 属性节点的 nodeValue 为属性值
- 文本节点的 nodeValue 为文本内容
5.3 节点类型: nodeType
- 元素节点的 nodeType 为 1
- 属性节点的 nodeType 为 2
- 文本节点的 nodeType 为 3
<body>
<div id="box">
<h1>标题</h1>
<div>
<img src="" alt="LOGO">
</div>
<p>图片的描述</p>
</div>
<script>
var box = document.getElementById('box');
var children = box.childNodes;
console.log(children);
//获取元素节点的方法
var arr = [];
for(var i = 0; i < children.length;i++) {
if(children[i].nodeType == 1) {
arr.push(children[i]);
}
}
//返回的全是元素节点
console.log(arr);
console.log('第一个子节点'+box.hasChildNodes());
console.log('返回上一个兄弟节点'+box.previousSibling);
console.log('返回父节点'+box.parentNode);
console.log('返回所有子节点'+box.children)
</script>
</body>
获取节点的方法 1、获取节点方法(W3C)
- 通过 ID 获取标签(获取一个标签 document.getElementByID(id);
- 通过标签名获取:(获取一个标签的集合、类似数组结构) document.getElementsByTagName(tagname);
- 通过 name 获取标签(获取的是一个集合) document .getElementsByName(name);
- 通过 class 名字获取标签(获取一个标签的集合、类似数组结构)只支持IE9及以上 document.getElementsByClassName(classname)
2、其他方法:
-
获取HTML标签(所有浏览器都支持的) document.documentElement
-
获取body标签 document.body
-
通过 form 的 name 获取表单 例如:
console.log(document.loginForm.username); 语法:document.表单名字 document.表单名字.表单元素名
3、强大的 query【无法获取动态添加的 dom 节点】
- document.querySelector(css选择器); --返回找到的第一个元素
- document.querySelector('#nav');
- document.querySelector('li');
- document.querySelectorAll(css选择器) --返回找到的所有元素
//使用document.getElementsByClassName 老版本IE9以前的版本兼容
/**
* 根据类名查找元素,解决浏览器兼容问题
* @param className <String> 待查找的类名
* @return 返回查找到的元素集合
*/
function byClass(className) {
if (document.getElementsByClassName) // 支持使用
return document.getElementsByClassName(className);
/* 不支持使用 getElementsByClassName() 方法,解决兼容 */
// 定义保存结果的数组
var result = [];
// 根据标签名查找所有元素
var elements = document.getElementsByTagName("*");
// 遍历每个元素
for (var i = 0, len = elements.length; i < len; i++) {
// 当前遍历到元素的所有类名
var classNames = elements[i].className.split(" ");
// 遍历当前元素的类名
for (var j = 0, l = classNames.length; j < l; j++) {
// 判断当前遍历到的类名是否与待查找元素的类名一致
if (classNames[j] === className) {
// 一致,则说明当前遍历到的元素是待查找出元素其中之一
result.push(elements[i]);
break;
}
}
}
// 返回查找到的结果
return result;
}
//方法二
/*
*封装 class的获取方法
*method ByClass(classname)
*param [string] classname class的名字
*return [string] 返回的class数组(元素集合)
*/
function ByClass(classname) {
//判断 如果支持document.getElementsByClassName【document.getElementsByClassName】默认的只在IE9+
if(document.getElementsByClassName) {
return document.getElementsByClassName(classname);
} else { //针对IE 6、7、8
var classArr = [];
// 第一步:遍历所有元素节点
var elesAll = document.getElementsByTagName('*');
for(var i = 0; i< elesAll.length;i++) {
// 第二步:将classname 与每一个标签的classname进行比对
if(elesAll[i].className.index(classname) != -1) {
//第三步:将匹配成功的推进新数组中
classArr.push(elesAll[i]);
}
}
return classArr;
}
}
console.log(ByClass('one'));
获取属性 1、获取属性:
- 元素.attributes --获取元素属性集合
console.log(attributes); console.log(attributes[0]);
- 元素.属性名【因为class是关键字,所以要写上className;用于获取元素】
console.log(baidu.className);
- 元素.getAttribute(属性名)【用于获取某一个属性】
console.log(baidu.getAttribute('href'));
[如果是class就不需要再用className了,因为''封装了不会起冲突]console.log(baidu.getAttribute('class'));
2、设置属性:
- 元素.属性名 = '属性值';
baidu.style.color = 'red';
- 元素.setAttribute(属性名,属性值);
baidu.setAttribute('title','您点击之后不会发生改变');
3、移除属性
元素.removeAttribute(属性名);
4、判断是否有某一个属性
元素.hasAttribute(属性名) --返回值是一个布尔值
5、HTML5 自定义属性操作
- element.dataset.自定义属性名(如:data-index)
- element.getAttribute('data-index');
<body>
<!--
HTML5 可以自定义属性,自定义的属性以 data- 开头,比如说设置index属性
-->
<a href="http://www.baidu.com" id="baidu" title="点击链接跳转到百度首页" class="baidu" data-index = '1'>首页</a>
<script>
var baidu = document.getElementsByTagName('a')[0];
// 获取元素所有属性集合
var attributes = baidu.attributes;
console.log(attributes);
console.log(attributes[0]);
// 获取属性【因为class是关键字,所以要写上className;用于获取元素】
console.log(baidu.href);
console.log(baidu.className);
console.log(baidu.getAttribute('href'));
console.log(baidu.getAttribute('class'));
baidu.style.color = 'red';
baidu.setAttribute('title','您点击之后不会发生改变');
//移除属性
baidu.removeAttribute('class');
console.log(attributes);
if(baidu.hasAttribute('class')) {
console.log(baidu.getAttribute('class'));
} else {
alert('您需要重新添加class');
}
</script>
</body>
通过获取节点修改css样式例子 1、JS动态创建标签
- document.createElement(您需要创建的标签名字);
document.createTextNode('动态创建文本内容');
将文本放入标签 li.appendChild(text);
//将子标签添加进父节点中demo.appendChild(li);
【父节点.appendChild(子节点);】 --将子节点添加到父节点的最后
2、删除子节点
父节点.removeChild(子节点); --代表移除子节点
<!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>
.co {
color: blue;
}
</style>
</head>
<body>
<ul id="demo">
<li>导航1</li>
<li>导航2</li>
<li>导航3</li>
</ul>
<button type="button" id="addColor">添加字体颜色</button>
<button type="button" id="changeColor">修改字体颜色</button>
<button type="button" id="addnav">添加导航</button>
<script>
var addColor = document.getElementById('addColor'),
demo = document.getElementById('demo'),
//获取demo下的所有li相当于后代选择器
lis = demo.getElementsByTagName('li'),
changeColor = document.getElementById('changeColor'),
addNav = document.getElementById('addnav');
// 给添加颜色按钮添加点击事件,改变css引用
addColor.onclick = function() {
for(var i = 0;i < lis.length;i++) {
lis[i].className = 'co';
}
}
changeColor.onclick = function() {
// 如果有颜色,就变为空,没有引用css样式
if(lis[0].className) {
for(var i = 0;i < lis.length;i++) {
lis[i].className = '';
}
// 如果没有颜色就把css样式引用起来,变为co
} else {
for(var i = 0;i < lis.length;i++) {
lis[i].className = 'co';
}
}
}
addNav.onclick = function() {
//动态创建标签
var li = document.createElement('li');
//创建文本内容
var text = document.createTextNode('动态创建文本内容');
//将文本放入标签
li.appendChild(text);
//将子标签添加进父节点中
demo.appendChild(li);
}
</script>
</body>
</html>
样式的操作 1、操作CSS样式
- 元素.style.css属性名 = css属性值;【大多数都要加''因为是值】
demo.style.height = '50px'; demo.style.border = '2px solid red';
注意:【如果css单词是通过链接的单词,则需要写成驼峰式命名】
如:demo.style.borderBottom = '2px solid red';
【因为float是js中的保留字,所以要写为cssFloat】
如: demo.style.cssFloat = 'right';
- cssText【可以帮助我么批量的设置CSS样式】
demo.style.cssText += 'width: 400px;height: 50px;';
- 添加 classname (推荐使用)提前在css中写好class,接下来动态添加class,比如:
demo.className = 'demo box';demo.className = 'demo box';
1、节点的创建、插入、替换和克隆 - 创建标签节点
document.createElement('标签名');
- 创建文本节点
document.createTextNode("文本内容")
- 节点的增加
父元素.appendChild(子节点); --将子节点添加到父元素的最后
- 在某元素之前插入新元素
父元素.insertBefore(新节点,旧节点);
<!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>
.box {
width: 100px;
height: 100px;
color: teal;
background: lavender;
}
</style>
</head>
<body>
<div class="demo"></div>
<script>
// 获取标签
var demo = document.getElementsByClassName('demo')[0];
// 设置css样式
// demo.style.height = '50px';
// demo.style.width = '50px';
// demo.style.background = 'pink';
// demo.style.borderBottom = '2px solid red';
// demo.style.cssFloat = 'right';
// demo.style.cssText += 'width: 400px;height: 50px;';
// 优化部分
// 通过动态添加class与移除class来改变css样式
demo.className = 'demo box';
</script>
</body>
</html>