JavaScript基础
本章节通过练习需要重点掌握对滚轮事件、键盘事件的操作并反复练习切换图片
110. 事件的传播
网景公司和微软公司对事件的传播有着不同的理解:
网景公司:认为事件应该是由外向内传播,即当事件触发时应该先触发当前元素的最外层的祖先元素的事件,然后再向内传播给后代元素
微软公司:认为事件应该是由内向外传播,即当事件触发时应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就是事件应该在冒泡阶段执行
W3C综合了两者的方案,将事件传播分成了三个阶段:
1.捕获阶段:从最外层的组选元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2.目标阶段:事件捕获到目标元素,开始触发事件
3.冒泡阶段:事件从目标元素向祖先元素传播,依次触发祖先元素上的事件
如果希望在捕获阶段触发事件,可以将addEventListener( )的第三个参数设置为true。一般情况下不会希望在捕获阶段触发事件,因此该参数一般为false
在IE8及以下的浏览器没有捕获阶段
<!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>
#box1{
width: 300px;
height: 300px;
background-color: aqua;
}
#box2{
width: 200px;
height: 200px;
background-color: blue;
}
#box3{
width: 100px;
height: 100px;
background-color: blueviolet;
}
</style>
<script>
window.onload = function(){
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
bind(box1,"click",function(){
alert("我是box1的响应函数");
});
bind(box2,"click",function(){
alert("我是box2的响应函数");
});
bind(box3,"click",function(){
alert("我是box3的响应函数");
});
};
function bind(obj,eventStr,callback){
if(obj.addEventListener){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr,callback,true);
}else{
//IE8以及下
obj.attachEvent("on"+eventStr,function(){
callback.call(obj);//在匿名函数中调用回调函数,改变this
});
}
}
</script>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
</body>
</html>
可以看到,当改为true后,先触发box1的响应函数,再触发box2、box3
111. 拖拽
练习:拖拽div元素
拖拽的流程:
1.当鼠标在被拖拽元素上按下时,开始拖拽
2.当鼠标移动时,被拖拽元素跟随鼠标移动
3.当鼠标松开时,被拖拽元素固定在当前位置
当我们拖拽一个网页中内容时,浏览器会默认去搜索引擎中搜索内容,此时会导致拖拽功能的异常,如果不希望发生这个行为,可以通过return false来取消默认行为,但不支持IE8
对于IE8可以通过设置捕获所有事件来解决,但setCapture( )方法在chrome浏览器会报错
因此要解决兼容问题
<!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>
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
#box2{
width: 100px;
height: 100px;
background-color: orange;
position: absolute;
left: 200px;
top: 200px;
}
</style>
<script>
window.onload = function(){
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
drag(box1);
drag(box2);
var img = document.getElementById("img");
drag(img);
};
function drag(obj){
obj.onmousedown = function(e){//为box1绑定鼠标按下事件
if(obj.setCapture){
obj.setCapture();//设置box1捕获所有鼠标按下事件
}
// box1.setCapture && box1.setCapture();
e = e || window.e;
//求出div的偏移量
var ol = e.clientX - obj.offsetLeft;
var ot = e.clientY - obj.offsetTop;
document.onmousemove = function(e){//为document绑定鼠标移动事件
e = e || window.e;//解决兼容性问题
var x = e.clientX - ol;
var y = e.clientY - ot;
obj.style.left = x + "px";
obj.style.top = y + "px";
};
document.onmouseup = function(){//为document绑定鼠标松开事件
document.onclick = null;//设置为空,即为取消该事件响应函数
document.onmousemove = null;
if(obj.releaseCapture){
obj.releaseCapture();
}
// box1.releaseCapture && box1.releaseCapture();
};
return false;
};
}
</script>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
<span>今天天气不错</span>
<img src="../img/1.gif" style="position: absolute;" id="img">
</body>
</html>
112. 滚轮的事件
练习:当鼠标滚轮向下滚动时,box变长;向上滚动时,box变短
onmousewheel:鼠标滚轮滚动事件,但火狐中不支持
DOMMouseScroll:为火狐绑定鼠标滚轮滚动事件,要使用addEventListener( )绑定响应函数
event.wheelDelta:可以获取鼠标滚轮滚动方向,不看大小只看正负,但火狐不支持
向上滚:120
向下滚:-120
event.detal:火狐中获取鼠标滚轮滚动方向,不看大小只看正负
向上滚:-3
向下滚:3
当滚轮滚动时,如果浏览器有滚动条,则浏览器滚动条会跟着滚动
可以通过return false取消这个默认值,但火狐中不支持
火狐是使用addEventListener( )绑定响应函数的,取消默认行为不能使用return false,需要使用event.preventDefault( ),但该方法不支持IE8
因此要解决兼容性问题
<!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>
#box1{
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<script>
window.onload = function(){
var box1 = document.getElementById("box1");
box1.onmousewheel = function(e){
e = e || window.e;
if(e.wheelDelta > 0 || e.detail < 0){//获取鼠标滚轮滚动方向,向上变短
box1.style.height = box1.clientHeight - 10 + "px";
}else{
box1.style.height = box1.clientHeight + 10 + "px";
}
e.preventDefalut && e.preventDefalut();//火狐取消浏览器滚动条滚动的默认事件
return false;//其它浏览器取消浏览器滚动条滚动的默认事件
};
bind(box1,"DOMMouseScroll",box1.onmousewheel);//火狐滚轮滚动事件
};
function bind(obj,eventStr,callback){
if(obj.addEventListener){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr,callback,false);
}else{
//IE8以及下
obj.attachEvent("on"+eventStr,function(){
callback.call(obj);//在匿名函数中调用回调函数,改变this
});
}
}
</script>
</head>
<body style="height: 2000px;">
<div id="box1"></div>
</body>
</html>
113. 键盘事件
onkeydown:按键被按下,如果一直按着则事件会一直触发;当连续触发时,第一次和第二次间隔会稍微长一些,其它的间隔一样,目的是为了防止误操作的发生
onkeyup:按键被松开
键盘事件一般绑定给可以获取焦点的对象或文档document对象
可以通过event.keycode获取按键的编码,从而判断那个按键被按下
altkey,ctrlkey,shiftkey这三个用来判断alt,strl,shift是否被按下,是则返回true
在文本框中输入内容属于onkeydown的默认行为,如果取消了默认行为则输入内容不会出现在文本框中
<!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>
<script>
window.onload = function(event){
document.onkeydown = function(event){
event = event || window.event;
if(event.keyCode ===89 && event.ctrlKey){
alert("ctrl和y键都被按下了")
}
};
var input = document.getElementsByTagName("input")[0];
input.onkeydown = function(event){
event = event || window.event;
// alert(event.keyCode);
if(event.keyCode >=48 && event.keyCode <= 57){
return false;//取消文本框默认行为,则输入内容不会出现在文本框中
}
};
};
</script>
</head>
<body>
<input type="text">
</body>
</html>
【注意】不要使用小键盘里的数字,小键盘数字0-9的keycode为96-105
114. 键盘移动div
<!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>
#box{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
<script>
//w:87,s:83,a:65,d:68
window.onload = function(){
var box = document.getElementById("box");
document.onkeydown = function(e){
e = e || window.e;
var speed = 10;
if(e.shiftKey){
speed = 50;
}
if(e.keyCode == 87){
box.style.top = box.offsetTop - speed + "px";
}else if(e.keyCode == 83){
box.style.top = box.offsetTop + speed + "px";
}else if(e.keyCode == 65){
box.style.left = box.offsetLeft - speed + "px";
}else if(e.keyCode == 68){
box.style.left = box.offsetLeft + speed + "px";
}
};
};
</script>
</head>
<body>
<div id="box"></div>
</body>
</html>
115. nvigator
BOM:浏览器对象模型,通过JS来操作浏览器
DOM:文档对象模型,通过JS来操作网页
BOM对象:
Window:代表整个浏览器窗口,也是网页中的全局对象
Navigator:代表当前浏览器的信息,可以来识别不同的浏览器
Location:代表当前浏览器的地址栏信息,可以跳转页面
History:代表浏览器的历史记录,由于隐私原因,该对象不能获取到具体的历史记录,只能操作向前或向后翻页,而且该操作只在当次访问时有效
Screen:代表用户屏幕的信息,可以获取到用户的显示器的相关信息
这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用
Naigator代表当前浏览器的信息,由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了,一般只会使用userAgent来判断浏览器信息
userAgent:返回一个字符串,含有用来描述浏览器信息的内容,不同浏览器返回不同
IE中已经将微软和IE相关的标识都去除了,所以基本已经不能通过userAgent来识别IE11
如果通过userAgent不能判断,还可以通过一些特有的对象,来判断浏览器的信息
比如:ActiveXObject
<!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>
<script>
console.log(window);
console.log(navigator);
console.log(location);
console.log(history);
console.log(screen);
console.log(navigator.appName);//Netscape
console.log(navigator.userAgent);
var ua = navigator.userAgent;
if(/firefox/i.test(ua)){
alert("火狐浏览器")
}else if(/chrome/i.test(ua)){
alert("chrome浏览器")
}else if(/msie/i.test(ua)){
alert("IE浏览器");
}else if("ActiveXObject" in window){
alert("IE11浏览器")
}
</script>
</head>
<body>
</body>
</html>
116. history
history对象可以操作浏览器向前或向后翻页
length属性:获取当前访问的链接数量
back( ):方法,用来回退到上一个页面,和浏览器回退按钮一样
forward( ):方法,用来跳转到下一个页面,和浏览器前进按钮一样
go( ):方法,用来跳转到指定的页面,需要一个整数作为参数
1:表示向前跳转1个页面,相当于forward( )
2:表示向前跳转2个页面
-1:表示向后回退1个页面,相当于back( )
-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=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(){
// history.back();
// history.forward();
history.go(1);
};
};
</script>
</head>
<body>
<a href="https://www.baidu.com/">访问百度</a>
<br>
<button id="btn">前进/回退</button>
</body>
</html>
117. location
如果打印location则可以获取到地址栏的信息(当前页面的完整路径)
如果直接将location属性修改为一个完整的路径或相对路径,则会自动跳转到该路径并生成相应历史记录
assign( ):方法,用来跳转到其它页面,作用和直接修改location一样
reload( ):方法,用来重新加载当前页面,作用和刷新按钮一样,如果传true作参数,则会强制清空缓存并刷新页面
replace( ):方法,用一个新页面替换当前页面,调用完毕也会跳转页面,但不会生成历史记录,即不能使用回退按钮回退页面
<!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>
<script>
window,onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(){
console.log(location);
// location = "https://www.baidu.com/";
// location.assign("https://www.baidu.com/");//跳转页面,可以回退
// location.reload(true);//强制清空缓存并刷新页面
location.replace("https://www.baidu.com/");//跳转页面,但不能回退
};
};
</script>
</head>
<body>
<input type="text">
<button id="btn">按钮</button>
</body>
</html>
118. 定时器简介
window方法:定时调用
如果希望一段程序可以每间隔一段时间执行一次,可以使用定时调用
setInterval( ):方法,将一个函数每间隔一段时间执行一次
参数:1.回调函数
2.间隔时间,单位毫秒
返回值,Number类型数据,作为定时器的唯一标识
clearInterval( ):方法,用来关闭一个定时器,
参数:定时器标识
<!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>
<script>
window.onload = function(){
var count = document.getElementById("count");
var num = 1;
var timer = setInterval(function(){
count.innerHTML = num++;
if(num == 10){
clearInterval(timer);
}
},1000);//定时调用
};
</script>
</head>
<body>
<h1 id="count"></h1>
</body>
</html>
119. 切换图片练习
clearInterval( )可以接收任意参数,如果参数为有效的定时器标识,则会停止对于的定时器,如果参数非有效的标识,则什么也不做
目前每点击一次按钮就会开启一个定时器,这就导致图片切换速度过快,且只能关闭最后一次开启的定时器
因此在开启一个新定时器之前,需要将当前元素上的定时器关闭
<!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>
<script>
window.onload = function(){
var img = document.getElementsByTagName("img")[0];
var count = 0;
var timer;
var p = document.getElementById("p");
var btn1 = document.getElementById("btn1");
btn1.onclick = function(){
clearInterval(timer);//开启新定时器之前,关闭上一个定时器
timer = setInterval(function(){
if(count > 4){
count = 0;
}
console.log(count);
img.src = "../img/" + (count+1) + ".gif";
p.innerText = "当前显示为第" + (count+1) + "张图片"
count ++;
},1000);
};
var btn2 = document.getElementById("btn2");
btn2.onclick = function(){
clearInterval(timer);
};
};
</script>
</head>
<body>
<p id="p">当前显示为第1张图片</p>
<img src="../img/1.gif">
<br>
<button id="btn1">开始循环播放图片</button>
<button id="btn2">停止循环播放图片</button>
</body>
</html>
下一章节将对延时调用、轮播图、类操作、二级菜单和JSON进行深入了解!