DOM

DOM:(document object mode)文档对象模型。DOM为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。

目的就是为了能让js操作html元素而制定的一个规范

DOM是由节点组成的:HTML加载完毕,渲染引擎会在内存中把HTML文档,生成一个DOM树

操作网页上的元素的API。比如让盒子移动、变色、轮播图等。

上图可知,在HTML当中,一切都是节点:(非常重要)

  • 元素节点:HTML标签。
  • 文本节点:标签中的文字(比如标签之间的空格、换行)
  • 属性节点::标签的属性。

整个html文档就是一个文档节点。所有的节点都是Object。

object节点维护的内容

dom操作的内容

节点查找

直接查找

根据ID查找

永远只会找到一个标签

// obj  = document.getElementById('元素的id') 永远只会找到一个标签
var dar = document.getElementById('d1');
console.log(dar)

根据类名查找

永远得到一个数组

var objs = document.getElementsByClassName('foo');
console.log(objs[0]);
console.log(objs[1]);

根据标签查找

永远得到一个数组

var objs = document.getElementsByTagName('div');
console.log(objs[0])
console.log(objs[1])
console.log(objs[2])

间接查找

节点之间的关系是以属性的方式存在的

找父亲

var p_obj = document.getElementsByClassName('foo')[0]
console.log(p_obj.parentElement);

找儿子

var objs = document.getElementById('d1');
console.log(objs.children); // objs的子标签
console.log(objs.firstElementChild); // objs的第一个子标签
console.log(objs.lastElementChild); // objs的最后一个子标签

找哥哥

var p_obj = document.getElementsByClassName('foo')[0];
dac = p_obj.nextElementSibling // p_obj的下一个同级元素
console.log(dac.previousElementSibling); // dac的上一个同级元素

找弟弟

var p_obj = document.getElementsByClassName('foo')[0];
console.log(p_obj.nextElementSibling); // p_obj的下一个同级元素

操作节点

// 创建节点
obj = document.createElement('p')
<p></p>
obj.innderText = 'p标签'
<p>p标签</p>
// 添加节点
父节点.appendChild(子节点对象)
父节点.insertBefore(要添加的子对象,参考节点对象)
// 删除节点
父节点.removeChild(子节点对象)
// 克隆节点
节点.cloneNode() 只拷贝一层
节点.cloneNode(True) 拷贝所有子节点
// 替换节点
父节点.replaceChild(新对象,旧子节点)

创建标签

obj = document.createElement('p');  // 创建一个p标签

obj.innerText = '我是一个p标签'; // 给创建的p标签插入值

插入节点

  • appendChild 在查找到的元素最后一个元素的位置追加
  • insertBefore 在查找到的元素前插入
// appendChild
var p = document.createElement('p');
p.innerText = '我是一个p标签'
var obj = document.getElementById('d1');
obj.appendChild(p); // 将p标签插入到obj子标签的最后位置 // insertBefore
var p = document.createElement('p');
p.innerText = '我是一个p标签'
var obj = document.getElementById('d1');
var p2 = obj.firstElementChild; obj.insertBefore(p,p2); // 将p标签插入到p2标签前

删除子节点

var obj = document.getElementById('d1');
// var las_obj = obj.lastElementChild;
var las_obj = document.getElementsByTagName('a')[0];
obj.removeChild(las_obj); // 父节点 删除 las_obj

删除自己

var a_obj = document.getElementsByTagName('a')[0];
var di_obj = a_obj.parentElement;
di_obj.removeChild(a_obj);

复制节点

var obj = document.getElementById('d1');
var new_obj = obj.cloneNode(true);
// 不加true 默认只会浅拷贝,例如只会拷贝匹配到的这一行,而不会拷贝这一行的子元素
obj.appendChild(new_obj);

替换节点

var new_p = document.createElement('p');
new_p.innerText = '我是一个新的p标签'
var obj = document.getElementById('d1');
var p_obj = obj.firstElementChild;
// 父节点.replaceChild(新节点,旧节点)
obj.replaceChild(new_p,p_obj);

操作节点内的文本

// innerText pobj.innerText = '<a>我是一个a标签</a>'
// innerText 只人文本 html是不认识的
var new_p = document.createElement('p');
new_p.innerText = '<p>我是一个新的p标签</p>'
console.log(new_p); // innerHTML
var new_p = document.createElement('p');
new_p.innerHTML = '<a href="http://www.baidu.com">chaojibaidu</a>'
console.log(new_p);

操作值

var obj = document.getElementsByTagName('input')[0];
obj.value; // 获取值
"alexvalue" obj.value = 'cccc'; // 设置值

操作属性

// obj.setAttribute('属性名','属性值')
// obj.getAttribute('属性名')
// obj.removeAttribute('属性名') var obj = document.getElementById('mi');
// 设置属性
obj.setAttribute('href','http://www.baidu.com') // 删除属性
obj.removeAttribute('href') // 获取属性的值
console.log(obj.getAttribute('href'));

操作类

// LOW方法
document.getElementsByTagName('li')[1].setAttribute('class','c_li'); var obj = document.getElementById('mi');
// 查看类的数组
obj.classList; // 类名的数组中追加
obj.classList.add('c_li2'); // 类名数组中删除
obj.classList.remove('c_li'); // 类名数组中是否存在 存在返回true 不存在返回false
obj.classList.contains('c_li');
true // 类名数组中存在就删除,没有就加上
obj.classList.toggle('c_li');
true
obj.classList.toggle('c_li');
false

操作样式

// obj.style.样式名 = 样式值
var obj = document.getElementById('mi');
obj.style.backgroundColor = 'red';
"red"

例子:红绿灯

<!DOCTYPE html>
<html lang="zh_CN">
<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>Green</title>
<style>
.outer{
border:solid darkgrey 5px;
display:inline-block;
padding:5px;
border-radius:10px;
} .light{
float:left;
height:100px;
width:100px;
border-radius:50%;
background-color:lightgray;
margin-left:5px;
} .clearfix:after{
content:'';
clear:both;
display: inline-block;
} .red{
background-color:red;
} .yellow{
background-color:yellow;
} .green{
background-color:green;
} </style>
</head>
<body>
<div class="outer">
<div class="container">
<div class="light red"></div>
<div class="light"></div>
<div class="light"></div>
</div>
</div>
</body>
<script>
function fn(){
var lights = document.getElementsByClassName('light');
if (lights[0].classList.contains('red')){
lights[0].classList.remove('red');
lights[1].classList.add('yellow');
}else if (lights[1].classList.contains('yellow')){
lights[1].classList.remove('yellow');
lights[2].classList.add('green');
}else{
lights[2].classList.remove('green');
lights[0].classList.add('red');
}
} setInterval(fn,1000)
</script>
</html>

事件

JS是以事件驱动为核心的一门语言。

事件源:引发后续事件的html标签。

事件:js已经定义好了(见下图)

事件驱动程序:对样式和html的操作。也就是DOM。

代码书写步骤如下:(重要)

(1)获取事件源:document.getElementById(“box”); //类似与ios语言的 UIButton *adBtn = [UIButton buttonWithType:UIButtonTypeCustom];

(2)绑定事件: 事件源box.事件onclick = function(){ 事件驱动程序 };

(3)书写事件驱动程序:关于DOM的操作

代码示例:

<body>
<div id="box1"></div> <script type="text/javascript">
// 1、获取事件源
var div = document.getElementById("box1");
// 2、绑定事件
div.onclick = function () {
// 3、书写事件驱动程序
alert("我是弹出的内容");
}
</script>
</body>

常见事件如下:

3中绑定事件的方式:

<!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>
</head>
<body>
<div>
<ul id="items">
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
</div> <button onclick="fn()">按钮1</button>
<button id="bt2">按钮2</button>
<button id="bt3">按钮3</button>
<!-- <bottom>按钮1</bottom> -->
</body> <script> var btn2 = document.getElementById('bt2');
btn2.onclick = fn; function fn(){
var obj = document.getElementById('items');
var liobj = document.createElement('li');
liobj.innerText = '插入的li标签'
obj.appendChild(liobj);
} var bt3 = document.getElementById('bt3');
bt3.onclick = function fn() {
var obj = document.getElementById('items');
var liobj = document.createElement('li');
liobj.innerText = '插入的li标签'
obj.appendChild(liobj);
} </script>
</html>

