1. 初识DOM
DOM: 文档对象模型
是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。
w3c已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式。
DOM树:
文档:一个页面就是一个文档, DOM中使用document来表示;
元素:页面中的所有标签都是元素,DOM中用element表示;
节点:网页中的 [所有内容] 都是节点(标签,属性,文本,注释等),DOM中使用node表示。
1.1
获取元素1
<!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>
</head>
<body>
<div id="time">Hello World</div>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
<ul id="ID">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
//1. getElementById():以对象的形式返回
var obj = document.getElementById('time');
// console.log(obj);
// console.log(typeof obj);
//console.dir(): 列出了对象的详细信息
// console.dir(obj);
//2. getElementsByTagName():以伪数组的形式返回:所有的li的集合
var lis = document.getElementsByTagName('li');
console.log(lis);
for(var i =0;i < lis.length;i++) {
console.log(lis[i]);
}
console.log('--------------------------');
var ul = document.getElementById("ID"); //ID下的li的集合
var liss = ul.getElementsByTagName("li");
console.log(liss);
for(var i =0;i < liss.length;i++) {
console.log(liss[i]);
}
</script>
</body>
</html>
1.2
获取元素2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=b, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
getElementsByClassName(): => html5
querySelector('选择器') => html5 返回指定选择器的第一个对象,选择器要加符号,.box,#nav;
querySelectorAll: => html5 返回选择器里的所有元素对象的集合 ;
-->
<div class="box">盒子1</div>
<div class="box">盒子2</div>
<div id="nav">
<ul>
<li>首页</li>
<li>产品</li>
</ul>
</div>
<script>
//
var Box = document.getElementsByClassName('box');
console.log(Box);
//
var firstbox = document.querySelector('.box');
console.log(firstbox);
var nav = document.querySelector('#nav');
console.log(nav);
var firstli = document.querySelector('li');
console.log(firstli);
//
var allbox = document.querySelectorAll('.box');
console.log(allbox);
</script>
</body>
</html>
1.3
获取元素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>
</head>
<body>
<script>
//1.获取body元素
console.log(document.body);
//2获取html元素
console.log(document.documentElement);
</script>
</body>
</html>
2. 属性操作
2.1
修改样式属性1
<!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>
div {
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<!--
通过element.style 修改样式;
-->
<div></div>
<script>
var div = document.querySelector('div');
div.onclick = function() {
this.style.backgroundColor = 'purple';
}
</script>
</body>
</html>
2.2
修改样式属性2
<!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>
div {
width: 100px;
height: 100px;
background-color: pink;
}
.change {
background-color: purple;
color: #fff;
font-size: 25px;
margin-top: 100px;
}
</style>
</head>
<body>
<!--
通过element.className 修改样式;
-->
<div class="first">文本</div>
<script>
// [1.] 使用 element.style 获得修改元素样式 如果样式比较少 或者 功能简单的情况下使用
var test = document.querySelector('div');
test.onclick = function () {
// this.style.backgroundColor = 'purple';
// this.style.color = '#fff';
// this.style.fontSize = '25px';
// this.style.marginTop = '100px';
// [2.] 我们可以通过 修改元素的className更改元素的样式 适合于样式较多或者功能复杂的情况;
// [3.] className会覆盖原先的类名; (通过浏览器调试就可以看出)
// this.className = 'change';
// [4.] 如果想要保留原先的类名,我们可以这么做 多类名选择器;
this.className = 'first change';
}
</script>
</body>
</html>
2.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>
<!--
1. element.属性;
2. getAttribute()/setAttribute();
3. removeAttribute();
-->
</head>
<body>
<div id="demo" index="1" class="nav"></div>
<script>
var div = document.querySelector('div');
// [1.] 获取元素的属性值(获取内置的属性值, 元素本身自带的属性)
// (1) element.属性;
console.log(div.id);
// (2) element.getAttribute('属性') (既可以获取内置的属性值, 又可以获取自定义属性值)
console.log(div.getAttribute('id'));
console.log(div.getAttribute('index')); //获取自定义属性值
/******************************************************************************************************/
// [2.] 设置元素属性值
// (1) element.属性= '值';
div.id = 'test';
div.className = 'navs';
// (2) element.setAttribute('属性', '值'); 主要针对于自定义属性
div.setAttribute('index', 2);
div.setAttribute('class', 'footer');
/******************************************************************************************************/
// [3.] 移除属性 removeAttribute(属性)
div.removeAttribute('index');
</script>
</body>
</html>
2.4
H5自定义属性
<!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 style="color: red" getTime="20" data-index="2" data-list-name="andy"></div>
<script>
var div = document.querySelector('div');
console.log(div.getTime); //undefined(因为不是内置属性)
console.log(div.getAttribute('getTime')); //20
console.log('-------------------------------');
/*
通过以上可以看出:自定义属性的属性值不能通过element.属性来获取, 必须通过getAttribute()来获取;
h5新增自定义属性的方法, 约定属性只能以data-开头;
dataset 是一个集合里面存放了所有以data开头的自定义属性;
*/
div.setAttribute('data-time', 20);
console.log(div.getAttribute('data-index')); // 2
console.log(div.getAttribute('data-list-name')); // andy
console.log('-------------------------------');
// 1. dataset是一个集合, 里面存放了所有以data开头的自定义属性;
console.log(div.dataset); //是一个集合
console.log(div.dataset.index); //相当于获取data-index属性值, 2
console.log(div.dataset['index']); //同上
// 2. 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
console.log(div.dataset.listName); //andy
console.log(div.dataset['listName']); //同上
</script>
</body>
</html>
3. 节点操作
3.1 init
<!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>
<!--
背景:获取元素通常有两种方式:
(1) 利用DOM提供的方法来获取元素;
document.getElementById(), .getElementByTagName(),,,
逻辑型不强, 繁琐;
(2) 利用节点层级关系来获取元素;
利用父子兄弟节点关系来获取元素;
-->
</head>
<body>
<!--
一般地,节点至少拥有nodeType, nodeName, nodeValue这三个基本属性;
元素节点: nodeType = 1;
属性节点: nodeType = 2;
文本节点: nodeType = 3; (文本节点包括:文字,空格,换行等)
Notice: 在实际开发中, 节点操作主要操作的是元素节点;
-->
</body>
</html>
3.2 获取父子节点
<!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>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<div class="demo">
<div class="box">
<span class="erweima">×</span>
</div>
</div>
<script>
/* 通过属性获取父子节点: */
/***********************************************************************/
// 1. 获取父节点
var erweima = document.querySelector('.erweima');
var box = document.querySelector('.box'); //之前写法
console.log(erweima.parentNode); //现在写法
/***********************************************************************/
// 2. 获取子节点
// (0) 之前:
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
// (1) childNodes: 获取[所有子节点]: 包含 元素节点, 文本节点等等;
console.log(ul.childNodes);
console.log(ul.childNodes[0].nodeType); // 3
console.log(ul.childNodes[1].nodeType); // 1
// (2) children: 获取[所有子元素]节点 也是我们实际开发常用的;
console.log(ul.children);
</script>
</body>
</html>
3.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>
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
<li>我是li5</li>
</ol>
<script>
var ol = document.querySelector('ol');
// 1. firstChild: 第一个子节点, 不管是文本节点还是元素节点;
console.log(ol.firstChild);
console.log(ol.lastChild);
// 2. firstElementChild: 返回第一个子元素节点, ie9才支持;
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
// 3. 实际开发的写法:
console.log(ol.children[0]);
console.log(ol.children[ol.children.length - 1]);
</script>
</body>
</html>
3.4 获取兄弟节点
<!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>我是div</div>
<span>我是span</span>
<script>
var div = document.querySelector('div');
// 1.nextSibling: 下一个兄弟节点, 包含元素节点或者 文本节点等等;
console.log(div.nextSibling);
console.log(div.previousSibling);
// 2. nextElementSibling: 得到下一个兄弟元素节点;
console.log(div.nextElementSibling);
console.log(div.previousElementSibling);
</script>
</body>
</html>
3.5 创建添加节点
<!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>
<ul>
<li>我是li</li>
</ul>
<script>
var ul = document.querySelector('ul');
// 1. 创建添加元素节点 (appendChild)
var li = document.createElement('li');
li.style.backgroundColor = 'green';
ul.appendChild(li);
// 3. 创建添加元素节点 (insertBefore)
var lili = document.createElement('li');
lili.style.backgroundColor = 'purple';
ul.insertBefore(lili, ul.children[0]);
</script>
</body>
</html>
3.6 删除节点
<!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>
<button>删除</button>
<ul>
<li>熊大</li>
<li>熊二</li>
<li>光头强</li>
</ul>
<script>
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
btn.onclick = function() {
if (ul.children.length == 0) {
this.disabled = true;
} else {
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
</html>
3.7 克隆节点
<!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>
<ul>
<li>1111</li>
<li>2</li>
<li>3</li>
</ul>
<script>
// 1. node.cloneNode(false): 括号为空或者里面是false, 则是浅拷贝, 只复制标签不复制里面的内容
// 2. node.cloneNode(true): 括号为true,则是深拷贝,既复制标签同时又复制里面的内容
var ul = document.querySelector('ul');
var copyLi = ul.children[0].cloneNode(true);
ul.appendChild(copyLi);
</script>
</body>
</html>
3.8 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>
<!--
1. document.write(); //很少使用
2. element.innerHTML;
3. document.createElement();
-->
</head>
<body>
<button>点击</button>
<p>abc</p>
<div class="inner"></div>
<div class="create"></div>
<script>
// window.onload = function() {
// document.write('<div>123</div>');
// }
// 三种创建元素方式区别
// 1. document.write() 创建元素;
// 如果页面文档流加载完毕,再调用这句话会导致页面重绘;
var btn = document.querySelector('button');
btn.onclick = function() {
document.write('<div>123</div>');
}
/**************************************************************************************************/
// 2. innerHTML 创建元素
var inner = document.querySelector('.inner');
// for (var i = 0; i <= 100; i++) {
// inner.innerHTML += '<a href="#">百度</a>'
// }
var arr = [];
for (var i = 0; i <= 100; i++) {
arr.push('<a href="#">百度</a>');
}
inner.innerHTML = arr.join('');
console.log(arr.join(''));
/**************************************************************************************************/
// 3. document.createElement() 创建元素
var create = document.querySelector('.create');
for (var i = 0; i <= 100; i++) {
var a = document.createElement('a');
a.innerText = 'Hello';
create.appendChild(a);
}
var Arr = ['1','2','3','4'];
console.log(Arr.join('')); //1234
</script>
</body>
</html>
3.9 效率测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>效率测试</title>
<!--
(1) document.write是直接将内容写入页面的内容流,但是文档流执行完毕, 则它会导致页面全部重绘;
(2) innerHTML 是将内容写入某个DOM节点, 不会导致页面全部重绘;
(3) innerHTML 创建多个元素效率更高(不要拼接字符串,采用数组形式拼接),但结构稍微复杂;
(4) createElement() 创建过个元素效率稍微低点, 但是结构更为清晰;
-->
</head>
<body>
</body>
<script>
function fn() {
var d1 = +new Date();
var str = '';
for (var i = 0; i < 1000; i++) {
document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
}
var d2 = +new Date();
console.log(d2 - d1);
}
fn();
/**********************************************************************************************/
function _fn() {
var d1 = +new Date();
var array = [];
for (var i = 0; i < 1000; i++) {
array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
}
document.body.innerHTML = array.join('');
var d2 = +new Date();
console.log(d2 - d1);
}
// _fn();
/**********************************************************************************************/
function __fn() {
var d1 = +new Date();
for (var i = 0; i < 1000; i++) {
var div = document.createElement('div');
div.style.width = '100px';
div.style.height = '2px';
div.style.border = '1px solid red';
document.body.appendChild(div);
}
var d2 = +new Date();
console.log(d2 - d1);
}
// __fn();
</script>
</html>
4. 事件基础
4.1
响应机制
<!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>
<!--
事件:事件源 + 事件类型 + 事件处理程序;
事件源:例如,按钮;
事件类型:比如,鼠标经过,键盘按下;
事件处理程序:函数;
常见鼠标事件:
onclick,onmouseover,onmouseout,onfocus,onblur,onmousemove,
onmouseup,onmousedown;
-->
</head>
<body>
<button id='btn'>Hello World!</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
alert('触发了!');
}
console.log('------------');
var a = [];
var b = a;
b[0] = 1;
console.log(a);
console.log(b);
console.log(a == b); //=>true,b实际上是变量a的引用,并不是拷贝
var num = 6;
console.log(num.toString(2)); //二进制
console.log("0" + num.toString(8)); //八进制
console.log("0x" + num.toString(16)); //16进制
//Js中 => 函数时可以嵌套定义的
function test() {
console.log('hello');
function tt() {
console.log('world');
}
tt();
}
test();
</script>
</body>
</html>
4.2
操作元素
<!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>
</head>
<body>
<div>Hello</div>
<p>
我是文字
<span>1324</span>
</p>
<script>
var div = document.querySelector('div');
//innerText 和 innerHTML的区别
//一、
//1. innerText不识别HTML标签(当做寻常的text内容使用即可), 去除空格会换行;
// div.innerText = '<strong>今天是:</strong>jlkkj', 保留空格和换行;
//2. innerHTML识别HTML标签;
div.innerHTML = '<strong>今天是:</strong>lljl';
//二、
var p = document.querySelector('p');
console.log(p.innerText); //我是文字 1324
console.log(p.innerHTML); //我是文字 [换行] <span>1324</span>
</script>
</body>
</html>
4.2
案例
<!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>
</head>
<body>
<button id='first'>第一张图片</button>
<button id='second'>第二张图片</button> <br/>
<img src="./images/1.jpg" alt="" title="第一张图片">
<link rel="stylesheet" href="" id="test">
<script>
var first = document.getElementById('first');
var second = document.getElementById('second');
var img = document.querySelector('img');
first.onclick = function() {
img.src = './images/2.jpg';
img.title = '第二张图片';
}
second.onclick = function() {
img.src = './images/1.jpg';
img.title = '第一张图片';
}
</script>
</body>
</html>
5.事件高级
5.1 注册事件
<!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>
<button>传统注册事件</button>
<button>方法监听注册事件</button>
<button>ie9 attachEvent</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) 同一个元素,同一个事件,可以添加多个监听器(事件处理程序);
// (3) ie9之前不支持此方法, 可用attachEvent来代替;
btns[1].addEventListener('click', function () {
alert(22);
})
btns[1].addEventListener('click', function () {
alert(33);
})
// [3.] attachEvent ie9以前的版本支持(不要使用它)
btns[2].attachEvent('onclick', function () {
alert(11);
})
</script>
</body>
</html>
5.2 删除事件
<!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>
div {
width: 200px;
height: 200px;
background-color: red;
border: 2px solid black;
}
</style>
</head>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
//1.传统方式的删除事件
var divs = document.querySelectorAll('div');
divs[0].onclick = function() {
alert(11);
divs[0].onclick = null; //删除事件
}
//2.监听方式的删除事件: removeEventListener
divs[1].addEventListener('click',fn)
function fn() {
alert('listen');
divs[1].removeEventListener('click', fn);
}
//3.attach方式的删除事件
divs[2].attachEvent('onclick',fn1);
function fn1(){
alert('attach');
divs[2].detachEvent('onclick',fn1);
}
</script>
</body>
</html>
5.3 dom事件流
<!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>
.father {
width: 200px;
height: 200px;
background-color: red;
}
.son {
width: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<!--
事件流描述的是从页面中接收事件的顺序;
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流;
DOM事件流分为3个阶段:
1.捕获阶段;
2.当前目标阶段;
3.冒泡阶段;
可以这么理解:捕获阶段 => 从最外层开始 向目标元素 层层靠近;
冒泡阶段 => 从目标元素开始 向外 逐层冒泡;
(1) JS代码只能处于其中一个阶段,要么是冒泡阶段,要么是捕获阶段;
(2) onclick 和 attachEvent只能得到冒泡阶段;
(3) addEventListener()的第3个参数可以决定处于哪个阶段:冒泡阶段还是捕获阶段;
true => 捕获阶段;
false或省略 => 冒泡阶段;
-->
<div class="father">
<div class="son"></div>
</div>
<script>
// 1.捕获阶段
// body-father->son
document.addEventListener('click', function() {
alert('document-捕获');
}, true);
var father = document.querySelector('.father');
father.addEventListener('click',function(){
alert('father-捕获');
}, true);
var son = document.querySelector('.son');
son.addEventListener('click',function(){
alert('son-捕获');
}, true);
// 2.冒泡阶段
// son->father->body
var son = document.querySelector('.son');
son.addEventListener('click',function(){
alert('son-冒泡');
}, false);
var father = document.querySelector('.father');
father.addEventListener('click',function(){
alert('father-冒泡');
}, false);
document.addEventListener('click',function(){
alert('document-冒泡');
}, false);
</script>
</body>
</html>
5.4 事件对象
<!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>
div {
width: 100px;
height: 100px;
background-color: green;
}
span {
display: block;
width: 100px;
height: 100px;
background-color: purple;
}
</style>
</head>
<body>
<!--
事件对象:事件发生后,跟事件相关的一系列信息数据的集合都放在这个对象里面,
这个对象就是事件对象event,它有很多属性和方法。
-->
<div>123</div>
<span>HelloWorld</span>
<script>
var div = document.querySelector('div');
div.onclick = function(event) {
console.log(event);
}
/*
上述函数中的形参event就是一个事件对象;
事件对象只有有了事件才会存在, 它是系统自动给我们创建的;
事件对象是与此事件相关的一系列数据的集合;
*/
var span = document.querySelector('span');
span.addEventListener('click', function (event) {
console.log(event);
// console.log(window.event);
event = event || window.event; //考虑兼容性问题
})
//另外,事件对象可以自己命名,event,ev,e都可以的!
//兼容性问题: IE678通过 window.event进行获得事件对象!
</script>
</body>
</html>
5.5 事件对象的属性和方法
<!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>
div {
width: 50px;
height: 50px;
background-color: green;
}
ul li {
width: 50px;
height: 50px;
background-color: red;
border: 2px solid black;
}
a {
width: 50px;
background-color: yellow;
}
.father {
width: 100px;
height: 100px;
background-color: purple;
}
.son {
width: 50px;
height: 50px;
background-color: blue;
}
/* 事件对象的属性和方法
e.target: 返回触发事件的对象;
e.srcElement: 返回事件的对象 非标准IE6—8使用;
e.type: 返回事件的类型, 比如click,mouseover,,,;
e.cancelBubble: 该属性阻止冒泡;
e.returnValue: 该属性阻止默认事件,比如不让链接跳转;
e.preventDefault(): 该方法阻止默认事件,比如不让链接跳转;
e.stopPropagation(): 阻止冒泡;
*/
</style>
</head>
<body>
<div>123</div>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<a href="www.baidu.com">百度</a>
<div class="father">
<div class="son">儿子</div>
</div>
<script>
/****************************************************************************/
// [1.] event.target返回的是触发事件的对象,this返回的是绑定事件的对象;
var div = document.querySelector('div');
div.addEventListener('click',function(event) {
console.log(event.target); //div
console.log(this); //div
});
//
var ul = document.querySelector('ul');
ul.addEventListener('click',function(event) {
console.log(this); //ul
console.log(event.target); //li
});
/****************************************************************************/
// [2.] preventDefault():阻止默认行为,让链接不跳转或者让提交按钮不提交;
var a = document.querySelector('a');
//监听注册
a.addEventListener('click',function(event) {
event.preventDefault();
})
//传统注册
a.onclick = function(event) {
event.preventDefault(); //普通浏览器
// event.returnValue; //低版本IE-678
return false; //也可以阻止默认行为, 没有兼容性问题,但是return后的代码无法执行了
};
/****************************************************************************/
// [3.] 阻止冒泡标准:stopPropagation() //false:冒泡阶段
var son = document.querySelector('.son');
son.addEventListener('click',function(event) {
alert('son-冒泡');
event.stopPropagation();
// event.cancelBubble = true; //低版本
}, false);
var father = document.querySelector('.father');
father.addEventListener('click',function(event) {
alert('father-冒泡');
},false);
document.addEventListener('click',function(event) {
alert('document');
}); //第三个参数useCapture:默认就是false
</script>
</body>
</html>
5.6 事件委托
<!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>
</head>
<body>
<Ul>
<li>Hello World</li>
<li>Hello World</li>
<li>Hello World</li>
<li>Hello World</li>
<li>Hello World</li>
</Ul>
<div>禁止复制文字</div>
<script>
/*
事件委托:也称为事件代理,jQuery里面称为事件委派;
事件委托的原理:不用给每个子结点单独设置事件监听器了,而是给其父结点安装事件监听器,然后利用冒泡影响设置每个子结点;
冒泡: li -> ul -> body -> html -> document -> window;
*/
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) { //给父结点ul安装事件监听器
e.target.style.backgroundColor = 'blue'; //e.target => li
})
/*
之前的话,把所有小li都给获取过来, 然后用依次给每个小li绑定click事件;(如果小li多就麻烦了)
现在,给小li的父结点添加点击事件, 因为点击li,会冒泡,冒到ul上,此时event.target => 就是点击的小li;
事件委托作用:只操作了一次dom, 提高了程序的性能;
*/
//两个事件: 菜单事件, 选择事件
// 1.禁用右键菜单
document.addEventListener('contextmenu', function(event){
event.preventDefault();
})
// 2.禁用鼠标选择
document.addEventListener('selectstart', function(event) {
event.preventDefault();
})
</script>
</body>
</html>
5.7 鼠标事件对对象
<!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>
body {
height: 3000px;
}
</style>
</head>
<body>
<script>
// 鼠标事件对象 MouseEvent
document.addEventListener('click', function(e) {
console.log(e);
// 1. client 鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log('---------------------');
// 2. page 鼠标在页面文档的x和y坐标
console.log(e.pageX);
console.log(e.pageY);
console.log('---------------------');
// 3. screen 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
})
</script>
</body>
</html>
5.8 键盘事件对象
<!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>
</head>
<body>
<!--
keyup: 可以识别功能键;
keydown: 可以识别功能键;
keypress: 不能识别功能键(control,shift,<-, ->,,,);
执行顺序: keydown -> keypress -> keyup;
-->
<!--
onkeydown和onkeyup不区分字母大小写,onkeypress区分字母大小写。
在实际开发中,更多的使用的是keydown和keyup,因为它能识别所有的键(包括功能键)
keypress: 不识别功能键(比如 ctrl shift 左右箭头,,,);
keydown/keyup: 识别功能键;
keyCode属性:返回该键的ASCII码值!
keyup 和keydown事件不区分字母大小写 => a 和 A 得到的都是65;
keypress 事件 区分字母大小写 => a-97 和 A-65;
-->
<script>
document.addEventListener('keydown', function(event) {
console.log('keydown' + event.keyCode);
});
document.addEventListener('keypress', function(){
console.log('press' + event.keyCode);
});
document.addEventListener('keyup', function(event) {
console.log('keyup' + event.keyCode);
});
</script>
</body>
</html>