<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Day4</title>
<style>
#dv1{
width: 300px;
height: 300px;
background-color: pink;
}
#dv2{
width: 200px;
height: 200px;
background-color: skyblue;
}
#dv3{
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<button id="btn1">按钮</button>
<button id="btn2">按钮</button>
<script>
/*
绑定事件函数的三种方式: 1.对象.on事件名 = function(){};相同事件后面的会覆盖前面的
2.对象.addEventListener("事件名,没on",function(){},false):可以为同一事件附加多个处理函数 IE8不支持
3.对象.attachEvent("on事件名",事件处理函数):可以为同一事件附加多个处理函数 只有IE8支持
*/
// 兼容代码:为任意元素的任意事件添加处理函数
function addEventFunction(element,type,fn){ //参数分别为元素,事件和处理函数
if (element.addElementListener) {
element.addElementListener(type, fn, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, fn);
} else {
element["on"+type] = fn ; //这里要用对象名.on事件名 = function(){};不能写element."on"+type
//因为element.onclick--如果用下面的方式是element."onclick";可以把onclick看成属性,则用[""]的方式访问该属性即可
// elementelement."on"+type = fn ;
}
}
//试验
var btn1 = document.querySelector("#btn1");
function ff(){console.log("咔咔")};
addEventFunction(btn1, "click", ff);
</script>
<script>
/*解绑事件处理函数的方法 注意:用什么方式绑定事件就应该用什么方式解绑事件
1.对象.on事件 = null; 对应第一种绑定方式
2.对象.removeEventListener(事件, 需要解绑的处理函数, false) 对应第二种绑定方式IE8不支持 注意,这种方式解绑需要在绑定的时候使用命名函数,使用匿名函数无法实现解绑,因为使用匿名函数绑定和解绑里的匿名函数不是同一个DOM对象。
3.对象.detachEvent(on事件,需要解绑的处理函数) 对应第三种绑定方式只有IE8支持 同样也需要使用命名函数才行
*/
// 解绑的兼容代码
function removeEventFunction(element,type,fn){
if (element.removeElementListener) {
element.removeEventListener(type, fn, false);
} else if(element.attachEvent){
element.detachEvent("on"+type, fn);
} else {
element["on"+type] = null;
}
}
//试验
var btn2 = document.getElementById("btn2");
btn2.onclick = function(){
removeEventFunction(btn1, "click", ff);
};
</script>
<div id="dv1">
<div id="dv2">
<div id="dv3"></div>
</div>
</div>
<script>
var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")];
function fn2(){ //一个事件处理函数,在控制台写入触发对象的id
console.log(this.id);
}
for (var i = 0; i < dvObj.length; i++) { //循环注册点击事件
dvObj[i].addEventListener("click", fn2, false);
}
//点击内部盒子时外部的盒子点击事件也会被触发---这就是事件冒泡--
/*
事件冒泡机制:元素(标签)嵌套,如果这些标签都注册了同一个事件,那么在触发内部标签的该事件时,外部标签的该事件也会被触发。事件冒泡这个机制不会触发到内部的元素事件,只会影响到外部的元素事件
如何阻止事件冒泡:1.在事件处理函数内部添加 window.event.cancelBubble = true; IE8
2.在事件处理函数的形参列表中加入一个参数(事件处理函数默认的参数对象)然后函数内加入 参数名.stopPropagation(); 谷歌、火狐
*/
// 下面的代码为阻止事件冒泡后的代码
function fn2(e){ //一个事件处理函数,在控制台写入触发对象的id
console.log(this.id);
e.stopPropagation(); //e这个形参是事件处理函数的一个默认参数,e.stopPropagation()这个方法是谷歌和火狐浏览器的阻止冒泡机制的方法
// window.event.canceBubble = true;//这是IE8特有的阻止冒泡的方法
}
for (var i = 0; i < dvObj.length; i++) { //循环注册点击事件
dvObj[i].addEventListener("click", fn2, false);
}
</script>
<script>
/*
事件触发的三个方式: 1.事件捕获方式
2.事件目标方式
3.事件冒泡方式
事件可以由这三种方式触发:
1.由事件捕获方式触发:由外向内的传递方式触发事件
2.事件目标方式触发:不是由于冒泡机制引发的事件,即事件触发的基点对象,他的事件触发方式为事件目标方式
3.由冒泡方式触发:由内向外的传递方式触发事件
这里就可以说明addEventListener方法里的布尔值的作用:控制事件处理函数的传递方式:false-事件冒泡;true-事件捕获
注意:事件触发方式里的冒泡方式和冒泡机制做出区分:事件冒泡机制是一直存在的,不管是设置addEventListener方法里的布尔值为true还是false,都存在冒泡机制,内部元素的事件触发都会引起外部元素的事件触发。冒泡机制的阻止是靠上面所述的方法。
事件触发方式的冒泡和捕获只是决定事件触发的先后顺序,可以用设置事件方法里的布尔值来设置。
*/
//试验:设置冒泡方式和捕获方式,对比结果
var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")];
function fn2(){ //一个事件处理函数,在控制台写入触发对象的id
console.log(this.id);
}
for (var i = 0; i < dvObj.length; i++) { //循环注册点击事件
dvObj[i].addEventListener("click", fn2, false);
}
//点击内部盒子,输出结果为dv3,dv2,dv1;可以看出里面的盒子的事件先触发,由冒泡方式内向外依次触发冒泡机制引发的事件
//修改上面的布尔值:
var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")];
function fn2(){ //一个事件处理函数,在控制台写入触发对象的id
console.log(this.id);
}
for (var i = 0; i < dvObj.length; i++) { //循环注册点击事件
dvObj[i].addEventListener("click", fn2, true);
}
//点击内部盒子,输出结果为dv1,dv2,dv3;可以看出外面的盒子的事件先触发,由捕获方式由外向里依次触发冒泡机制引发的事件
//
//可以利用:事件处理参数.eventPhase查看事件触发的方式:1为事件捕获,2为事件目标,3为事件冒泡
var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")];
function fn2(e){
console.log(this.id + "触发方式为" + e.eventPhase);
}
for (var i = 0; i < dvObj.length; i++) {
dvObj[i].addEventListener("click", fn2, true);
}
</script>
<!-- 案例:同一个元素的不同事件-不同的处理函数封装到一个函数中 -->
<button id="btn3">按钮3</button>
<script>
var btn3 = document.getElementById("btn3");
btn3.onclick = f1;
btn3.onmouseover = f1;
btn3.onmouseout = f1;
function f1(e){ //形参e为默认的事件处理函数的参数,是浏览器保存事件处理函数数据的一个对象。里面的type属性为事件
switch (e.type) { //利用这个type属性,实现多个事件的处理函数封装
case "click" : //这里的属性名没有on
alert("咔咔");
break;
case "mouseover" :
this.style.backgroundColor = "purple";
break;
case "mouseout" :
this.style.backgroundColor = "pink";
break;
}
}
</script>
<script>
//BOM:Browser Object Model
//根对象:window整个浏览器窗口
var num = 100;
console.log(num);
console.log(window.num); //效果相同
//window的几个方法
//window.alert("咔咔"); //弹出框
//window.prompt("咔咔"); //弹出输入框
//window.confirm("咔咔");//弹出框,有两个按钮,确定返回true,取消返回false
//window加载事件:
window.onload //页面加载完毕时触发的事件
window.onunload //页面关闭后触发的事件
window.onbeforeunload //页面关闭之前触发的事件
</script>
<script>
//DOM的location对象
console.log(window.location);
console.log(location);
//属性: hash:地址栏内#后的内容,URL的锚部分
// host:返回一个URL的主机名和端口
// hostname 返回URL的主机名
// href 返回完整的URL
// pathname 返回的URL相对路径
// port 返回URL服务器使用的端口号
// protocol 返回URL协议
// search 返回URL的查询部分
//方法:assign()改变地址栏内容,利用herf属性能实现相同的效果
//location.assign("http://www.baidu.com");
//location.herf = "http://www.baidu.com";
// reload()重新加载,刷新
// replace()替换地址栏内容,和herf或者assign的区别:不会记录历史,不能回退到前面的界面
</script>
<script>
//DOM的history对象
//方法:back() 加载 history 列表中的前一个 URL
//forward() 加载 history 列表中的下一个 URL
//go() 加载 history 列表中的某个具体页面
</script>
<script>
//DOM的navigator对象
//属性:userAgent:获取User Agent简称UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。用这个属性可以判断浏览器类型
// platform:获取一个只读的字符串,声明了运行浏览器的操作系统和(或)硬件平台。
</script>
<p id="date"></p>
<script>
//DOM的两个计时器方法
//1.setInterval(函数,毫秒数):按照指定的周期(毫秒数)执行函数
var dtp = document.getElementById("date");
var timeId = setInterval(function(){
var d = new Date();
var dt = d.toLocaleTimeString();
dtp.innerText = dt;
}, 1000);
//停止该定时器:clearInterval(定时器的返回值)
//clearInterval(timeId)
//2.setTimeout(函数,毫秒数) 在指定的毫秒数后调用一次函数或计算表达式
setTimeout(function(){
alert("我在三秒后弹出");
}, 3000 );
//可以使用clearTimeout()来阻止事件的发生(在事件发生之前)
//
</script>
</body>
</html>