这篇文章讲解了修改元素属性,自定义属性,节点的增删添加删除等操作
这篇文章实在是太长了,里面主要有一些代码占据了很多的空间,我尝试能不能把他们折叠起来
这篇博客是初学者写下的笔记,如有错误,欢迎前来指正!
最后推荐大家看这部分知识点的总结,六分钟回顾一下这里的知识点
<body>
<button>按钮1button>
<button>按钮2button>
<button>按钮3button>
<script>
// 1. 获取所有按钮元素
var btns = document.querrySelectorAll('button');
// 返回含有三个button的伪数组
for (var i = 0; i < btns.length; i++) {
// 为背景颜色添加事件
btns[i].onclick = function() {
// 先把所有的背景颜色清空,防止出现多个被选中的状态
for (var i = 0; i < btns.length; i++) {
btns[i].style.backgroundColor = '';
}
// 改变按钮的背景颜色
this.style.backgroundColor = 'blue';
}
}
script>
body>
<head>
<style>
ul li {
float: left;
list-style: none;
}
.color ul li:first-child {
height: 40px;
width: 40px;
}
.color ul li:nth-child(2) {
height: 40px;
width: 40px;
}
.color ul li:nth-child(3) {
height: 40px;
width: 40px;
}
.color ul li:last-child {
height: 40px;
width: 40px;
}
style>
head>
<body>
<div class="color">
<ul>
<li><img src="1.ipg" alt="">li>
<li><img src="2.jpg" alt="">li>
<li><img src="3.jpg" alt="">li>
<li><img src="4.jpg" alt="">li>
ul>
div>
<script>
var items = document.querySelector('.color'). querySelectorAll('img');
console.log(items);
for (var i = 0; i < items.length; i++) {
items[i].onclick = function () {
console.log(this.style.backgroundColor);
// 这里需要注意一下,这里需要两边加上url()
document.body.style.backgroundColor = 'url(' +this.src+')';
}
}
script>
body>
<body>
<div class="table">
<div class="thead">表头div>
<div class="tbody">
<ul>
<li>行1<li>
<li>行2<li>
<li>行3<li>
ul>
div>
div>
<script>
// 多重选择
var tbody = document.querySelector('.tbody'). querySelectorAll('li');
for (var i = 0; i < tbody.length; i++) {
// 鼠标经过事件
tbody[i].onmouseover = function() {
this.style.backgroundColor = 'gray';
}
// 鼠标离开事件
tbody[i].onmouseout = function() {
this.style.backgroundColor = '';
}
}
script>
body>
要求:有一个全选按钮,当所有元素都被选中时他也被选中,反之只要有一个还是没有选中的状态他就没有选中,点击他可以实现全选与非全选之间的切换,同样,下面有一个按钮未选中时全选按钮就不选中,下面所有按钮选中时上面全选按钮选中
操作思路:
代码示例:
<body>
<div class="checkall"><input type="checkbox">全选div>
<div>
<dl>
<dd><input type="checkbox">dd>
<dd><input type="checkbox">dd>
<dd><input type="checkbox">dd>
dl>
div>
<script>
var dtinput = document.querySelector('.checkall').querySelector('input');
var ddinput = document.querySelector('dl').getElementsByTagName('input');
// 全选按钮影响下面的按钮
dtinput.onclick = function () {
for (var i = 0; i < ddinput.length; i++) {
// 这里十分巧妙,让下面的普通复选框保持和全选复选框一样的状态就可以了
ddinput[i].checked = this.checked;
}
}
// 下面按钮影响全选按钮
for (var i = 0; i < ddinput.length; i++) {
ddinput[i].onclick = function () {
// 这个flag一定要放在function里面,否则会出现下面的按钮全选,而上面的全选按钮没有选上
var flag = true;
for (var i = 0; i < ddinput.length; i++) {
if (!ddinput[i].checked) {
flag = false;
// 这里是为了提高运行效率
break;
}
}
dtinput.checked = flag;
}
}
script>
body>
获取属性:
可以使用element.属性
来获取元素属性值
或者通过element.getAttribute('属性')
获取属性
代码示例:
<body>
div>
<script>
var div = document.querrySelector('div');
// element.属性
console.log(div.id);
// element.getAttribute('属性')
console.log(div.getAttribute('index'));
script>
body>
-
两者区别:
element.属性
:获取元素本身自带的属性 (无法获取自定义属性)
element.getAttribute('属性')
:获取程序员自己定义的属性(自定义属性)
-
修改属性:
-
element.属性
同样可以改变元素的属性值
-
还可以通过element.setAttribute('属性','值');
来修改元素属性值 (同样针对自定义属性值,但是也能修改普通的属性)
小知识:用element.属性
修改class属性时应该写element.className
- 删除属性:
- 移除属性:
removeAttribute('属性')
操作元素属性值实例:tab栏切换
- 点击不同的标签显示不同的内容
- 这里面的难点,不知道点击哪个li
- 解决方法,给 li 添加自定义属性例如
index
等于从 0 到 4 然后通过 this 来取出哪个要显示的标签
<head>
<style>
li {
list-style: none;
}
.headbox {
height: 50px;
}
.headbox ul li {
float: left;
height: 48px;
width: 100px;
background-color: #a7a3a3;
text-align: center;
line-height: 50px;
margin-left: 10px;
}
.footbox {
display: none;
height: 200px;
width: 100%;
background-color: #a7a7a7;
font-size: 24px;
text-align: center;
line-height: 200px;
z-index: 0;
}
.tagbox .selected {
background-color: red;
color: white;
}
style>
head>
<body>
<div class="tagbox">
<div class="headbox">
<ul>
<li index="0">商品介绍li>
<li index="1">规格与包装li>
<li index="2">售后保障li>
<li index="3">商品评价li>
ul>
div>
<div class="footbox" style="display:block;">产品介绍div>
<div class="footbox">规格与包装div>
<div class="footbox">售后保障div>
<div class="footbox">商品评价div>
div>
<script>
var tab = document.querySelector('.headbox').querySelectorAll('li');
var items = document.querySelectorAll('.footbox');
// 点击一个按钮后按钮变色
for (var i = 0; i < tab.length; i++) {
tab[i].onclick = function () {
// tag标签变色
for (var i = 0; i < tab.length; i++) {
tab[i].className = '';
}
this.className = 'selected';
// 显示内容变化
var index = this.getAttribute('index');
console.log(index);
for (var i = 0; i < items.length; i++) {
items[i].style.display = 'none';
}
items[index].style.display = 'block';
}
}
script>
body>
- 刚开始我尝试自己做的时候,就陷入了一个误区,我当时认为可以通过外面给 li 注册事件的循环计数的 i 可以知到我点击的是哪个 li,但是注册事件是一次注册完成的,就是说你无论点击哪个 li,他能获取到的 i 的值都是 4 (刚开始我看到这个 4 还十分奇怪,后来仔细想想 for 循环是先++再判断,所以最后 i 值是 4),所以外层循环的 i 是没有价值的
- 然后我又琢磨了好长时间,当时的我既不知到 this 来知到我们选择的是哪个元素又想不出穿透作用域的方法,后来接着看老师的视频,才发现如此简单
- 这里简单总结一下,其实很简单,通过 this 指针来知到我们点击的是哪个 li 在和下面的div相对应,然后就可以实现点击不同标签出现不同内容的效果了
H5自定义属性
-
自定义属性目的是保存数据
-
自定义属性通过element.getAttribute('属性')
获取
-
为了区分自带的属性和我们自己定义的自定义属性,H5做出如下规范
- H5规定自定义属性用
data-属性
作为自定义属性名
-
新方法:可以通过element.dataset.属性名
或者element.dataset['属性名']
(IE11兼容)
- 注意:属性名前面不用加
data-
了
element.dataset
存放了所有以 data 开头的属性 (也就是自定义属性)
- 自定义属性里面有多个-连接,dataset后面的用小驼峰命名法
-
代码示例:
<body>
<div data-list-name="andy">div>
<script>
var div = document.querySelector('div');
// 这是个特例,需要注意下
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
script>
body>
节点操作
-
通过节点层级关系获取元素
-
节点包括:文档,元素,属性,文本
-
一个节点至少包括nodeType(节点类型) nodeName(节点名称) nodeValue(节点值)
-
其中nodeType分类:
- 元素节点nodeType = 1
- 属性节点nodeType = 2
- 文本节点nodeType = 3 (包括文字,空格,换行)
节点层级
- 分为父子兄三种关系
父节点
- 父节点
parentNode
- 同样是就近原则,返回的是最近的父节点
- 没有返回null
- 代码示例:
<body>
<div class="box">
<span class="ada">span>
div>
<script>
var ada = documnet.querySelector('.ada');
// 获取父节点
console.log(ada.parentNode);
script>
body>
子节点
-
所有子节点 childNodes
-
这种子节点方法会返回文本节点和元素节点,如果我们只想要元素节点的话,我们根据 nodeType 来区分
-
只获取元素的子节点children
-
代码示例:
<body>
<ul>
<li>li>
<li>li>
<li>li>
ul>
<script>
var ul = document.querySelector('ul');
console.log(ul.childNodes);
// 这时返回 7 个节点,里面包括四个文本节点 (包括换行)
console.log(ul.children);
// 这时只输出三个 li
script>
body>
-
获取子节点 (同样会获取文本节点)
- 第一个节点
firstChild
- 最后一个节点
lastChild
-
获取子元素节点 (有兼容性问题 IE9以上支持)
- 第一个元素节点
firstElementChild
- 最后一个元素节点
lastElementChild
-
实际开发写法ul.children[0]
(这不挺正常)
- 最后一个的写法
ul.children[ul.children.length - 1]
节点操作实例:下拉菜单
- 鼠标一经过,显示下拉菜单,离开时隐藏下拉菜单
- 这里使用定位来确定这两个下拉菜单,注册鼠标经过与鼠标离开两个事件
- 代码如下:
<head>
<style>
ul,
li {
list-style: none;
margin: 0;
padding: 0;
}
.tag ul li {
float: left;
padding: 10px;
position: relative;
}
.tag ul li a {
height: 30px;
width: 40px;
background-color: yellow;
}
.tag ul li ul {
position: absolute;
display: none;
}
.tag ul li ul li {
height: 40px;
width: 50px;
background-color: #dd72bd;
}
style>
head>
<body>
<div class="tag">
<ul>
<li>
<a href="#">下拉菜单1a>
<ul>
<li>目录1li>
<li>目录2li>
<li>目录3li>
ul>
li>
<li>
<a href="#">下拉菜单2a>
<ul>
<li>目录1li>
<li>目录2li>
<li>目录3li>
ul>
li>
ul>
div>
<script>
var tag = document.querySelector('.tag');
// 找到两个li
var lis = tag.querySelector('ul').children;
console.log(lis);
for (var 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>
兄弟节点
-
获取上一个兄弟节点的方式:node.previousSibling
-
获取下一个兄弟节点的方式:node.nextSibling
- 这两种种获取方式都包括文本节点
-
获取下一个元素兄弟节点:node.nextElementSibling
-
获取上一个元素兄弟节点:node.previousElementSibling
- 这两种方法有兼容性问题,IE9以上支持
- 解决兼容性方法:写一个兼容性的函数
创建和添加节点
- 动态创建元素节点
document.createElement('tagname')
- 创建完节点之后还要把节点添加到某个地方
- 添加 (插入) 节点:
node.appendChild(child)
- 给父节点 node 节点添加一个元素 child 在父元素的末尾 (类似于 after 伪元素)
- 代码示例:
<body>
<ul>ul>
<script>
var ul = document.querySeletor('ul');
// 创建节点
var li = document.createElement('li');
// 添加节点
ul.appendChild(li);
script>
body>
- 第二种添加 (插入) 方法:
node.insertBefore(child,指定元素)
- 在指定元素前面插入
创建/添加节点案例:留言板
-
在一个文本框内输入后点击提交后会在下方出现一个 li 来展示输入的内容
-
小知识:text.value
获取文本框里的文字
- 通过
li.innerHTML
把值给li
-
代码示例:
<body>
<div class="comments">
<input type="text"><button>提交button>
<ul>ul>
div>
<script>
// 获取元素
var btn = document.querySelector('button');
var text = document.querySelector('input');
var ul = document.querySelector('ul');
// 注册按钮事件
btn.onclick = function () {
if (text.value == '') {
alert('您还没有输入');
return false;
} else {
// 创建元素
var li = document.createElement('li');
// 给li里面赋值
li.innerHTML = text.value;
// 添加元素
ul.appendChild(li);
}
}
script>
body>
- 如果想让最新的评论显示在最上面的话把
ul.appendChild(li)
改成node.insertBefore(li,ul.children[0])
就可以了
删除节点
-
删除某个节点的方法:node.removeChlid(child)
- 删除父节点中的一个子节点,返回删除的节点
-
代码示例:
<body>
<ul>
<li>1li>
<li>2li>
<li>3li>
ul>
<script>
// 获取父元素
var ul = document.querrySelector('ul');
// 开始删除
ul.removeChild(ul.children[0]);
script>
body>
删除节点案例:删除留言
- 接着上一个示例做
- li 后面有一个链接,当点击链接的时候,删除这个 li
- 代码示例:
// 获取元素
var btn = document.querySelector('button');
var text = document.querySelector('input');
var ul = document.querySelector('ul');
// 注册按钮事件
btn.onclick = function () {
if (text.value == '') {
alert('您还没有输入');
return false;
} else {
// 创建元素
var li = document.createElement('li');
// 给li里面赋值
li.innerHTML = text.value + "删除";
// 添加元素
ul.appendChild(li);
}
}
var as = document.querySelectorAll('a');
for(var i = 0;i<as.length;i++) {
as[i].oncilck = function() {
// 这里删除的是 ul 的子元素 li ,但是是这个事件 a 的父元素
ul.removeChild(this.parentElement);
}
}
- 样式尽量通过css修改
- 阻止链接跳转可以使用
javascript:void(0);
或者 javascript:;
复制节点
- 复制节点的方法:
node.cloneNode()
- 返回这个节点的一个副本
- 注意:参数为空或者为 flase 则为浅拷贝,只复制节点本身,不复制里面的子节点(包括内容)
- 括号里为 true 时为深拷贝
<body>
<ul>
<li>1li>
<li>2li>
<li>3li>
ul>
<script>
// 获取父元素
var ul = document.querrySelector('ul');
// 开始复制
var li = ul.chlidren[0].cloneNode();
// 把复制的节点放入ul里面
ul.appendChild(li);
// 浅拷贝只复制了节点
script>
body>
动态表格示例
- 使用动态数据 (在js里面使用数据)
- 这个主要是通过这个示例来把 json 数据 和 js 联系起来,然后又复习了节点操作
- 代码示例:
<head>
<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;
}
style>
head>
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名th>
<th>科目th>
<th>成绩th>
<th>操作th>
tr>
thead>
<tbody>
tbody>
table>
<script>
// 感觉这个就是 json 文件里的东西
var datas = [{
name: '小铭',
subject: 'JavaScript',
score: 100
}, {
name: '子程序',
subject: 'JavaScript',
score: 90
}, {
name: '海洋哥',
subject: 'JavaScript',
score: 80
}, {
name: 'zzmc',
subject: 'JavaScript',
score: 70
}];
// 动态生成表格
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
// 创建四行 tr
var tr = document.createElement('tr');
tbody.appendChild(tr);
// 创建单元格 td
for (var k in datas[i]) {
var td = document.createElement('td');
// 把值赋给单元格
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
// 创建删除单元格
var td = document.createElement('td');
td.innerHTML = "删除";
tr.appendChild(td);
td.onclick = function () {
tbody.removeChild(this.parentElement);
}
}
script>
body>
三种动态创建元素的区别
-
document.white()
使用很少 (不推荐)
- 代码示例:
document.white('123');
// 新建一个页面,里面只显示div一个元素
- 这种方法如果文档流执行完毕 (页面显示完毕),这种写法会导致重绘页面
- 重绘页面:新建一个网页,里面只显示white里的元素
-
innerHTML
创建元素
- 代码示例:
// 前面有个 div 标签,类名叫 inner
var inner = document.querySelector('.inner');
inner.innerHTML = '123';
- 字符串不可变性,所以在大量创建的时候耗时较长 (拼接字符串时间较长)
- 改进方法:新建一个数组,把要添加的标签放在数组里,然后通过 join 来一起给添加 (效率极高,甚至比createElement还高)
- 改进方法示例:
for(var i = 0;i < 1000;i++) {
array.push('123');
}
document.body.innerHTML = array.join('');
// 运行效率极高,达到几毫秒级别
-
document.createElement('tagname')
创建元素
- 代码示例:
// 前面依旧有一个 div 标签,类名叫 inner
var inner = document.querySelector('.inner');
var a = document.createElement('a');
inner.appendChild(a);