下面针对事件的三要素,进行分别介绍。

1、获取事件源(DOM节点的获取)

示例:

1.模态框案例

需求:打开网页时有一个普通的按钮,点击当前按钮显示一个背景图,中心并弹出一个弹出框,点击X的时候会关闭当前的模态框

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
html,body{
height: 100%;
}
#box{
width: 100%;
height: 100%;
background: rgba(0,0,0,.3);
}
#content{
position: relative;
top: 150px;
width: 400px;
height: 200px;
line-height: 200px;
text-align: center;
color: red;
background-color: #fff;
margin: auto;
}
#span1{
position: absolute;
background-color: red;
top: 0;
right: 0;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
color: #fff; }
</style>
</head>
<body>
<button id="btn">弹出</button>
</body>
<script type="text/javascript">
//获取dom元素 1.获取事件源
var oBtn = document.getElementById('btn');
//创建弹出模态框的相关DOM对象
var oDiv = document.createElement('div');
var oP = document.createElement('p');
var oSpan = document.createElement('span'); // 设置属性
oDiv.id = 'box';
oP.id = 'content'
oP.innerHTML = '模态框成功弹出'
oSpan.innerHTML = 'X';
oSpan.id = 'span1' // 追加元素
oDiv.appendChild(oP);
oP.appendChild(oSpan); // 点击弹出按钮 弹出模态框
oBtn.onclick = function(){
//动态的添加到body中一个div
this.parentNode.insertBefore(oDiv,oBtn) }
// 点击X 关闭模态框
oSpan.onclick = function(){
// 移除oDiv元素
oDiv.parentNode.removeChild(oDiv)
} </script>
</html>

2.Select选择框

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<select name="province" id="province">
<option value="0" selected>请选择省</option>
</select>
<select name="city" id="city">
<option>请选择市:</option>
</select>
</body>
<script>
data = {"河北": ["廊坊", "邯郸"], "北京": ["朝阳区", "海淀区"], "山东": ["威海市", "烟台市"]}
var select1 =document.getElementById('province')
for(i in data){
var option = document.createElement('option')
option.innerText = i
select1.appendChild(option)
}
select1.onchange = function () {
var select2 =document.getElementById('city')
select2.innerText = null
var choosed = select1.options[this.options.selectedIndex].innerText
for(var i=0;i<data[choosed].length;i++){
var option = document.createElement('option')
option.value = i
option.innerText = data[choosed][i]
select2.appendChild(option)
}
}
</script>
</html>

3.Tab选项卡

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
ul{
list-style: none;
}
#tab{
width: 480px;
margin: 20px auto;
border: 1px solid red;
}
ul{
width: 100%;
overflow: hidden;
}
ul li{
float: left;
width: 160px;
height: 60px;
line-height: 60px;
text-align: center;
background-color: #cccccc;
} ul li a{
text-decoration: none;
color:black;
}
li.active{
background-color: red;
}
p{
display: none;
height: 200px;
text-align: center;
line-height: 200px;
background-color: red;
}
p.active{
display: block; } </style>
</head>
<body>
<div id="tab">
<ul>
<li class="active">
<a href="#">首页</a>
</li>
<li>
<a href="#">新闻</a>
</li>
<li>
<a href="#">图片</a>
</li>
</ul>
<p class="active">首页内容</p>
<p>新闻内容</p>
<p>图片内容</p> </div>
</body>
<script type="text/javascript">
window.onload = function(){
// //需求:鼠标放到上面的li上,li本身变色(添加类),对应的p也显示出来(添加类);
//思路:1.点亮上面的盒子。 2.利用索引值显示下面的盒子。 var tabli = document.getElementsByTagName('li');
var tabContent = document.getElementsByTagName('p') for(var i = 0; i < tabli.length; i++){
// 绑定索引值(新增一个自定义属性:index属性)
tabli[i].index = i;
tabli[i].onclick = function(){ // 1.点亮上面的盒子。 2.利用索引值显示下面的盒子。(排他思想)
for(var j = 0; j < tabli.length; j++){
tabli[j].className = '';
tabContent[j].className = '';
}
this.className = 'active' tabContent[this.index].className = 'active';//【重要代码】
}
}
} </script>
</html>

4.简易留言板

需求:当在textarea中输入内容,点击留言按钮,会添加到浏览器中,效果图如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>留言板</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.close{
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
cursor: pointer;
background-color: rgba(0,0,0,.1);
margin-left: 20px;
}
</style>
</head>
<body>
<h1>简易留言板</h1>
<div id="box">
<!--<ul> </ul>--> </div>
<textarea id="msg"></textarea>
<input type="button" id="btn" value="留言"/>
<button onclick="sum()">统计</button>
</body>
<script type="text/javascript"> // 0 将ul标签添加到div#box标签中
var oUl = document.createElement('ul');
var oBox = document.getElementById('box');
oBox.appendChild(oUl); var oBtn = document.getElementById('btn');
var oMsg = document.getElementById('msg')
// 控制留言的总数量
var count = 0;
oBtn.onclick = function(){ // 点击留言按钮事件操作
// 1.创建li标签
var oLi = document.createElement('li');
//2.设置内容
oLi.innerHTML = oMsg.value + "<span class='close'>X</span>" // 3.如果想在插入的第一个li获取的前面继续添加li标签
//3.1获取li标签
var olis = document.getElementsByTagName('li');
//3.2 如果是第一次添加的li标签,则直接添加到ul的后面
if(olis.length == 0){
oUl.appendChild(oLi);
count++; }else{
// 3.3 如果不是第一次添加的li标签,则插入到第一个li标签的前面
oUl.insertBefore(oLi,olis[0]);
count++;
}
// 4.添加完成之后 清空textarea的值
oMsg.value = ''; // 5.点击X的时候删除当前的一条数据
//5.1先获取所有的X
var oSpans = document.getElementsByTagName('span'); // 5.2for循环 对所有的X添加点击事件
for(var i = 0; i< oSpans.length; i++){
oSpans[i].onclick = function(){
// 5.3 移除当前的li标签
oUl.removeChild(this.parentNode)
count--;
}
} } function sum(){
alert('一共发布了'+count+'条留言'); }
</script>
</html>

最新文章

  1. vscode过滤pyc文件
  2. Ignite China 2015 之行
  3. UVALive 3027 Corporative Network
  4. 如何更高效地定制你的bootstrap
  5. T4
  6. nginx虚拟主机配置
  7. 仿知乎Android端回答UI
  8. Java设计模式-责任链模式(Chain of Responsibility)
  9. windows系统安装MongoDB
  10. exists与in的使用与区别
  11. iOS - 正则表达式判断邮箱、身份证..是否正确:
  12. html中em和px
  13. 华夏的理财30天A和华夏财富宝货币哪个收益比较好?
  14. nvm linux命令
  15. ECS活动真实IP (前端存在SLB)
  16. Android Studio和eclipse混淆打包总结
  17. linux系统下手动安装Angular-cli
  18. Keep Mind Working
  19. Ubuntu下LAMP环境配置
  20. 深入理解MyBatis框架的的配置信息

热门文章

  1. eclipsePreferences位置
  2. 72.Minimum Window Substring(最小子串窗口)
  3. JS的video在手机上有些手机能播放,而有些不能原因
  4. upx压缩notepad.exe(运行时压缩)
  5. K3 cloud选单时候必须把必录的数据录完以后才可以选单
  6. 从0构建webpack开发环境(二) 添加css,img的模块化支持
  7. 2019-8-31-C#-条件编译
  8. CreateJS入门 -- 注释详细到爆炸(My Style)
  9. after()和append()的区别、before()和prepend()区别、appendTo()和prependTo()、insertAfter()和insertBefore()
  10. 【leetcode】623. Add One Row to Tree