一、普通事件设置与移除
1、普通事件采用的是属性保存方式,所以会出现覆盖的问题。
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
console.log('这是一个点击事件');
};
btn.onclick = function () {
console.log('这是新的点击事件代码');
</script>
2、普通事件的移除
btn.onclick = null;
设置某个事件为null即可(理论上来说,设置任意的非函数值即可,但是null较为规范)。
二、事件绑定
1、元素.addEventListener() - 添加事件监听(事件绑定)
参数1:事件类型,没有on
参数2:事件处理程序,函数
好处:可以避免事件的覆盖问题。
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn');
btn.addEventListener('click', function () {
console.log('这是事件代码1');
});
function fun () {
console.log('这是事件代码2');
}
btn.addEventListener('click', fun);
</script>
2、移除方式:removeEventListener()
参数必须与设置时完全相同(注意:事件处理程序必须是同一个函数,通常采用命名函数形式即可)。
btn.removeEventListener('click', fun);
对我们来说,最致命的话不是爱过,而是我们要兼容IE
3、ie中的事件操作
btn.attachEvent('onclick', function () {
console.log('这是点击事件');
});
function fun () {
console.log('这是点击事件');
}
btn.attachEvent('onclick', fun);
// detachEvent() - 移除事件
btn.detachEvent('onclick', fun);
三、事件捕获
1、事件冒泡
① 某个元素的事件触发后,可能不仅触发当前元素事件,还会触发其他元素的事件。
② 事件的默认传递方式称为,事件冒泡。
③ 传递规则(从内向外):当前元素触发后,触发自身事件,并且将事件传递给父元素如果父元素具有相同类型的事件时,也可以被触发。以此类推。
2、事件捕获
① 设置方式:使用addEventListener()的参数3,布尔类型,默认为false,表示事件冒泡,true表示事件捕获执行。
② 执行顺序:与事件冒泡执行顺序相反,从外向内。
3、事件执行的三个阶段
① 捕获阶段
② 当前目标阶段
③ 冒泡阶段
④ 如果多个事件中,同时设置了事件冒泡和事件捕获,先是事件捕获执行,然后是当前目标执行,最后事件冒泡执行,通常情况下我们只使用事件冒泡
四、事件对象
事件操作中,有许多信息会被js的事件机制整理好之后,采用一个对象保存,传递给我们,这个对象就是事件对象。
1、接收方式
① 在事件处理程序的参数位置接收
② ie中使用window.event接收
e = e || window.event;
// 兼容处理
2、type属性
利用事件对象的type属性进行检测,可以使用一个函数对多个事件进行统一管理。
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = fun;
btn.onmouseover = fun;
function fun (e) {
if (e.type === 'click') {
console.log('这是点击事件代码');
} else if (e.type === 'mouseover') {
console.log('这是移入事件代码');
}
}
</script>
五、事件委托
事件委托经常使用,一定要会,一定要!
事件冒泡的使用场景——事件委托:将内部元素的事件,设置给了某个祖先元素,事件中通过一些检测,让内部的某些元素触发效果。
为啥要使用事件委托捏?主要是因为用js动态创建的子元素是没有事件的,我们必须重新绑定事件,用事件委托就不用重新绑定。再者,用事件委托可以大大地提高代码的性能,十个子元素需要与DOM交互十次,如果子元素事件委托给了父元素,只需要父元素与DOM交互一次,代码的性能自然就提高了。
<div id="box">
<h4 class="title">这是h4</h4>
<p>这是box中原始的p标签</p>
<p>这是box中原始的p标签</p>
<p>这是box中原始的p标签</p>
<span>这是span</span>
</div>
<button id="btn">按钮</button>
<script>
var box = document.getElementById('box');
var ps = box.children; // 获取所有p标签
var btn = document.getElementById('btn');
btn.onclick = function () {
// 给box内部动态创建元素,设置一个新的p标签
var p = document.createElement('p');
p.innerText = '这是新的p标签';
box.appendChild(p);
};
// 出现的问题:希望给box中所有的p标签添加事件,但是动态创建的元素无法使用这个事件。
box.onclick = function (e) {
// 将事件设置给box后,虽然所有p标签均可使用事件,但是box自身和内部的其他元素也可以触发这个事件。我们只需要在box的事件内部设置一些判断规则即可,例如,这个触发的元素是不是p标签
// 事件对象的属性target,用于获取真正触发事件的元素
// console.log(e.target);
// 根据需求,进行任意的检测操作即可:
if (e.target.nodeName === 'P') {
console.log('这是p标签的对应操作');
} else if (e.target.nodeName === 'SPAN') {
console.log('这是span标签的对应操作');
} else if(e.target.className === 'title') {
console.log('这是类名为title的元素操作');
}
};
</script>
关于表格的小案例
<style>
* {
margin: 0;
padding: 0;
}
table {
width: 600px;
border-collapse: collapse;
}
thead {
background-color: #e5e5e5;
}
tbody {
text-align: center;
}
tbody td {
width: 165px;
height: 19px;
}
</style>
<div id="box">
</div>
<script>
//创建表格数据
//表头的数据 创建th使用
var heads = ["姓名", "科目", "成绩", "操作"];
//根据datas中对象的个数创建tr行,每个行中的td个数就是这个对象的属性个数
var datas = [
{"name": "张三1", "subject": "语文1", "score": 99.8},
{"name": "张三2", "subject": "语文2", "score": 80.8},
{"name": "张三3", "subject": "语文3", "score": 70.8},
{"name": "张三4", "subject": "语文4", "score": 100},
{"name": "张三5", "subject": "语文5", "score": 60},
{"name": "张三6", "subject": "语文6", "score": 70},
{"name": "张三7", "subject": "语文7", "score": 89.8}
];
// 步骤:
// 1 明确数据的含义
// 2 创建基本结构
// 3 根据数据进行结构创建
//1.’获取元素
var box = document.getElementById('box');
// 2.创建table、thead、tbody
var table = crt('table', box);
table.border = '1';
var thead = crt('thead', table);
var tbody = crt('tbody', table);
// 3 创建thead中的结构
var tr = crt('tr', thead);
for(var i = 0; i < heads.length; i++) {
var th = crt('th', tr);
th.innerText = heads[i];
}
// 4 根据datas中的数据进行tbody中结构的创建 - 课后练习
for(i = 0; i < datas.length; i++) {
tr = crt('tr', tbody);
for(var k in datas[i]) {
var td = crt('td', tr);
td.innerText = datas[i][k];
}
// 5 在每个tr最后单独设置一个td,内部放置一个删除按钮
td = crt('td', tr);
td.innerHTML = '<a href="javascript:;">删除</a>';
td.children[0].onclick = function () {
var tr = this.parentNode.parentNode;
var trs = tbody.children;
for (var i = 0; i < trs.length; i++) {
if (trs[i] === tr) {
datas.splice(i,1);
break;
}
}
tbody.removeChild(tr);
}
}
function crt (tagName, target) {
var ele = document.createElement(tagName);
target.appendChild(ele);
return ele;
}
</script>