DOM简介
DOM :Document Object Model
专门操作网页内容的一套现成的对象和函数的集合
只有dom能操作, jquery是基于dom封装的
Dom标准,w3c指定并负责维护的一套对象和函数的标准,绝大多数浏览器都兼容
Dom4步 非常重要 (dom增删改查+事件绑定)
查找触发事件的元素 必不可少
绑定事件处理函数
元素.on 事件名=function(){}
查找要修改的元素
修改元素
Dom树
内存中,保存整个网页内容的树形结构
上下级关系,都适合用Dom树
比如,一个html页面也是一个Dom树,其中标签自带的属性是那个标签的同级,标签之间的内容是标签的下级
:
直接获取元素
console.log 输出当前根节点以下所有元素
console.dir 输出当前节点的所有属性方法
根节点对象 document
document 根节点对象 代表整个dom树和所有网页内容
案列: 直接输出根节点下所有元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>标题一</h1>
<span id="cute">可爱</span>
<script>
//输出节点及其子节点的dom树结构
console.log(document);
//输出当前子节点对象自己的属性和方法
console.dir(document);
</script>
</body>
</html>
document.documentElement 直接输出html下所有元素
也就是说以html为根节点
案列: document.documentElement
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>标题一</h1>
<span id="cute">可爱</span>
<script>
//输出节点及其子节点的dom树结构
console.log(document.documentElement);
//输出当前子节点对象自己的属性和方法
console.dir(document.documentElement);
</script>
</body>
</html>
document.head 直接输出head下所有元素
也就是说以head为根节点
案列:document.head
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>标题一</h1>
<span id="cute">可爱</span>
<script>
//输出节点及其子节点的dom树结构
console.log(document.head);
//输出当前子节点对象自己的属性和方法
console.dir(document.head);
</script>
</body>
</html>
document.body 直接输出body下所有元素
也就是以body为根节点
案列:document.body
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>标题一</h1>
<span id="cute">可爱</span>
<script>
console.log(document.body);
console.dir(document.body);
</script>
</body>
</html>
查找元素
节点树------不推荐使用
按节点关系查找元素
包含所有网页内容的树结构
包括两大类关系,6个属性,按关系可以分为父子关系 兄弟关系
连看不见的换行和空字符也被当做节点对象
父子关系
获取一个元素的父节点 元素.parentNode //返回一个节点对象
获取一个元素的所有直接子节点 元素.childNodes //返回一个包含多个直接子节点对象的类数组对象
获取一个元素下第一个直接子节点 元素.firstChild
获取一个元素下最后一个直接子节点 元素.lastChild
dom的下标也是从0开始
案列:获取sapn
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>标题一</h1>
<span id="cute">可爱</span>
<script>
// 目标:获取span
console.log(document.body.childNodes[1]);//但结果是<h1>...,不是span
//打印出所有body下子节点
console.log(document.body.childNodes);
//这样才能找出span
console.log(document.body.childNodes[3]);
</script>
</body>
</html>
兄弟关系
获得一个元素相邻的前一个兄弟节点 元素.previousSibling
获取一个元素相邻的下一个兄弟节点 元素.nextSibling
按元素树查找-------推荐使用
不会受看不见的空字符干扰
包括两大类关系,6个属性,按关系可以分为父子关系 兄弟关系
父子关系
获取一个元素的父元素 元素.parentElement //返回一个元素对象
获取一个元素的所有直接子元素 元素.children //返回一个包含多个直接子元素对象的类数组对象
获取一个元素下第一个直接子元素 元素.firstElementChild
获取一个元素下最后一个直接子元素 元素.lastElementChild
dom的下标也是从0开始
案列:获取body的子元素span
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>标题一</h1>
<span id="cute">可爱</span>
<script>
// 目标:获取span
console.log(document.body.children[1]);
</script>
</body>
</html>
兄弟关系
获得一个元素相邻的前一个兄弟元素 元素.previousElementSibling
获取一个元素相邻的下一个兄弟元素 元素.nextElementSibling
按HTML特征查找
通过id名查找一个元素对象getElementById
var 元素对象=document.getElementById("id名");
找到,返回一个元素对象,找不到,返回
案例:查找id为nav的元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<span>Hello World</span>
<ul id="nav">
<li>电影</li>
<li>综艺
<ul>
<li>跑男</li>
<li>爸爸</li>
<li>极限</li>
</ul>
</li>
<li>剧集</li>
</ul>
<script>
//查找id为nav的元素
var nav=document.getElementById("nav");
console.log(nav);
</script>
</body>
</html>
通过标签名(tagname)查找多个元素getElementsByTagName
<h1> </h1>这种 ,它会查询所有后代
var 类数组对象=任意父元素.getElementsByTagName("标签名");
找到,返回一个类数组对象,找不到返回一个空类数组对象{length:0} ,{length:0} 表示有一个对象,但里面没有东西
如果想要获取一个仅有的元素对象,需要加上[0],从类数组对象中0位置,取出唯一找到的一个元素对象
案例:查找nav下的所有li元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<span>Hello World</span>
<ul id="nav">
<li>电影</li>
<li>综艺
<ul>
<li>跑男</li>
<li>爸爸</li>
<li>极限</li>
</ul>
</li>
<li>剧集</li>
</ul>
<script>
//查找nav下的所有li元素
var lis=nav.getElementsByTagName("li");
console.log(lis);
</script>
</body>
</html>
案列:类数组对象[0]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<span>Hello World</span>
<ul id="nav">
<li>电影</li>
<li>综艺
<ul>
<li>跑男</li>
<li>爸爸</li>
<li>极限</li>
</ul>
</li>
<li>剧集</li>
</ul>
<script>
//查找span
//这个是集合
var span=document.getElementsByTagName("span");
console.log(span);
//这个是元素
var span2=document.getElementsByTagName("span")[0];
console.log(span2);
</script>
</body>
</html>
通过类名查找多个元素getElementsByClassName
它会查询所有后代
var 类数组对象=任意父元素.getElementsByClassName("class名");
找到,返回一个类数组对象,包含指定标签名的元素对象,找不到返回一个空类数组对象{length:0}
如果想要获取一个仅有的元素对象,需要加上[0],从类数组对象中0位置,取出唯一找到的一个元素对象
如果一个元素被多个class修饰,只需要使用其中任意一个class,就可以找到这个元素
案列:类名查找元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<span>Hello World</span>
<span>可爱</span>
<ul id="nav">
<li class="item">电影</li>
<li class="item">综艺
<ul>
<li class="item active">跑男</li>
<li class="item">爸爸</li>
<li class="item">极限</li>
</ul>
</li>
<li class="item">剧集</li>
</ul>
<script>
//查找class为item的所有元素
var items=nav.getElementsByClassName("item");
console.log(items);
//查找class为active的单个元素
var active=nav.getElementsByClassName("active")[0];
console.log(active);
</script>
</body>
</html>
通过name名查找多个表单元素getElementsByName
var 类数组对象=document.getElementsByName("name名");
找到返回一个类数组对象,包含所有指定标签名的元素对象,找不到返回一个空类数组对象{length:0}
如果想要获取一个仅有的元素对象,需要加上[0],从类数组对象中0位置,取出唯一找到的一个元素对象
案例:name例子
注意:单选按钮时两个名字相同
n
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form action="">
用户名:<input type="text" name="uname"></br>
性别:<input type="radio" name="sex" value=1>男
<input type="radio" name="sex" value=0>女
</form>
<script>
//查找name为sex的两个radio元素
var radio=document.getElementsByName("sex");
console.log(radio);
//查找name为uname的一个文本框
var txtName=document.getElementsByName("uname")[0];
console.log(txtName);
</script>
</body>
</html>
通过选择器查找元素 2个函数
一个元素
会查找所有后代
只要一个元素藏的深,查找条件比较复杂时,都可以用选择器查找元素
var 一个元素对象=任意父元素.querySelector("选择器");
如果找到,返回一个元素的对象,如果没找到,返回null
案列:找出<p>学习</p>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<span>Hello World</span>
<span>可爱</span>
<ul id="nav">
<li class="item">电影</li>
<li class="item">综艺
<ul>
<li class="item active">跑男</li>
<li class="item">爸爸</li>
<li class="item">极限</li>
<p>学习</p>
</ul>
</li>
<li class="item">剧集</li>
</ul>
<script>
var study=nav.querySelector("p");
console.log(study);
</script>
</body>
</html>
多个元素
var 类数组对象=任意父元素.querySelectorAll("选择器")
找到,返回类数组对象,包含找到所有找到符合要求的Dom元素对象,没找到,返回{length:0}
案列:查找nav下的所有li
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<span>Hello World</span>
<span>可爱</span>
<ul id="nav">
<li class="item">电影</li>
<li class="item">综艺
<ul>
<li class="item active">跑男</li>
<li class="item">爸爸</li>
<li class="item">极限</li>
</ul>
</li>
<li class="item">剧集</li>
</ul>
<script>
var lis=nav.querySelectorAll("li");
console.log(lis);
</script>
</body>
</html>
获取修改元素内容
获取内容
获取开始标签到结束标签之间的原始HTML内容(<开始标签> .........<结束标签>)
元素.innerHTML
修改内容:先将内容交个浏览器解析,解析后,返回门外汉也能看懂的内容
元素.innerHTML=“”
获取开始标签到结束标签之间的纯文本内容
元素.textContent
将特殊符号翻译为正文,并去掉内嵌的标签
修改内容:直接显示内容,不交给浏览器解析
元素.textContent=“”
案例:innerHTML与textContent获取内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h3>来自<<<a href="#">新华社</a>>>的消息</h3>
<script>
//获取h3的内容,先找到位置再获取
var h3=document.getElementsByTagName("h3")[0];
console.log(h3.innerHTML);
//获取h3的存文本内容
console.log(h3.textContent);
</script>
</body>
</html>
案例:innerHTML与textContent修改内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h2></h2>
<h3></h3>
<script>
//innerHTml修改内容
var h2=document.getElementsByTagName("h2")[0];
h2.innerHTML=`来自<<<a href="#">新华社</a>>>的消息`;
//textContent修改内容
var h3=document.getElementsByTagName("h3")[0];
h3.textContent=`来自<<<a href="#">新华社</a>>>的消息`;
</script>
</body>
</html>
表单元素值获取修改
元素.value
表单元素没有结束标签,所以innerHTML ,textContent无法使用,可以用value属性
案例:获取文本框里的内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<input id="keyword"/><button id="btn">百度一下</button>
<script>
var btn=document.getElementById("btn");
btn.onclick=function(){
//获取id为keyword的文本框值
var keyword=document.getElementById("keyword");
var value=keyword.value;
//trim去掉开头结尾的空字符
if(value.trim()!=""){
console.log(`搜索${value}的内容`);
}
}
</script>
</body>
</html>
属性
字符串类型的HTML标准属性
html标准中规定的,值为字符串的html属性
eg:id class name value title href arc
旧核心的DOM4个函数
获取一个元素的属性值:元素.getAttribute("属性名")
修改一个元素的属性值:元素.setAttribute("属性名”,“新属性值”)
判断一个元素上是否包含某个属性 元素.hasAttribute("属性名")
移除一个元素上的属性:元素.removeAttribute("属性名")
案列:就核心的dom4个函数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<a id="bone" href="#" title="骨头">人体有多少骨头</a>
<script>
var bone=document.getElementById("bone");
//获取a标签title的属性值
console.log(bone.getAttribute("title"));
//修改a标签title的属性值
bone.setAttribute("title","身体组成成分");
console.log(bone.getAttribute("title"));
//判断标签a上有没有href属性
console.log(bone.hasAttributes("href"));//true
//移除标签a上的title属性
bone.removeAttribute("title");
console.log(bone.getAttribute("title"));//null
//不知道为什么这个打印出来是true,元素显示上已经没它了
//console.log(bone.hasAttributes("title"));
</script>
</body>
</html>
新HTML DOM
获取一个元素的属性值:元素.属性名
修改一个元素的属性值:元素.属性名
判断一个元素上是否包含某个属性: 元素.属性名!==" "
移除一个元素上的属性:元素.属性名=" "
注意:class属性,class已经被ES6定义为关键字,所以用className代替
案例:HTML DOM
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<a id="bone" href="#" title="吃饭">好好生活</a>
<script>
var bone=document.getElementById("bone");
//获取a标签title的属性值
console.log(bone.title);//吃饭
//修改a标签title的属性值
bone.title="煮饭";
console.log(bone.title);//煮饭
//判断标签a上有没有href属性
console.log(bone.href!=="");//true
//移除标签a上的title属性
bone.title="";
</script>
</body>
</html>
bool类型的HTML标准属性-----------不懂
凡是不用写属性值,只要放在元素开始标签中,就能起作用。比如disabled,checked,selected...
但是旧核心的DOM只支持字符串类型属性,不支持bool类型属性。
bool类型的HTML标准属性,用HTML DOM
访问方式 元素.属性名,并且属性值不许是bool值,true或false
css的状态伪类
:cheacked 专门匹配选中的单选按钮和复选框
:disabled 专门匹配禁用的元素
自定义的扩展属性
程序员根据自身需要,自发添加的定义属性。代替id选择器、类选择器、标签选择器等,作为查找触发事件的元素条件。
查找触发事件元素,一律使用自定义属性作为查找条件
<元素 data-自定义属性名=“属性值”>
元素.dataset.自定义属性名
dataset可自动收集元素开始标签中,一切以data开头的自定义属性,集中保存起来备用。
使用dataset访问自定义属性时,不用加data-前缀,直接写属性名。
案列:自定义属性案列
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button data-n="0">按钮</button>
<script>
//查找带有data-n属性的元素
var btn=document.querySelector("[data-n]");
btn.onclick=function(){
//获得当前按钮身上data-n属性的值,转为整数
var n=parseInt(
//this.getAttribute("data-n"); DOM方法
this.dataset.n
);
n++;
//将新的n,放回当前按钮的data-n属性中报存
//this.getAttribute("data-n",n);
this.dataset.n=n;
}
</script>
</body>
</html>
修改样式
修改内联样式
这种是script里修改
元素.style.css属性名=“属性值;” 等价于 <元素 style="css属性:属性值;">
注意:如果css属性名中包含-,则必须更名为去横线变驼峰。但是,虽然在js中改了名字,可是实际操作的还是原来的css属性
eg: z-index === 元素.zIndex font-size === 元素.fontSize
background-color === 元素.backgroundColor
和长度、大小、距离有段的数值,必须加单位
案例:字体颜色改变
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
span{
color:red;
}
</style>
</head>
<body>
<span>我爱学习</span>
<script>
var span=document.getElementsByTagName("span")[0];
//把红色变为绿色
span.style.color="green";
</script>
</body>
</html>
获取样式getComputedStyle
.style属性,无法获取样式表中的样式,如果使用.style获取css属性值,会丢掉一大部分css属性值
获得元素的完整的css属性,要用计算后的样式,就是最终应用到元素上的所有样式的总和
1.获取一个元素计算后的所有属性的整体
var style=getComputedStyle(元素对象)
2.从style结果对象中,单独访问我们需要的某一个css属性
style.css属性名
注意: 计算后的样式,都是只读的,禁止修改。
想要修改一个元素的样式,用元素.style.css属性,因为内联样式优先级最高
案例:getComputedStyle
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
h2{
background-color:pink;
}
</style>
</head>
<body>
<h2 id="roll" style="color:green">努力学习</h2>
<script>
var rose=document.getElementById("roll");
//获取rose计算后的所有样式的集合
var raw=getComputedStyle(rose);
//获取努力学习的字体颜色
console.log(raw.color);
//获取努力学习的背景颜色
console.log(raw.backgroundColor);
//获取努力学习的字号
console.log(raw.fontSize);
//修改努力学习 字体大小
rose.style.fontSize="64px"
console.log(raw.fontSize);
</script>
</body>
</html>
批量修改一个元素的css属性
只要批量修改一个元素的多个css属性,都用class代替.style方式
步骤2步
1先在css中提前准备好几套class预案
2在js中,根据不同的情况,选择1对应的class,设置到对应的元素上
案列:带表单的验证
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
table{
width:700px;
}
td:first-child{
width:60px;
}
td:nth-child(2){
width:200px;
}
td:first-child+td{
width:200px;
}
td span{
color:red;
}
.vali_info{
display: none;
}
.txt_focus{
border-top: 2px solid black;
border-left: 2px solid black;
}
.vali_success,.vali_fail{
background-repeat: no-repeat;
background-position: left center;
display: block;
}
.vali_success{
background-image:url("img/add.png");
padding-left: 20px;
width: 0px;
height:20px;
overflow: hidden;
}
.vali_fail{
background-image: url("img/subtract.png");
border:1px solid red;
background-color: #ddd;
color:red;
padding-left: 30px;
}
</style>
</head>
<body>
<form id="form1">
<h2>增加管理员</h2>
<table>
<tr>
<td>姓名:</td>
<td>
<input name="username"/>
<span>*</span>
</td>
<td>
<div class="vali_info">
10个字符以内的字母、数字或下划线的组合
</div>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" name="pwd"/>
<span>*</span>
</td>
<td>
<div class="vali_info">6位数字</div>
</td>
</tr>
<tr>
<td></td>
<td colspan="2">
<input type="submit" value="保存"/>
<input type="reset" value="重填"/>
</td>
</tr>
</table>
</form>
<script>
//当姓名文本框失去焦点时触发,先找到它
var txtName=document.getElementsByName("username")[0];
// 绑定事件处理函数
txtName.onblur=function(){
// this 当前姓名文本框
// 查找要修改的元素
var div=this.parentElement.nextElementSibling.children[0];
// 当前td 下一个td 下一个td下的div
// 定义正则表达式,描述姓名文本框的规则
var reg=/^\w{1,10}$/;
var result=reg.test(this.value);
// 如果验证通过
if(result==true){
// 就设置div的class为vali_success
div.className="vali_success";
}else{
// 就设置div的class为vali_fail
div.className="vali_fail";
}
}
</script>
</body>
</html>
添加删除替换元素------在script里
dom树 --render tree 加载树(css挂载)---排版----绘制网页内容
先创建一个新的空元素
var 新元素=document.createElement("标签名”)
给新元素添加属性
元素.属性名=“属性值”
将新元素对象,挂载到DOM数上指定的父元素下------3种
在父元素下所有直接子元素末尾追加新元素:
父元素.appendChild(新元素)
将新元素插入到一个父元素下现有子元素之前
父元素.insertBrfore(新元素,现有元素)
用新元素替换一个父元素下现有子元素
父元素.replaceChild(新元素,现有元素)
删除元素
父元素.removeChild(子元素)
补充:第二种添加元素和元素内容的方法
createElement ------添加空的元素节点/创建一个新的xx元素
createTextNode-------创建文本节点,通过文本节点添加文本内容
案列:创建添加元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
//创建一个a元素
var a=document.createElement("a");
a.href="http://baidu.com";
a.innerHTML="欢迎访问百度";
//在控制台上打印出内容
console.log(a);
//将a追加到body结尾,这样就会在网页上显示
document.body.appendChild(a)
//删除元素
//document.body.removeChild(a)
</script>
</body>
</html>
案列2:创建添加一个新的元素内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div[id="div1"]{
width: 300px;
height: 300px;
background-color: skyblue;
}
div{
width: 300px;
height: 100px;
background-color: deeppink;//粉色
}
</style>
</head>
<body>
<div id="div1">
<p id="p1">这是一个段落</p>
</div>
<script>
// 创建了一个新的div
var newp=document.createElement("div");
// 在新的div上面追加文本内容
var node=document.createTextNode("我刚刚出生啦");
newp.appendChild(node);
var element=document.getElementById("div1");
element.appendChild(newp);
</script>
</body>
</html>
文档片段对象
如果父元素已经在DOM树上,需要添加多个平级子元素,应该借助于文档片段对象。
内存中临时保存多个平级子元素的虚拟父元素
创建文档片段对象
var 文档片段对象=document.createDocumentFragment();
将多个平级子元素,追加到文档片段对象
文档片段对象.appendChild(子元素)
将文档对象一次性添加到Dom树上指定父元素下
父元素.appendChild(文档片段对象)
注意:当文档片段对象将多个平级子元素添加到指定父元素下后就释放了,不会成为页面上一级元素
尽量减少操作DOM树的次数
每操作一次DOM树,浏览器都会重排重绘,极大的影响页面加载效率
如何做
如果同时添加父元素和子元素,应该现在内存中将所有子元素添加到父元素上,最后再将父元素一次添加到DOM树上。这样就只需要一次重排重绘。
案列:动态创建表格 ---减少操作Dom树次数
之前的优化代码本人已经删除,这个代码一步到位
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
table{width:600px; border-collapse:collapse;
text-align:center;
}
td,th{border:1px solid #ccc}
</style>
</head>
<body>
<div id="data">
<table>
<thead>
<tr>
<th>员工姓名</th>
<th>薪资</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
<!--通过js添加,已经在DOM树上了!-->
</tbody>
</table>
</div>
<script>
var json=[
{
"ename":"Tom",
"salary":11000,
"age":25
},
{
"ename":"John",
"salary":13000,
"age":28
},
{
"ename":"Mary",
"salary":12000,
"age":25
},
{
"ename":"Mary",
"salary":12000,
"age":25
},
];
//创建文档片段对象
var frag=document.createDocumentFragment();
//遍历json数组中每个员工对象,每遍历一个员工对象,就创建一个tr,追加到frag中
for(var emp of json){
var tr=document.createElement("tr");
frag.appendChild(tr);
//遍历当前员工对象中每个属性
for(var key in emp){
//每遍历一个属性,就创建一个td
var td=document.createElement("td");
//设置td的内容为当前对象当前属性的属性值
td.innerHTML=emp[key];
//将td追加到tr
tr.appendChild(td);
}
}
//当所有tr和td都添加到frag中,最后再将frag追加到tbody中
var tbody=document.querySelector("#data>table>tbody");
tbody.appendChild(frag);
</script>
</body>
</html>
HTML DOM常用对象
html dom对个别比较常用,又比较复杂的元素提供了一套简化版的操作。
但它只对个别元素提供了简化版操作,不是所有元素都能简化。并且它的简化没有jq和vue简单。
<img元素>
只有在新建img元素时,才有简化的做法
旧DOM var img=document.createElement("img");
HTML DOM var img=new image()
<form元素>
网页已将所有form元素集中保存在了document.forms集合中。
form元素对象已将内部所有表单元素集中保存在了form.elements集合中。
快速获取页面中某一个form元素
var form元素=docuemnt.forms[i]
快速获得form内某个表单元素
标准:form.elements[i下标/id/name名]
简写:如果表单元素有name名属性,简写为form.name
表单元素身上都有一个.focus()函数,可以让当前表单元素自动获得焦点!
案列:from元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form>
姓名:<input type="text"/><br/>
密码:<input type="password"/><br/>
<button>按钮</button>
</form>
<form>
姓名1:<input type="text"/><br/>
密码1:<input type="password" name="pwd"/><br/>
<button>按钮</button>
</form>
<script>
//获取页面中某一个form元素---这个获取到的是第二个form
var form=document.forms[1];
console.log(form);
//获取到了第二个form的第二个值
var s=form.elements[1];
console.log(s);
</script>
</body>
</html>
案列:带样式的表单验证
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>实现带样式的表单验证</title>
<style>
table {
width: 700px
}
td:first-child {
width: 60px
}
td:nth-child(2) {
width: 200px
}
td:first-child+td {
width: 200px
}
td span {
color: red
}
.vali_info {
display: none;
}
.txt_focus {
border-top: 2px solid black;
border-left: 2px solid black;
}
.vali_success,
.vali_fail {
background-repeat: no-repeat;
background-position: left center;
display: block;
}
.vali_success {
background-image: url("images/ok.png");
padding-left: 20px;
width: 0px;
height: 20px;
overflow: hidden;
}
.vali_fail {
background-image: url("images/err.png");
border: 1px solid red;
background-color: #ddd;
color: Red;
padding-left: 30px;
}
</style>
</head>
<body>
<form id="form1">
<h2>增加管理员</h2>
<table>
<tr>
<td>姓名:</td>
<td>
<input name="username" />
<span>*</span>
</td>
<td>
<div class="vali_info">
10个字符以内的字母、数字或下划线的组合
</div>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" name="pwd" />
<span>*</span>
</td>
<td>
<div class="vali_info">6位数字</div>
</td>
</tr>
<tr>
<td></td>
<td colspan="2">
<input type="submit" value="保存" />
<input type="reset" value="重填" />
</td>
</tr>
</table>
</form>
<script>
//本例中: 当姓名文本框失去焦点时触发验证
// var txtName=document.getElementsByName("username")[0];
//form优化
//获得form元素
var form=document.forms[0];
var txtName=form.elements["username"]; //这部还可以这样写 var txtName=form.username
//文本框自动获得焦点
txtName.focus();
//2. 绑定事件处理函数
txtName.onblur=function(){
//this->当前姓名文本框
//3. 查找要修改的元素
//本例中: 要修改文本框的爹的下一个兄弟的第一个孩子
var div=this //当前文本框
.parentElement //当前td
.nextElementSibling //下一个td
.children[0]; //下一个td下的div
//4. 修改元素
//定义正则表达式,描述姓名文本框的规则
var reg=/^\w{1,10}$/;
//用正则表达式去验证当前姓名文本框的内容
var result=reg.test(this.value);
//如果验证通过
if(result==true){
//就设置div的class为vali_success
div.className="vali_success";
}else{//否则如果验证不通过
//就设置div的class为vali_fail
div.className="vali_fail";
}
}
</script>
</body>
</html>
table元素
table结构是所有html元素中最复杂的。所有html dom提供了一套函数,逐级管理table中的元素
table管着行分组
添加行分组(两个功能)
var thead=table.createTHeada(); 创建了thead元素并添加到table
var tbody=table.createTBody();
var tfoot=table.createTFoot();
删除行分组
table.deteleTHead()
table.deleteTFoot()
获取行分组
table.tHead
table.tFoot
获取tbody
table.tBodies[i]
注意:一个table中只能有一个thead、tfoot.。但可以有多个tbody,保存在一个tBodies的集合中。必须用下标才能获取某一个tbody。所以table也就没法删除tbody.
行分组管着行
添加行
var tr=行分组.insertRow(i)
开头插入新行 行分组. insertRow(0)
末尾追加行 行分组.insertRow
注意:创建了新空行,再将新行添加到行分组。
如果行分组已经有现有行了,则插入的行会把当前位置的行及之后的行向后挤一个位置,新行再占据当前下标位置
删除行
行分组.deteleRow(i) i,要求必须是行分组内的相对下标位置
rowindex 属性-----每个行对象自带属性rowindex,记录行在整个表中的下标位置
行在整个表中的下标位置=rowindex所表示的下标
假设想删 i 行 , 行分组.deleteRow(tr.rowIndex),删除的就是i+1行
删除table中某一行,标准写法:table.deleteRow(tr.rowindex).
获取行
行分组.row[i] 代替 行分组.children[i]
行管理格
添加格 var td=行.insertCell() //先创建一个新的td,在把td追加到tr中
删除格:行.deleteCell(i). //删除行中下标为i的格。
获取格: 行.cells[i]
案例:删除表格中某一行数据
<!DOCTYPE HTML>
<html>
<head>
<title>动态创建表格</title>
<meta charset="utf-8" />
<style>
table{width:600px; border-collapse:collapse;
text-align:center;
}
td,th{border:1px solid #ccc}
</style>
</head>
<body>
<div id="data">
<table>
<thead>
<tr>
<th>员工姓名</th>
<th>薪资</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
</table>
</div>
<script>
var json=[
{
"ename":"Tom",
"salary":11000,
"age":25
},
{
"ename":"John",
"salary":13000,
"age":28
},
{
"ename":"Mary",
"salary":12000,
"age":25
}
];
(function(){
//1. 创建tbody,追加到table中
var tbody=document.createElement("tbody");
//需要先查找一下
var table=document.querySelector("#data>table");
//2. 遍历json数组中每个员工对象
for(var emp of json){
//每遍历一个员工对象,就创建一个tr,追加到tbody中
// var tr=document.createElement("tr");
//tbody.appendChild(tr);
// 简化写法
var tr=tbody.insertRow();//末尾追加行
//var tr=tbody.insertRow[0];//开头插入行 //这样出不来
//进一步遍历当前员工对象中每个属性
for(var key in emp){
//每遍历一个属性,就创建一个td
// var td=document.createElement("td");
//tr.appendChild(td);
var td=tr.insertCell();
//设置td的内容为当前对象当前属性的属性值
td.innerHTML=emp[key];
}
// 在添加一个td
//var td=document.createElement("td");
//tr.appendChild(td);
var td=tr.insertCell();
//在td中添加一个button
var btn=document.createElement("button");
td.appendChild(btn);
//设置按钮的位置,并为按钮绑定单击事件
btn.innerHTML="x";
btn.onclick=function(){
//this.innerHTML="❀"; 测试
//查找当前按钮父元素td的父元素 tr
var tr=this.parentElement.parentElement;
console.log(tr);
var ename=tr.cells[0].textContent;
//var ename=tr.children[0].innerHTML;
console.log(ename);
//先跟用户确认,是否继续删除
var result=confirm(`是否继续删除${ename}`);
//用户点击确认,表示用户同意删除
if(result==true){
//最终效果
table.deleteRow(tr.rowIndex);
}
}
}
//再将tbody一次性添加到DOM树
table.appendChild(tbody);
})()
</script>
</body>
</html>
浏览器三大对话框
输入框
包含一个文本框,可输入内容。并且可用返回值接住用户输入的内容。
var 内容=prompt("提示信息");
警告框
只有一个确认按钮的提示框,没有选择
alert("提示信息");
确认框
有一个确认按钮和一个取消按钮的对话框。用户可用选择确认或取消。程序中,还可以通过返回值接住用户点击的结果。
var 结果=confirm("提示信息");
结果一个为true,一个为false
但这三个所用不多,因为它用兼容性问题,不同浏览器显示的对话框会有差别。它的样式你不能修改
案列
购物车案例
运行效果:
jsDOM购物车效果展示
更清晰视频地址jsDOM购物车效果展示_哔哩哔哩_bilibili
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
table{
width:600px;
text-align: center;
border-collapse: collapse;
}
th,td{
border: 1px solid black;
}
[colspan="3"]{
text-align: right;
}
</style>
</head>
<body>
<table id="data">
<thead>
<tr>
<th>商品名称</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
</tr>
</thead>
<tbody>
<tr>
<td>iphone6</td>
<td>¥4488.00</td>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
<td>¥4488.00</td>
</tr>
<tr>
<td>iphone6 plus</td>
<td>¥5288.00</td>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
<td>¥5288.00</td>
</tr>
<tr>
<td>ipad Air2</td>
<td>¥4288.00</td>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
<td>¥4288.00</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3">Total:</td>
<td>¥14064.00</td>
</tr>
</tfoot>
</table>
<script>
//通过按钮实现数量增加减少功能
//找到按钮
var table=document.getElementById("data");
var btns=table.getElementsByTagName("button");
//单击按钮产生数量加减效果
for(var btn of btns){
btn.onclick=function(){
//先找到数量
var span=this.parentElement.children[1];
var n=parseInt(span.innerHTML);
if(this.innerHTML=="+"){
n++;
}else if(n>1){
n--;
}
span.innerHTML=n;
//计算小计
//找到价格并切分人民币符合
var td=this.parentElement.nextElementSibling;
var price=parseFloat(this.parentElement.previousElementSibling.innerHTML.slice(1));
//小计
var sum=price*n;
td.innerHTML=`¥${sum.toFixed(2)}`;
//总计
//找到它并修改
var lastTd=table.querySelector("tfoot>tr>td:last-child");
var tds=table.querySelectorAll("tbody>tr>td:last-child");
var total=0;
//累加小计
for(var td of tds){
total+=parseFloat(td.innerHTML.slice(1));
}
lastTd.innerHTML=`¥${total.toFixed(2)}`;
var lastTd=table.querySelector("tfoot>tr>td:last-child");
var tds=table.querySelectorAll("tbody>tr>td:last-child");
var total=0;
//累加小计
for(var td of tds){
total+=parseFloat(td.innerHTML.slice(1));
}
lastTd.innerHTML=`¥${total.toFixed(2)}`;
}
}
</script>
</body>
</html>
手风琴效果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
float: left;
height:100px;
line-height: 100px;
}
#d1,#d3{
background-color: #ccff00;
}
#d2{
cursor: pointer;
background-color: #00BFFF;
}
</style>
</head>
<body>
<div id="d1">树形列表</div>
<div id="d2"><<</div>
<div id="d3">内容的主体</div>
<script>
var d2=document.getElementById("d2");
//点d2显示或隐藏d1
d2.onclick=function(){
var d1=document.getElementById("d1");
//当d2箭头为<<就隐藏
//当d2为>>就打开
if(this.innerHTML=="<<"){
//等价于<div id="d1" style="display:none">
d1.style.display="none";
this.innerHTML=">>"
}else{
//写block的话,行内情况不对,所以不写默认就是显示
d1.style.display="",
this.innerHTML="<<"
}
}
</script>
</body>
</html>
点击隐藏展示效果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
li{
list-style: none;
}
li span{
padding-left:40px;
cursor: pointer; ,
/* background:url("img/add.png") no-reapat center left; */
}
li ul{
display: none;
}
/* .open{
background:url("img/subtract.png") no-repeat center left;
} */
.open+ul{
display: block;
}
img{
width:70px;
heigh:70px;
}
</style>
</head>
<body>
<ul class="tree">
<li>
<span class="open">考勤管理</span>
<ul>
<li>日常考勤</li>
<li>请假申请</li>
<li>加班/出差</li>
</ul>
</li>
<li>
<span>协同办公</span>
<ul>
<li>公文流转</li>
<li>文件中心</li>
<li>内部邮件</li>
<li>即时通信</li>
<li>短信提醒</li>
</ul>
</li>
</ul>
</body>
<script>
var spans=document.querySelectorAll("li>span");
for(var span of spans){
span.onclick=function(){
//this指当前点击的span
var spans=document.querySelectorAll("li>span");
//先遍历,清除所有span上的class,class用className代替
if(this.className=="open"){
this.className=""
}else{
for(var span of spans){
span.className=""
}
this.className="open"
}
}
}
</script>
</html>
全选案列
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h2>管理员列表</h2>
<table border="1px" width="500px">
<thead>
<tr>
<th><input type="checkbox"/>全选</th>
<th>管理员ID</th>
<th>姓名</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox"/></td>
<td>1</td>
<td>Tester</td>
<td>修改 删除</td>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>2</td>
<td>Manager</td>
<td>修改 删除</td>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>3</td>
<td>Analyst</td>
<td>修改 删除</td>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>4</td>
<td>Admin</td>
<td>修改 删除</td>
</tr>
</tbody>
</table>
<button>删除选定</button>
<script>
//功能一 点击全选按钮,下面4个全选中
//通过选择器查找全选按钮
var chbAll=document.querySelector("thead input");
//单击按钮时绑定下面4个按钮
chbAll.onclick=function(){
//通过选择器查找4个按钮
var chbs=document.querySelectorAll("tbody input");
for(var chb of chbs){
chb.checked=this.checked;
//this指代全选按钮,checked表示选中
}
}
//功能二:4个按钮没全选中就取消全选按钮
var chbs=document.querySelectorAll("tbody input");
for(var chb of chbs){
chb.onclick=function(){
//查找全选按钮
var chbAll=document.querySelector("thead input");
//只要一个没选择就不能全选,:checked表示选中复选框单选框
var unchecked=document.querySelector("tbody input:not(:checked)");
//判断全选和未选中关系
if(unchecked!=null){
chbAll.checked=false;
}else{
chbAll.checked=true;
}
}
}
</script>
</body>
</html>
选项卡
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
#tab li {
float: left;
list-style: none;
}
#tab li a {
display: inline-block;
text-decoration: none;
width: 80px;
height: 40px;
line-height: 40px;
text-align: center;
color: #000;
}
#container {
position: relative;
}
#content1,
#content2,
#content3 {
width: 300px;
height: 100px;
padding: 30px;
position: absolute;
top: 40px;
left: 0;
}
#tab li:first-child,
#content1 {
background-color: lightblue;
}
#tab li:first-child+li,
#content2 {
background-color: palegreen;
}
#tab li:first-child+li+li,
#content3 {
background-color: yellowgreen;
}
</style>
</head>
<body>
<h2>实现多标签页效果</h2>
<div class="tabs">
<ul id="tab">
<li><a href="#content1" data-toggle="tab" data-id="content1">10元套餐</a></li>
<li><a href="#content2" data-toggle="tab" data-id="content2">30元套餐</a></li>
<li><a href="#content3" data-toggle="tab" data-id="content3">50元包月</a></li>
</ul>
<div id="container">
<!-- 加style 然初始页面是第一个 -->
<div id="content1" style="z-index:10">
10元套餐详情:<br /> 每月套餐内拨打100分钟,超出部分2毛/分钟
</div>
<div id="content2">
30元套餐详情:<br /> 每月套餐内拨打300分钟,超出部分1.5毛/分钟
</div>
<div id="content3">
50元包月详情:<br /> 每月无限量随心打
</div>
</div>
</div>
<script>
// 注意:复制代码后如果点不动,重新写一下onclick就可以了
//查找触发事件的元素
//首先绑定两个之间有联系
//查找所有带有data-toggle属性,且属性值为tab的所有a元素
var tabs=document.querySelectorAll("[data-toggle=tab]");
//定义一个z,保存z-index的值
var z=10;
//所有tab都可点击,所有遍历
for(var tab of tabs){
tab.onclick=function(){
//this指当前点击的a元素
//查找要修改的a与元素
//先从当前a自己身上查找对应div的id
var id=this.dataset.id;
//用id查找对应的div元素
var div=document.getElementById(id);
this.dataset.id=this.getAttribute("data-id")
z++;//将z变量的值加1
//修改div的z-index属性值为最大值
div.style.zIndex=z;//js中不能随便写-,所以所以css中带有-的属性名一律去掉横线变驼峰。
}
}
</script>
</body>
</html>