6.获取元素属性
6.1 获取元素属性
获取元素的属性有两种方式:
-
element.属性:
-
获取内置属性值,元素本身自带的属性
-
不能获取自定义属性
-
代码示例如
console.log(div.id)
-
-
element.getAttribute(‘属性’):
-
可以获取内置属性值
-
可以获取自定义属性
-
代码示例如下:
console.log(div.getAttribute('id'))
-
6.2设置属性值
设置属性值有两种方式:
- element.属性=“值”:
- element.setAttribute(“属性”,“值”):
6.3 移除属性
- element.removeAttribute(‘属性’)
6.4 tab切换案例
如下代码是实现tab切换的案例完整的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.tab{
width: 800px;
height: 300px;
/* background-color: aqua; */
margin: 0 auto;
margin-top: 100px;
}
.tab-lst{
clear: both;
border-bottom: 2px solid rgb(133, 70, 167);
height: 30px;
background-color: rgb(227, 226, 229);
}
.tab-lst li{
float: left;
display: block;
height: 30px;
line-height: 30px;
width: 120px;
text-align: center;
font-size: 16px;
cursor: pointer;
/* background-color: blue; */
}
.item{
height: 300px;
background-color: #ebeaea;
display: none;
}
.tab-lst-bg{
background-color:rgb(133, 70, 167);
color: #fff;
}
.con-show{
display: block;
}
</style>
</head>
<body>
<div class="tab">
<div class="tab-lst">
<ul>
<li class="tab-lst-bg">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab-content">
<div class="item con-show">商品介绍模块内容</div>
<div class="item">规格与包装模块内容</div>
<div class="item">售后保障模块内容</div>
<div class="item">商品评价模块内容</div>
<div class="item">手机社区模块内容</div>
</div>
</div>
<script>
// 1.上面的选项卡,点击某一个,当前背景颜色为紫色,其他的为灰色,排他思想
// 获取元素
let tab_lst = document.querySelector('.tab-lst');
let lis = tab_lst.querySelectorAll('li');
let items = document.querySelector('.tab-content').querySelectorAll('.item')
// for循环绑定点击事件
for (let i = 0; i < lis.length; i++){
lis[i].onclick = function(){
// 排他思想,先给所有元素设置clasName为空
for(let i = 0; i < lis.length; i++){
lis[i].className = '';
items[i].className = 'item';
}
// 设定自己的className
this.className = 'tab-lst-bg';
items[i].className = "item con-show";
};
}
</script>
</body>
</html>
效果如下:
注意:上面的实现效果是按照自己理解来写的代码,教程中用的是在js中给每个li设置index自定义属性,然后再获取index值,再通过index值来设置item的display属性,我觉得那个有一点繁琐,所以没放在这里。另外这个效果也可以通过CSS来实现。
6.5 H5自定义属性
自定义属性的目的:是为了保持并使用数据,有些数据可以保存在页面中而不用保存到数据库中。
通过getAttribute(“属性”)获取
但是有些自定义属性容易引起歧义,不容易判断是元素的内置属性还是自定义属性,因此H5给自定义属性设置了规范
h5规定自定义属性以**data-
**开头作为属性名
h5获取自定义属性用**document.dataget.属性
获取属性值,其中document.dateget
**获取的是所有的自定义属性的对象
如果定义属性有多个**-
连接,那么获取的时候需要采用驼峰命名法。例如自定义属性为data-name-index
,那么获取的时候需要用dataget.nameIndex
**
7.节点操作
7.1 获取元素的两种方式
- 利用DOM提供的方法获取元素
- document.getElementById()
- document.getElementByTagName()
- document.querySelector等等
- 逻辑性不强,繁琐
- 利用节点层级关系获取元素
- 利用父子兄节点关系获取元素
- 逻辑性强,但是兼容性稍差
7.2 节点概述
网页中的所有内容都是节点(标签、属性、文本、概述),在DOM中节点使用node来表示。
HTMl DOM树中的所有节点均可通过js进行访问,所有的html元素(节点)均可被修改,也可以创建或删除。
一般节点至少拥有nodeType(节点类型)、**nodeName(节点名称)和nodeValue(节点值)**三个基本属性。
- **元素节点:**nodeType 为 1,主要操作元素节点
- 属性节点:nodeType 为 2
- 文本节点:nodeType 为 3 (文本节点包含文字、空格、换行等)
7.3 节点层级
利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。
-
获取父级节点:
-
用node**.parentNode**获取父节点,
-
得到是离它最近的节点,不会获取祖节点;
-
如果找不到,返回为 null
-
代码示例,如下代码是先获取了元素,为了实现某个效果,需要操作它的父元素,按照之前的方式需要把父元素也要获取过来,不过现在有有的节点操作,可以直接用node**.parentNode**来获取父元素。
<body> <div class="outer"> <button>点我关闭</button> </div> <script> let btn = document.querySelector('button'); btn.onclick = function(){ console.log(btn.parentNode) } </script> </body>
控制台输出结果为:
-
-
获取子节点
-
用parentNode**.childNodes**获取子节点
- 得到是所有的子节点,包括元素节点、文本节点(如空格、换行等)等等。
- 如果只想要获得里面的元素节点,则需要专门处理,所以一般不使用node**.childNodes**。
-
用parentNode**.children**获取子元素节点
- 是一个只读属性,返回所有的子元素节点。
- 它只返回子元素节点,其余节点不返回。
- 实际开发常用的。
<body> <div class="outer"> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> </div> <script> let ul = document.querySelector('ul'); console.log(ul.children) </script> </body>
-
获取第一个子节点parentNode**.firstChild**,获取最后一个子节点用parentNode**.lastChild**
- 获取的是第一个或最后一个子节点,不管是元素还是文本
-
获取第一个子元素节点parentNode**.firstElementChild**,获取最后一个子元素节点用parentNode**.lastElementChild**
- 获取的是第一个或最后一个子元素节点
- 找不到则返回null
-
7.4 下拉菜单案例
要实现的是新浪网页面中的效果,如下动图所示。
实现以上效果,完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
a,li{
text-decoration:none;
text-indent:0;
list-style: none;
color: #252525;
font: 16px 微软雅黑;
cursor: pointer;
}
.outer{
background-color: #e1e1e1;
height: 40px;
}
.nav{
display: block;
height: 40px;
width: 300px;
clear: both;
margin: 0 auto;
/* background-color: aqua; */
}
.nav>li,a{
height: 40px;
line-height: 40px;
width: 100px;
float: left;
text-align: center;
cursor: pointer;
position: relative;
}
.nav a:hover,.nav ul li:hover{
background-color: #b5b5b5;
color: #f3ec6a;
}
.nav ul {
position: absolute;
top:40px;
left: 0;
width: 100%;
border-left: 2px solid #f3ec6a;
border-right: 2px solid #f3ec6a;
box-shadow: 2px 2px 5px 5px rgba(0,0,0,0.2);
display: none;
}
.nav ul li{
border-bottom: 2px solid #f3ec6a;
}
</style>
</head>
<body>
<div class="outer">
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li>私信</li>
<li>评论</li>
<li>@我</li>
</ul>
</li>
<li>
<a href="#">博客</a>
<ul>
<li>博客评论</li>
<li>未读评论</li>
</ul>
</li>
<li>
<a href="#">邮箱</a>
<ul>
<li>免费邮箱</li>
<li>VIP邮箱</li>
<li>企业邮箱</li>
<li>注册邮箱</li>
</ul>
</li>
</ul>
</div>
<script>
// 获取元素
let nav = document.querySelector('.nav');
// 获取li标签
let lis = nav.children;
// 循环注册事件
for (let i = 0;i<lis.length;i++){
lis[i].onmouseover = function(){
this.children[1].style.display = "block";
}
lis[i].onmouseout = function(){
this.children[1].style.display = "none";
}
}
</script>
</body>
</html>
运行效果如下:
7.5 兄弟节点
兄弟节点可以通过以下代码获取
节点名 | 语法 | 备注 |
---|---|---|
获取下一个兄弟节点 | node.nextSibling | 包含元素节点、文本节点、属性节点等等 |
获取上一个兄弟节点 | node.previousSibling | 包含元素节点、文本节点、属性节点等等 |
获取下一个兄弟元素节点 | node.nextElementSibling | 返回当前元素的下一个兄弟元素节点,找不则返回null |
获取上一个兄弟元素节点 | node.previousElementSibling | 返回当前元素的上一个兄弟元素节点,找不则返回null |
7.6 节点操作
名称 | 语法 | 说明 |
---|---|---|
创建节点 | document.createElement(‘tagName’) | 该方法创建由tagName指定的HTML元素,这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。 |
添加节点 | node.appendChild(添加的元素) | node是父节点,child 是子节点 在后面追加元素,类似数组中的push |
插入节点 | node.insertBefore(插入的元素,指定元素) | 在指定元素前面插入元素,两个参数是必须的。 |
删除节点 | node.removeChild(child) | node是父节点,child 是子节点 从DOM中删除一个子节点,返回删除的节点 |
复制节点 | node.cloneNode(node) | 返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点 |
7.7 留言板案例
案例效果如下所示
完整代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简单发布留言板</title>
<style>
.outer{
width: 500px;
margin: 50px auto;
}
.inner{
text-align: right;
}
textarea{
width: 500px;
height: 200px;
margin: 10px 0;
box-sizing: border-box;
}
ul{
list-style: none;
padding: 0;
margin: 0
}
li{
border-bottom: 1px solid #000;
margin-top: 5px;
clear: both;
}
li a{
float: right;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">
<textarea name="" id="" ></textarea>
<input type="submit" value="发布">
</div>
<ul>
<!-- <li>评论内容</li> -->
</ul>
</div>
<script>
// 获取元素
var text = document.querySelector('textarea');
var btn = document.querySelector('input');
var ul = document.querySelector('ul');
// 点击发布按钮
btn.onclick = function(){
if(text.value == ''){
alert('请输入内容');
return;
}else{
// 获取文本框的内容
var content = text.value;
// 创建li元素
var li = document.createElement('li');
// 将文本框的内容添加到li中,同时添加删除按钮,'javascript:;'阻止链接跳转
li.innerHTML = content + ' <a href="javascript:;">删除</a>';
// 将li添加到ul中
ul.insertBefore(li,ul.children[0]);
// 清空文本框
text.value = '';
// 删除功能
var a = document.querySelectorAll('a');
for(var i = 0; i < a.length; i++){
// 给每个a添加点击事件
a[i].onclick = function(){
// 删除当前a的父元素
ul.removeChild(this.parentNode);
}
}
}
}
</script>
</body>
</html>
上面案例的核心思路是:
1.点击按钮之后,就会动态创建一个li,添加到ul里面
2.创建li的同时,把文本域立面的值通过li.innerHTML
赋值给li并且添加删除按钮
3.如果想要新的留言在后面显示就用appendChild
,如果想要在前面显示就用insertBefore
4.给删除按钮添加事件,点击删除它的父元素,也就是li元素
7.8 动态生成表格案例
案例效果如下:
表格中的数据是动态获取的,页面中的表格元素均由js创建,完整代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态生成表格案例</title>
<style>
table {
width: 500px;
margin: 100px auto;
border-collapse: collapse;
text-align: center;
}
td,th {
border: 1px solid #333;
}
thead tr {
height: 40px;
background-color: #ccc;
}
tbody tr {
height: 30px;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<td>姓名</td>
<td>科目</td>
<td>成绩</td>
<td>操作</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1.先模拟从服务器获取到的数据
var datas = [
{
name: '张三',
subject: 'javascript',
score: 100
},
{
name: '李四',
subject: 'javascript',
score: 98
},
{
name: '王五',
subject: 'javascript',
score: 99
},
{
name: '赵六',
subject: 'javascript',
score: 88
}
];
// 2.获取tbody元素
var tbody = document.querySelector('tbody');
for (let i = 0; i < datas.length; i++) {
// 3.创建行
let tr = document.createElement('tr');
tbody.appendChild(tr);
// 4.创建单元格,单元格的数量取决于属性个数
for (let k in datas[i]) {
let td = document.createElement('td');
tr.appendChild(td);
// 5.单元格的内容取决于属性值
td.innerHTML = datas[i][k];
}
// 6.创建删除按钮
let td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除</a>';
tr.appendChild(td);
// 7.为删除按钮添加点击事件
let a = td.children[0];
a.onclick = function () {
tbody.removeChild(tr);
}
}
</script>
</body>
</html>
7.9 动态创建元素的区别
语法 | 说明 |
---|---|
document.write() | 直接将内容写入页面的内容流,但是文档流执行完毕后,页面会全部重绘,这个方法不常用 |
element.innerHTML | 将内容写入摸个DOM节点,不会导致页面全部重绘 创建多个元素效率更高(不要拼接字符串,采取数组的形式拼接),结构稍微复杂 |
createElement() | 创建多个元素效率稍微低一点点,但是结构更清晰 |
8.DOM重点核心总结
- 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或XML)的标准编程接口。
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构、样式。
-
在DOM中把整个页面划分为一个由文档、元素、节点组成的树形结构。
-
**文档:**一个页面就是一个文档,DOM中使用document表示。
-
**元素:**页面中所有的标签都是元素,DOM中使用element表示。
-
**节点:**网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示。
-
-
关于dom操作,我们主要针对于元素的操作,主要有创建、增、删、改、查、属性操作、事件操作。
语法 | 说明 | |
---|---|---|
创建 | 1.document.write() | |
创建 | 2.element.innerHTML | |
创建 | 3.createElement() | |
增 | 1.appendChild | 在后面添加 |
增 | 2.insertBefore | 在前面添加 |
删 | 3.removeChild | |
改 | 1.src\href\title等 | 修改元素属性 |
改 | 2.innerHTML\innerText | 修改普通元素内容 |
改 | 3.value\type\disable等 | 修改表单元素 |
改 | 4.style\className | 修改元素样式 |
查 | 1.getElementById\getElementByTagName | DOM提供的API方法,用法古老不推荐 |
查 | 2.querySelector\querySelectorAll | H5提供的新方法,推荐 |
查 | 3.父(parentNode)、子(children)、兄(previousElementSibiling\nextElementSibing) | 利用节点操作获取元素,推荐 |
属性操作 | 1.setAttribute | 设置dom的属性值 |
属性操作 | 2.getAttribute | 获取dom的属性值 |
属性操作 | 3.removeAtribute | 移除属性 |
- 事件操作,主要是鼠标事件,具体如下表
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |