1 DOM文档对象模型
(1).获取元素
1.document.getEelementById(’’):获取元素信息
2.getElementsByTagName(’’):通过html标签名获取某一类元素
3.getElementsByClassName(’’):根据类名返回元素对象的集合
4.querySelect(‘选择器’):根据指定选择器返回第一个元素对象
5.querySelectAll(‘选择器’):返回选择器所有元素对象的集合
(2).事件基础
1.element.innerText:可以获取元素的内容根据需求修改
2.innerHtml:获取元素的内容(可以识别html标签)
// 点击显示当前时间
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.onclick = function() {
div.innerText = getDate();
}
function getDate() {
var date = new Date();
var year = date.getFullYear(); // 年
var minth = date.getMonth()+1; // 月,数组是重0号的索引开始的
var dates = date.getDate(); // 日
var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
var day = date.getDay(); //返回一周的第几天,下标和月份一样,重0开始
var hours = date.getHours() //时
var minutes = date.getMinutes() //分
var second = date.getSeconds() //秒
return '今天是'+year+'年'+minth+'月'+dates+'号'+arr[day]+hours+'时'+minutes+'分'+second+'秒';
}
(3).仿京东隐藏密码案例
<body>
<div class="box">
<label for="">
<img src="png/闭眼.jpg" alt="" id="eye">
</label>
<input type="password" name="" id="pwd">
</div>
<script>
//1.获取元素
var eye = document.getElementById('eye');
var pwd = document.getElementById('pwd');
var flg = 0;
//2.注册事件,处理程序
eye.onclick = function() {
if(flg == 0) {
pwd.type = 'text';
eye.src = 'png/睁眼.jpg';
flg = 1;
} else {
pwd.type = 'password';
eye.src = 'png/闭眼.jpg';
flg = 0;
}
}
</script>
</body>
(4).操作元素——获取焦点(onfocus)和失去焦点(onblur)。
显示隐藏文本框内容
<body>
<input type="text" value="手机">
<script>
// 1.获取元素
var text = document.querySelector('input');
// 2.注册事件,获取焦点
text.onfocus = function() {
console.log('获取了焦点');
if(this.value ==='手机') {
this.value = '';
}
// 获得焦点需要把文本框里面的文字颜色变黑
this.style.color = 'black';
}
// 3.注册事件,失去焦点
text.onblur = function() {
console.log('失去焦点');
if(this.value === '') {
this.value = '手机';
}
// 失去焦点需要把文本框里面的文字颜色变浅
this.style.color = '#999';
}
</script>
</body>
(5).密码框验证信息.
<style>
input {
width: 200px;
margin: 100px auto;
}
.message {
display: inline-block;
font-size: 12px;
color: #999;
background:url(png/睁眼.jpg) no-repeat left center;
padding-left: 50px;
}
.wrong {
color: red;
background: url(png/闭眼.jpg);
}
.right {
color: green;
background: url(png/闭眼.jpg);
}
</style>
<!--分隔线-->
<div class="register">
<input type="password" class="ipt">
<p class="message">请输入6~16位密码</p>
</div>
<script>
// 密码框验证信息
// 1.获取元素
var ipt = document.querySelector('.ipt');
var message = document.querySelector('.message');
// 2.注册事件 获取焦点
ipt.onblur = function() {
//根据表单里面的长度 ipt.value.length
if(ipt.value.length >= 6 && ipt.value.length <= 16) {
// console.log('输入正确');
message.className = 'message right';
message.innerHTML = '您输入的位数符合要求';
} else {
message.className = 'message wrong';
message.innerHTML = '您输入的位数不够';
}
}
</script>
(6).百度换肤效果.
<body>
<ul class="baidu">
<li><img src="images/1.jpg"></li>
<li><img src="images/2.jpg"></li>
<li><img src="images/3.jpg"></li>
<li><img src="images/4.jpg"></li>
</ul>
<script>
// 1.获取元素
var imgs = document.querySelector('.baidu').querySelectorAll('img');
var bodys = document.body; //注意获取body标签的方式
// 2.循环注册事件
for(var i = 0; i < imgs.length; i++) {
imgs[i].onclick = function() {
console.log(this.src);
bodys.style.backgroundImage = 'url('+this.src+')';
}
}
</script>
</body>
(6).全选和取消全选.
<body>
<div class="wrap">
<table>
<thead>
<tr>
<th>
<input type="checkbox" id="j_cbAll" />
</th>
<th>商品</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPhone8</td>
<td>8000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPad Pro</td>
<td>5000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPad Air</td>
<td>2000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Apple Watch</td>
<td>2000</td>
</tr>
</tbody>
</table>
</div>
<script>
// 1. 全选和取消全选 做法:让下面所有复选框的checked属性(选中状态) 跟随 全选按钮即可
// 获取元素
var j_cbAll = document.getElementById('j_cbAll');
var j_tb = document.getElementById('j_tb').getElementsByTagName('input'); //下面所有的复选框
// 注册事件
j_cbAll.onclick = function() {
// console.log(this.checked); //它可以得到当前复选框的选中状态如果是true 就是选中,如果是false 就是未选中
for(var i = 0; i < j_tb.length; i++) {
j_tb[i].checked = this.checked;
}
}
// 2. 下面复选框需要全部选中, 上面全选才能选中 做法: 给下面所有复选框绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有一个没选中的, 上面全选就不选中。
for(var i = 0 ; i < j_tb.length; i++) {
j_tb[i].onclick = function() {
var flag = true;
// 每次点击下面的复选框都要循环检查者4个小按钮是否全被选中
for(var i = 0; i < j_tb.length; i++) {
if(!j_tb[i].checked) {
flag = false; //如果一个没选中就把flag=false;
break;
}
}
// 如果flag = true,就把全选按钮也选中;
j_cbAll.checked = flag;
}
}
</script>
</body>
(7).tab栏切换
核心思路:使用自定义属性lis[i].setAttribute(‘index’, i) ;给每一个要显示的div设置一个重零开始的索引。
<!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>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
.tab {
width: 978px;
margin: 100px auto;
}
.tab_list {
height: 39px;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab_list li {
float: left;
height: 39px;
line-height: 39px;
padding: 0 20px;
text-align: center;
cursor: pointer;
}
.tab_list .current {
background-color: #c81623;
color: #fff;
}
.item_info {
padding: 20px 0 0 20px;
}
.item {
display: none;
}
</style>
</head>
<body>
<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价(50000)</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab_con">
<div class="item" style="display: block;">
商品介绍模块内容
</div>
<div class="item">
规格与包装模块内容
</div>
<div class="item">
售后保障模块内容
</div>
<div class="item">
商品评价(50000)模块内容
</div>
<div class="item">
手机社区模块内容
</div>
</div>
</div>
<script>
// 获取元素
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
var items = document.querySelectorAll('.item');
// for循环绑定点击事件
for (var i = 0; i < lis.length; i++) {
// 开始给5个小li 设置索引号
lis[i].setAttribute('index', i);
lis[i].onclick = function() {
// 1. 上的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变(排他思想) 修改类名的方式
// 干掉所有人 其余的li清除 class 这个类
for (var i = 0; i < lis.length; i++) {
lis[i].className = '';
}
// 留下我自己
this.className = 'current';
// 2. 下面的显示内容模块
var index = this.getAttribute('index');
console.log(index);
// 干掉所有人 让其余的item 这些div 隐藏
for (var i = 0; i < items.length; i++) {
items[i].style.display = 'none';
}
// 留下我自己 让对应的item 显示出来
items[index].style.display = 'block';
}
}
</script>
</body>
</html>
2.H5新属性
(1).H5规定自定义属性data-开头做为属性名并且赋值。
比如<div data-index= "1”></div>
(2).获取H5自定义属性
1.兼容性获取element.getAttribute( 'data-index’);
2.H5新增element.dataset.index或者element.dataset['index’ ] ie11才开始支持的;
<script>
var div = document.querySelector('div');
// console.log(div.getTime);
console.log(div.getAttribute('getTime'));
div.setAttribute('data-time', 20);
console.log(div.getAttribute('data-index'));
console.log(div.getAttribute('data-list-name'));
// h5新增的获取自定义属性的方法 它只能获取data-开头的
// dataset 是一个集合里面存放了所有以data开头的自定义属性
console.log(div.dataset);
console.log(div.dataset.index);
console.log(div.dataset['index']);
// 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
</script>
(3).新浪下拉菜单案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
a {
text-decoration: none;
font-size: 14px;
}
.nav {
margin: 100px;
}
.nav>li {
position: relative;
float: left;
width: 80px;
height: 41px;
text-align: center;
}
.nav li a {
display: block;
width: 100%;
height: 100%;
line-height: 41px;
color: #333;
}
.nav>li>a:hover {
background-color: #eee;
}
.nav ul {
display: none;
position: absolute;
top: 41px;
left: 0;
width: 100%;
border-left: 1px solid #FECC5B;
border-right: 1px solid #FECC5B;
}
.nav ul li {
border-bottom: 1px solid #FECC5B;
}
.nav ul li a:hover {
background-color: #FFF5DA;
}
</style>
</head>
<body>
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
</ul>
</body>
<script>
// 1.获取元素
var nav = document.querySelector('.nav');
var lis = nav.children; //得到四个小li
// 2.循环注册事件
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>
</html>
(4).创建节点,添加节点——一般用于发布的评论
创建:document.createElement(‘tagName’);
添加在尾部:node.appendChild(child);
添加在头部:node.insertBefore(child);
删除节点:node.removeChild(child);
(node 父级,child 是子级,后面追加元素,类似于数组中的push)
<body>
<ul>
<li>123</li>
</ul>
<script>
// 1. 创建节点元素节点
var li = document.createElement('li');
// 2. 添加节点 node.appendChild(child) node 父级 child 是子级 后面追加元素 类似于数组中的push
var ul = document.querySelector('ul');
ul.appendChild(li);
// 3. 添加节点 node.insertBefore(child, 指定元素);
var lili = document.createElement('li');
ul.insertBefore(lili, ul.children[0]);
// 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
</script>
</body>
(4).评论留言显示,删除留言案例
<body>
<textarea name="" id=""></textarea>
<button>发布</button>
<ul>
</ul>
<script>
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
btn.onclick = function() {
if(text.value === '') {
alert('您没有输入内容!')
return false;
} else {
// 1.创建元素
var li = document.createElement('li');
// 先有li 才能赋值
li.innerHTML = text.value + '<a href="javasrcipt:;">删除</a>'
// 2.添加元素
ul.insertBefore(li,ul.children[0]);
// 3.删除元素
var as = document.querySelectorAll('a');
for (let index = 0; index < as.length; index++) {
as[index].onclick = function() {
// 删除的是li 是a当前所在的li this.parentNode
ul.removeChild(this.parentNode);
}
}
// 清除文本框内容
text.value = '';
}
}
</script>
</body>
(5).js实现动态表格生成案例(主要包含节点操作)
<!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>
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>
// 1.先去准备好学生的数据
var datas = [{
name: '魏璎珞',
subject: 'JavaScript',
score: 100
}, {
name: '弘历',
subject: 'JavaScript',
score: 98
}, {
name: '傅恒',
subject: 'JavaScript',
score: 99
}, {
name: '明玉',
subject: 'JavaScript',
score: 88
}, {
name: '大猪蹄子',
subject: 'JavaScript',
score: 0
}];
// 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) { // 外面的for循环管行 tr
// 1. 创建 tr行
var tr = document.createElement('tr');
tbody.appendChild(tr);
// 2. 行里面创建单元格(跟数据有关系的3个单元格) td 单元格的数量取决于每个对象里面的属性个数 for循环遍历对象 datas[i]
for (var k in datas[i]) { // 里面的for循环管列 td
// 创建单元格
var td = document.createElement('td');
// 把对象里面的属性值 datas[i][k] 给 td
// console.log(datas[i][k]);
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
// 3. 创建有删除2个字的单元格
var td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除 </a>';
tr.appendChild(td);
}
// 4. 删除操作 开始
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
// 点击a 删除 当前a 所在的行(链接的爸爸的爸爸) node.removeChild(child)
tbody.removeChild(this.parentNode.parentNode)
}
}
// for(var k in obj) {
// k 得到的是属性名
// obj[k] 得到是属性值
// }
</script>
</body>
</html>
3.事件高级
(1).addEventListtener() 事件监听方式
eventTarget.addEventListener(‘type’,listener[, useCapture])
eventTarget.addEventListener()方法将指定的监听器注册到eventTarget (目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
<body>
<button>传统注册事件</button>
<button>方法监听注册事件</button>
<script>
var btns = document.querySelectorAll('button');
// 1. 传统方式注册事件
btns[0].onclick = function() {
alert('hi');
}
btns[0].onclick = function() {
alert('hao a u');
}
// 2. 事件侦听注册事件 addEventListener
// (1) 里面的事件类型是字符串 必定加引号 而且不带on
// (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click', function() {
alert(22);
})
btns[1].addEventListener('click', function() {
alert(33);
})
</script>
</body>
(2).事件对象使用语法
eventTarget.onclick = function (event) {
//这个event 就是事件对象,我们还喜欢的写成e或者evt
}
(3).事件对象阻止冒泡事件的方法
阻止冒泡 dom 推荐的标准: e.stopPropagation();
非标准:e.cancelBubble = true
<head>
<style>
.father {
overflow: hidden;
width: 300px;
height: 300px;
margin: 100px auto;
background-color: pink;
text-align: center;
}
.son {
width: 200px;
height: 200px;
margin: 50px;
background-color: purple;
line-height: 200px;
color: #fff;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son儿子</div>
</div>
<script>
// 常见事件对象的属性和方法
// 阻止冒泡 dom 推荐的标准 stopPropagation()
var son = document.querySelector('.son');
son.addEventListener('click', function(e) {
alert('son');
e.stopPropagation(); // stop 停止 Propagation 传播
e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
}, false);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
alert('father');
}, false);
document.addEventListener('click', function() {
alert('document');
})
</script>
</body>