JavaScript同步和异步+宏任务和微任务+事件
同步和异步
所有的点击事件都是异步的

注意:所有事件函数(addEventListener)都不能return
/*
* 同步和异步
* 同步,是指代码从上向下执行,执行完一条,才去执行下一条,是按照顺序按照步骤的执行
*
* 异步,代码执行需要有一个过程,或者需要一定的时间,或者开始的时间不确定,这时候
* 我们先让别的不相关的代码执行,而当前代码当执行完成后去执行一个回调函数
*
*
* 注意:如果代码写在script中,并且写在函数外部,那么这个代码他只能执行一次,并且
* 是在开始时就同步执行了,显然这种方式不利于代码中出现交互,因此,代码就需要写在
* 函数中,减少代码之间同步执行方式。函数外通常仅用来定义变量(全局)和执行初始化函数
*
* */
var sum=0;
var bn=document.querySelector("button");
// 所有的事件都是异步
bn.addEventListener("click",clickHandler);
function clickHandler(e) {
sum++;
oneFn(sum); //回调
// return sum; //注意:所有事件函数都不能return
}
function oneFn(sum) {
console.log(sum,"1___");
twoFn(sum);
}
function twoFn(sum) {
console.log(sum,"2___");
threeFn(sum)
}
function threeFn(sum) {
console.log(sum,"3___");
}
宏任务和微任务
/*
* 宏任务 setTimeout setInterval
* 微任务 Promise (一共3个)
* 同一个队列中,先执行的是宏任务,再执行其他任务,最后执行微任务
*
* 在当前队列中出现的异步,如果是微任务就会放在当前任务队列最底端,
* 如果当前队列出现的异步是宏任务,就会出现在下一个队列最顶端
*
* 也就是说在同一个队列中触发异步,微任务先执行,宏任务后执行
* */

两道常考的笔试题:
// 重要程度:1 ,常考的笔试题
setTimeout(function () {
new Promise(function (res, rej) {
console.log("1");
res();
}).then(function () {
console.log("2")
}, function () {
});
console.log("3")
}, 0);
// 2
console.log("4");
//结果:4 1 3 2
/* setTimeout(function () {
console.log("1");
},0);
new Promise(function (res,rej) {
console.log("2");//同步执行
res();
}).then(function () {
console.log("3");//异步执行
});
console.log("4") //同步执行 */
// 结果: 2 4 3 1
事件流程
事件触发的3个阶段
捕获阶段 ---> 目标阶段 ---> 冒泡阶段

<style>
#div0{
width: 300px;
height: 300px;
background: yellow;
margin: auto;
position: relative;
}
#div1{
width: 200px;
height: 200px;
background: green;
position: absolute; /*绝对定位 auto left=top=right=bottom=0 --->居中*/
margin: auto;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
#div2{
width: 100px;
height: 100px;
background: red;
margin: auto;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
</style>
</head>
<body>
<div id="div0">
<div id="div1">
<div id="div2"></div>
</div>
</div>
<script>
var div0 = document.getElementById("div0");
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
div0.addEventListener('click',clickHandler0);
var num = 1;
function clickHandler0(e) {
console.log('div0',e.target,e.currentTarget,this);
setTimeout(function (div) {
div.style.backgroundColor = "rgba(255,255,0,0.3)";
},num*1000,this);
num++;
}
div1.addEventListener('click',clickHandler1,true); //加了true 捕获阶段优先
function clickHandler1(e) {
// e.stopPropagation(); //阻止冒泡
console.log('div1',e.target,e.currentTarget,this);
setTimeout(function (div) {
div.style.backgroundColor = "rgba(0,255,0,0.3)";
},num*1000,this);
num++;
}
div2.addEventListener('click',clickHandler2);
function clickHandler2(e) {
console.log('div2',e.target,e.currentTarget,this);
setTimeout(function (div) {
div.style.backgroundColor = "rgba(255,0,0,0.3)";
},num*1000,this);
num++;
}
总结归纳:
/*
* 事件触发是由3个阶段组成
* 捕获阶段 目标阶段 冒泡阶段
* 外 -->内 目标 内 -->外
* */
/*
* 阻止冒泡 可以在冒泡阶段也可以在捕获阶段
* e.stopPropagation();//阻止冒泡
e.cancelBubble=true;//只适用于IE 8及以下
*
* */
比较 onclick 和 addEventListener
/*
* 比较 onclick 和 addEventListener
* 1,onclick 它不可以一个事件做多个方法,addEventListener可以针对同一个
* 对象是一个事件做多个方法,并且可以自由选择中间停止某些方法
* 2.onclick不能设置捕获和冒泡阶段那个优先,addEventListener可以设置捕获和
* 冒泡的优先,及是否选择确定一个被另一个覆盖
* 3.onclick这种事件没有自由度,addEventListener可以侦听所有自定义的事件
*
* */
/* div0.onclick=function () {
console.log("a")
};
div0.onclick=function () {
console.log("b");
} //第二个会覆盖第一个*/
/*div0.addEventListener("click",clickHandler0);
div0.addEventListener("click",clickHandler1);
function clickHandler0() {
console.log("a");
this.removeEventListener("click",clickHandler0);
}
function clickHandler1() {
console.log("b");
}*/
/*
* IE8及以下浏览器无法通过这个事件选择捕获或者优先的级别
*
* */
// div0.attachEvent("onclick",clickHandler0);//相当于 addEventListener
// div0.detachEvent("onclick",clickHandler0);//相当于 removeEventListener
事件的一些重要概念:

一个小案例:
涉及知识点:
1、关闭事件冒泡
2、为所有的li设置同一个 clickHandler


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
ul{
border: 1px solid red;
padding: 10px;
}
li{
border: 1px solid blue;
margin: 10px;
}
</style>
</head>
<body>
<!--仅侦听外容器ul 就可以达到对所有子容器的侦听
<ul>
<li>北京</li>
<li>上海</li>
<li>广州</li>
<li>深圳</li>
<li>重庆</li>
<li>天津</li>
</ul>
<script>
var ul = document.getElementsByTagName('ul')[0];
ul.addEventListener('click',clickHandler);
function clickHandler(e) {
// console.log(e.target.constructor === HTMLUListElement);
if(e.target.constructor === HTMLUListElement) return;
console.log(e); //MouseEvent {isTrusted: true, screenX: 171, screenY: 198, clientX: 85, clientY: 47, …}
e.target.style.color = "red";
}
</script>-->
<ul>
<li>北京
<ul>
<li>昌平
<ul>
<li>沙河</li>
<li>城关</li>
<li>回龙观</li>
<li>天通苑</li>
</ul>
</li>
<li>海淀</li>
<li>朝阳</li>
<li>东城</li>
<li>西城</li>
</ul>
</li>
<li>山东</li>
<li>山西</li>
<li>河北
<ul>
<li>保定</li>
<li>石家庄</li>
<li>张家口
<ul>
<li>张北</li>
<li>崇礼</li>
<li>下花园</li>
<li>宣化</li>
</ul>
</li>
<li>承德</li>
<li>邯郸</li>
</ul>
</li>
<li>河南
<ul>
<li>郑州</li>
<li>许昌</li>
<li>洛阳</li>
<li>驻马店</li>
<li>信阳
<ul>
<li>罗山
<ul>
<li>竹竿镇</li>
<li>楠杆镇</li>
<li>子路镇</li>
<li>青山镇</li>
<li>灵山镇</li>
<li>莽张镇</li>
<li>周党镇</li>
</ul>
</li>
<li>光山</li>
<li>息县</li>
<li>潢川</li>
<li>新县</li>
<li>正阳</li>
<li>商城</li>
<li>固始</li>
<li>淮滨</li>
</ul>
</li>
</ul>
</li>
</ul>
<script>
var lis = document.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
lis[i].addEventListener("click", clickHandler)
}
function clickHandler(e) {
e.stopPropagation();
// console.log(this); //this == e.target
e.target.bool = !e.target.bool;
// console.log(e.target.bool);
if(this.bool){
// console.log(this.firstElementChild); //点击信阳 第一个子元素就是 ul
this.firstElementChild.style.display = "none";
return;
}
this.firstElementChild.style.display = "block";
}
</script>
</body>
</html>

阻止系统默认事件:
/*
* 阻止系统默认事件的几种类型:
* 1.阻止提交表单(跳转)
* 2.阻止系统右键菜单(contextmenu事件中使用)
* 3.阻止图片拖动时的禁用效果
*
* */
<form action="1、Promise.html" method="get">
<input type="text" name="user">
<input type="submit">
</form>
/* var bn=document.querySelector("[type=submit]");
bn.addEventListener("click",clickHandler);
function clickHandler(e) {
console.log(e);
e.preventDefault();//阻止默认事件,
//e.returnValue=false;//IE8 及以下浏览器
}*/
鼠标事件:

MouseEvent 全部事件

MouseEvent {isTrusted: true, screenX: 31, screenY: 125, clientX: 28, clientY: 20, …}
altKey: false
bubbles: true
button: 0
buttons: 0
cancelBubble: false
cancelable: true
clientX: 28
clientY: 20
composed: true
ctrlKey: false
currentTarget: null
defaultPrevented: false
detail: 1
eventPhase: 0
fromElement: null
isTrusted: true
layerX: 20
layerY: 12
metaKey: false
movementX: 0
movementY: 0
offsetX: 18
offsetY: 10
pageX: 28
pageY: 20
path: (6) [button, div#btn, body, html, document, Window]
relatedTarget: null
returnValue: true
screenX: 31
screenY: 125
shiftKey: false
sourceCapabilities: InputDeviceCapabilities {firesTouchEvents: false}
srcElement: button
target: button
timeStamp: 7005.505000000994
toElement: button
type: "click"
view: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
which: 1
x: 28
y: 20
__proto__: MouseEvent
鼠标事件举例:
/*
* e.x e.y e.clientX e.clientY 鼠标相对文档左上顶部位置(当有滚动条或者滚动条改变时,也会改变)
* e.pageX e.pageY 鼠标相对页面左上角位置
* e.offsetX e.offsetY 鼠标距离侦听目标的左上角位置
* e.layerX, e.layerY 容器内元素针对侦听目标的左上角位置
* e.screenX e.screenY 针对显示屏的左上角位置
* e.movementX e.movementY 本次鼠标移动距离(主要用于mousemove事件中)
* e.ctrlKey e.shiftKey e.altKey e.metaKey(苹果键盘) 鼠标事件触发时按下了键盘的那个辅助键,是true就是按下了
*
* */
// var div = document.querySelector("div");
var div = document.querySelector("#div1");
div.addEventListener("click", clickHandler);//点击(鼠标左键)
// div0.addEventListener("click", clickHandler);//点击(鼠标左键)
// div1.addEventListener("click", clickHandler);//点击(鼠标左键)
// div.addEventListener("dblclick",clickHandler);//双击
// div.addEventListener("mousemove",clickHandler);//在目标上移动鼠标
// div.addEventListener("mouseover",clickHandler);//鼠标经过 针对e.target 目标(目标改变就会触发)
// div.addEventListener("mouseout",clickHandler);//鼠标滑出 针对e.target 目标(目标改变就会触发)
// div.addEventListener("mouseenter",clickHandler);//鼠标进入 针对e.currentTarget侦听的对象
// div.addEventListener("mouseleave",clickHandler);//鼠标离开 针对e.currentTarget侦听的对象
// div.addEventListener("mousedown",clickHandler);//按下鼠标(鼠标三键都会触发)
// div.addEventListener("mouseup",clickHandler);//释放鼠标(鼠标三键都会触发)
div.addEventListener("contextmenu",clickHandler);//右键点击呼出菜单
function clickHandler(e) {
console.log(e);
// e.preventDefault(); 阻止默认事件,鼠标右击不会呼出菜单
}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>设置DOM对象的位置</title>
<style>
*{
margin: 0;
padding: 0;
}
.div1{
position: absolute;
width: 200px;
height: 100px;
background-color: red;
left: 50px;
top: 100px;
}
</style>
</head>
<body>
<div class="div1"></div>
<script>
init();
function init() {
var $div = document.getElementsByClassName('div1')[0];
$div.addEventListener('mousedown',mouseHandler);
$div.style.position = "absolute";
// $div[0].draggable = true;
console.log($div);
}
function mouseHandler(e) {
// console.log(e);
// console.log(e.currentTarget); //e.currentTarget == $div 就是div对象
//鼠标点击处 距离屏幕左上角 距离
// console.log(e.clientX, e.clientY);
// console.log(e.x, e.y);
// console.log(e.pageX, e.pageY);
//鼠标点击处 距离div左上角 距离
// console.log(e.offsetX, e.offsetY);
// console.log(e.layerX, e.layerX);
switch (e.type) {
case "mousedown":
console.log("按下鼠标");
e.currentTarget.point = {x:e.offsetX,y:e.offsetY};
document.elem = e.currentTarget;
document.addEventListener('mousemove',mouseHandler);
document.addEventListener('mouseup',mouseHandler);
break;
case "mousemove":
console.log("移动鼠标");
document.elem.style.left = e.x - document.elem.point.x +"px";
document.elem.style.top = e.y - document.elem.point.y +"px";
break;
case "mouseup":
console.log("松开鼠标");
document.removeEventListener('mousemove',mouseHandler);
document.removeEventListener('mouseup',mouseHandler);
}
}
</script>
</body>
</html>
小案例-div跟随鼠标:

源代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div
{
width: 50px;
height: 50px;
background-color: greenyellow;
position: absolute;
}
</style>
</head>
<body>
<div></div>
<script>
var div=document.querySelector("div");
document.addEventListener("mousemove",mouseHandler);
function mouseHandler(e) {
console.log(e);
div.style.left=e.clientX-div.offsetWidth/2+"px";
div.style.top=e.clientY-div.offsetHeight/2+"px";
console.log(e.offsetX,e.offsetY);
}
</script>
</body>
</html>
拖拽效果:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>1-拖拽</title>
<style>
div{
width: 100px;
height: 100px;
position: absolute;
background-color: orange;
font-size: 26px;
text-align: center;
line-height: 100px;
}
</style>
</head>
<body>
<div id="div0">0</div>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<script>
//常规版>>>方式一
/*var div0 = document.getElementById("div0");
div0.addEventListener("mousedown",mousedownHandler);
function mousedownHandler(evt) {
var x = evt.offsetX;
var y = evt.offsetY;
var $that = this;
document.addEventListener('mousemove',mousemoveHandler);
function mousemoveHandler(e1) {
$that.style.left = e1.clientX - x +"px";
$that.style.top = e1.clientY - y +"px";
}
div0.addEventListener('mouseup',mouseupHandler);
function mouseupHandler(e2) {
document.removeEventListener('mousemove',mousemoveHandler);
}
}*/
/*//加强版>>>方式二
var div0 = document.getElementById("div0");
div0.addEventListener("mousedown",mousedownHandler);
function mousedownHandler(evt) {
document.x = evt.offsetX;
document.y = evt.offsetY;
document.addEventListener('mousemove',mousemoveHandler);
this.addEventListener('mouseup',mouseupHandler);
}
function mousemoveHandler(e1) {
div0.style.left = e1.clientX - this.x +"px";
div0.style.top = e1.clientY - this.y +"px";
}
function mouseupHandler(e) {
document.removeEventListener('mousemove',mousemoveHandler);
}*/
/*
//超强版>>>方式三
var divs = document.querySelectorAll("div");
for(var i=0;i<divs.length;i++){
divs[i].addEventListener("mousedown",mousedownHandler);
}
function mousedownHandler(evt) {
evt.preventDefault();
document.x = evt.offsetX;
document.y = evt.offsetY;
document.ele = this;
document.addEventListener('mousemove',mousemoveHandler);
this.addEventListener('mouseup',mouseupHandler);
}
function mousemoveHandler(e1) {
//这里的this 就是document
this.ele.style.left = e1.clientX - this.x +"px";
this.ele.style.top = e1.clientY - this.y +"px";
}
function mouseupHandler(e) {
document.removeEventListener('mousemove',mousemoveHandler);
}
*/
//终极版 封装成函数
var divs = document.querySelectorAll("div");
for(var i=0;i<divs.length;i++){
drag(divs[i]);
}
removeDrag(divs[0]);
function drag(elem) {
elem.addEventListener('mousedown',mouseHandler)
}
function removeDrag(elem) {
//取消拖拽功能
elem.removeEventListener('mousedown',mouseHandler)
}
function mouseHandler(e) {
switch (e.type) {
case "mousedown":
e.preventDefault();
document.addEventListener('mousemove',mouseHandler);
this.addEventListener('mouseup',mouseHandler);
this.x = e.offsetX;
this.y = e.offsetY;
document.elem = this;
break;
case "mousemove":
this.elem.style.left = e.clientX - this.elem.x +"px";
this.elem.style.top = e.clientY - this.elem.y +"px";
break;
case "mouseup":
document.removeEventListener("mousemove",mouseHandler);
this.removeEventListener("mouseup",mouseHandler);
break;
}
}
</script>
</body>
</html>
小案例-拖拽碰撞

源代码:
知识点:分开写 拖拽函数,随机位置函数,碰撞函数 ,将这些常用的功能函数放在 Utils.js 中调用

var Utils=(function () {
return {
setStyle:function (elem,style) {
for(var prop in style){
elem.style[prop]=style[prop];
}
},
randomColor:function (alpha) {
if(alpha>1 || isNaN(alpha) || alpha<0){
alpha=1;
}
var color="rgba(";
for(var i=0;i<3;i++){
color+=parseInt(Math.random()*256);
color+=",";
}
color+=alpha+")";
return color;
},
loadImage:function (arr,callback) {
var img=new Image();
img.arr=arr;
img.callback=callback;
img.imgList=[];
img.num=0;
img.addEventListener("load",this.loadHandler);
img.src=arr[img.num];
},
loadHandler:function (e) {
this.imgList.push(this.cloneNode(false));
this.num++;
if(this.num>this.arr.length-1){
this.callback(this.imgList);
this.removeEventListener("load",Utils.loadHandler);
return;
}
this.src=this.arr[this.num];
},
dragElem:function (elem) {
elem.addEventListener("mousedown",this.mouseHandler);
elem.style.position="absolute";
elem.self=this;
},
removeDrag:function (elem) {
elem.removeEventListener("mousedown",this.mouseHandler);
elem.self=null;
},
mouseHandler:function (e) {
switch (e.type){
case "mousedown":
e.preventDefault();
document.addEventListener("mousemove",this.self.mouseHandler);
document.addEventListener("mouseup",this.self.mouseHandler);
this.x1=e.offsetX;
this.y1=e.offsetY;
document.elem=this;
break;
case "mousemove":
this.elem.style.left=e.clientX-this.elem.x1+"px";
this.elem.style.top=e.clientY-this.elem.y1+"px";
var evt=new Event("elemMove"); //定义一个事件
this.elem.dispatchEvent(evt); //抛发事件
break;
case "mouseup":
//this 是mouseup的侦听对象,document
//elem 就是document.elem--->(line 56)this--->mousedown对应的侦听对象是div
//self div.self--->(line 42)this---> 当前的对象Utils
//mouseHandler 是Utils下面的函数
document.removeEventListener("mousemove",this.elem.self.mouseHandler);
document.removeEventListener("mouseup",this.elem.self.mouseHandler);
break;
}
},
getRandomPosition:function (elem) {
var w=document.documentElement.clientWidth-elem.offsetWidth;
var h=document.documentElement.clientHeight-elem.offsetHeight;
elem.style.position="absolute";
elem.style.left=Math.random()*w+"px";
elem.style.top=Math.random()*h+"px";
},
hitTest:function (elem0,elem1) {
var range0 = elem0.boundingClientRect();
var range1 = elem1.boundingClientRect();
//下面的if 条件 是4中碰撞可能
if(range0.left<=range1.left && range1.left<= range0.right || range0.left >= range1.left &&range0.left<=range1.right){
return true;
}
else if(range0.bottom>=range1.top && range0.bottom <=range1.bottom || range1.bottom >= range0.top &&range1.bottom<=range0.bottom){
return true;
}
return false;
}
}
})();

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>2-拖拽碰撞</title>
<script src="js/Utils.js"></script>
<style>
#div0{
width: 50px;
height: 50px;
background: cadetblue;
position: absolute;
font-size: 16px;
text-align: center;
line-height: 50px;
}
#div1{
width: 50px;
height: 50px;
background: orange;
position: absolute;
font-size: 16px;
text-align: center;
line-height: 50px;
}
</style>
</head>
<body>
<div id="div0">0</div>
<div id="div1">1</div>
<script>
var div0 = document.getElementById("div0");
var div1 = document.getElementById("div1");
Utils.getRandomPosition(div1);
Utils.dragElem(div0);
Utils.dragElem(div1);
div0.addEventListener('elemMove',mouseHandler);
div1.addEventListener('elemMove',mouseHandler);
function mouseHandler(e) {
// console.log(this);
if(Utils.hitTest(div0,div1)){
if(this.id === "div0"){
Utils.getRandomPosition(div1);
}else if(this.id === "div1"){
Utils.getRandomPosition(div0);
}
}
}
</script>
</body>
</html>
Event对象


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>form对象的一些事件</title>
<style>
html{
font-size: 100px;
}
body{
font-size: 14px;
}
img{
width: 8rem; /*注意:rem是以html中 font-size: 100px; 为参照 8rem=8*100px*/
height: 8rem;
}
</style>
</head>
<body>
<form action="#" method="get" id="form1">
<input type="text" id="texts">
<input type="checkbox" id="check">
<select name="" id="selects" multiple> <!--设置为多选*/-->
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
<option value="chongqing">重庆</option>
</select>
<input type="submit">
<input type="reset">
</form>
<script>
/*
* submit 和 reset事件都是针对表单form的侦听
* 通常用于提交表单和重置表单时,需要取消系统默认的提交事件
* */
/*var form1 = document.getElementById("form1");
form1.addEventListener("submit", formHandler);
form1.addEventListener("reset", formHandler);
function formHandler(e) {
e.preventDefault();
console.log("aaa")
}*/
// 页面随着窗口大小的变化自适应缩放内部元素的大小
// resize事件是可以获取window窗口变化缩放的事件侦听,当窗口大小发生改变时,收到该事件
/*window.addEventListener("resize", resizeHandler);
function resizeHandler(e) {
var scale = document.documentElement.clientWidth / 1343;
document.documentElement.style.fontSize = 100 * scale + "px";
}*/
/*
* select
* 当文本框中的值被选中时,激活该事件
*
*texts.selectionStart texts.selectionEnd //被选中的元素开始 结束的索引
* */
/*var sel = document.getElementById("texts");
sel.addEventListener('select',selectHandler);
function selectHandler(e) {
// console.log(e);
// console.log(sel.selectionStart,sel.selectionEnd);
sel.value = sel.value.slice(0,sel.selectionStart)+sel.value.slice(sel.selectionStart,sel.selectionEnd).toUpperCase()+sel.value.slice(sel.selectionEnd);
}*/
/* *
表单中如果表单元素的value值或者选中属性被修改, 并且与原来的值不同
* 当失去焦距时触发change事件
* */
/*var inputs=document.querySelector("#check");
inputs.addEventListener("change",changeHandler);
function changeHandler(e) {
console.log(e);
}*/
/*
* selects.selectedIndex 当前选择下拉菜单的索引值
*selects.selectedOptions 是一个列表,当选择下拉菜单时,如果没有指定多选
* 这个列表中只有一个元素,如果指定多选时,可以有多个元素
*
* */
var selects= document.getElementById("selects");
selects.addEventListener("change",changeHandler);
function changeHandler(e) {
console.log(e);
console.log(e.target.selectedIndex); //索引
console.log(e.target.selectedOptions[0].textContent); //内容
console.log(e.target.selectedOptions[0].innerHTML); //内容
console.log(this); //this == selects == e.target
console.log(e.target);
console.log(selects);
}
/*// scroll
// 滚动条滚动事件(不是滚轮滚动)
window.addEventListener("scroll", scrollHandler);
function scrollHandler(e) {
console.log("aa");
}*/
/*
* 图片,脚本,css样式表文件的加载时,如果指定地址错误加载失败,
* 都可以通过侦听error来判断是否错误
* ajax也可以用来判断通信失败
*
* */
/*var img=new Image();
img.addEventListener("error",errorHandler);
img.src="img/1.jpg";
function errorHandler(e) {
console.log("加载错误");
}*/
/*
* load 加载
* 用于浏览器全部加载完成判断,图片加载成功判断,视频,声音等加载
* 后面学习AJAX也可以使用load判断加载完成
* */
// 因为script标签比img更早执行完毕
var img=document.getElementById("imgs");
console.log(img); //null
window.onload = function () {
// 当整个页面全部加载完毕 即图片加载完成,
// 这个时候在执行这个load完成后的事件就可以获取页面中任意位置的img
var img=document.getElementById("imgs");
console.log(img); //<img src="img/max.jpg" id="imgs">
}
</script>
<img src="img/max.jpg" id="imgs">
</body>
</html>
change: 单选框改变触发 <input type="checkbox" id="check">,或者select 下拉框选择改变也会触发事件。
<form action="#" method="get" id="form1">
<input type="text" id="texts">
<input type="checkbox" id="check">
<select name="" id="selects" multiple> <!--设置为多选*/-->
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
<option value="chongqing">重庆</option>
</select>
<input type="submit">
<input type="reset">
</form>
//------------------------------------------------------js
/* *
表单中如果表单元素的value值或者选中属性被修改, 并且与原来的值不同
* 当失去焦距时触发change事件
* */
/*var inputs=document.querySelector("#check");
inputs.addEventListener("change",changeHandler);
function changeHandler(e) {
console.log(e);
}*/
/*
* selects.selectedIndex 当前选择下拉菜单的索引值
*selects.selectedOptions 是一个列表,当选择下拉菜单时,如果没有指定多选
* 这个列表中只有一个元素,如果指定多选时,可以有多个元素
*
* */
var selects= document.getElementById("selects");
selects.addEventListener("change",changeHandler);
function changeHandler(e) {
console.log(e);
console.log(e.target.selectedIndex); //索引
console.log(e.target.selectedOptions[0].textContent); //内容
console.log(e.target.selectedOptions[0].innerHTML); //内容
console.log(this); //this == selects == e.target
console.log(e.target);
console.log(selects);
}
error: 图片,脚本,css样式表文件的加载时,如果指定地址错误加载失败,都可以通过侦听error来判断是否错误
/*
* 图片,脚本,css样式表文件的加载时,如果指定地址错误加载失败,
* 都可以通过侦听error来判断是否错误
* ajax也可以用来判断通信失败
*
* */
/*var img=new Image();
img.addEventListener("error",errorHandler);
img.src="img/1.jpg";
function errorHandler(e) {
console.log("加载错误");
}*/
load: 加载用于浏览器全部加载完成判断,图片加载成功判断,视频,声音等加载,后面学习AJAX也可以使用Load判断加载完成
<script>
/*
* load 加载
* 用于浏览器全部加载完成判断,图片加载成功判断,视频,声音等加载
* 后面学习AJAX也可以使用load判断加载完成
* */
// 因为script标签比img更早执行完毕
var img=document.getElementById("imgs");
console.log(img); //null
window.onload = function () {
// 当整个页面全部加载完毕 即图片加载完成,
// 这个时候在执行这个load完成后的事件就可以获取页面中任意位置的img
var img=document.getElementById("imgs");
console.log(img); //<img src="img/max.jpg" id="imgs">
}
</script>
<img src="img/max.jpg" id="imgs">
submit 和 reset事件:都是针对表单form的侦听,通常用于提交表单和重置表单时,需要取消系统默认的提交事件 e.preventDefault();
/*
* submit 和 reset事件都是针对表单form的侦听
* 通常用于提交表单和重置表单时,需要取消系统默认的提交事件
* */
/*var form1 = document.getElementById("form1");
form1.addEventListener("submit", formHandler);
form1.addEventListener("reset", formHandler);
function formHandler(e) {
e.preventDefault();
console.log("aaa")
}*/
resize: window窗口缩放时触发事件
<head>
<meta charset="UTF-8">
<title>form对象的一些事件</title>
<style>
html{
font-size: 100px;
}
body{
font-size: 14px;
}
img{
width: 8rem; /*注意:rem是以html中 font-size: 100px; 为参照 8rem=8*100px*/
height: 8rem;
}
</style>
</head>
<body>
<form action="#" method="get" id="form1">
<input type="text" id="texts">
<input type="checkbox" id="check">
<select name="" id="selects" multiple> <!--设置为多选*/-->
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
<option value="chongqing">重庆</option>
</select>
<input type="submit">
<input type="reset">
</form>
<script>
// 页面随着窗口大小的变化自适应缩放内部元素的大小
// resize事件是可以获取window窗口变化缩放的事件侦听,当窗口大小发生改变时,收到该事件
/*window.addEventListener("resize", resizeHandler);
function resizeHandler(e) {
var scale = document.documentElement.clientWidth / 1343;
document.documentElement.style.fontSize = 100 * scale + "px";
}*/
</script>
<img src="img/max.jpg" id="imgs"></body></html>
select:当文本框中的值被选中时,激活该事件
/*
* select
* 当文本框中的值被选中时,激活该事件
*
*texts.selectionStart texts.selectionEnd //被选中的元素开始 结束的索引
* */
/*var sel = document.getElementById("texts");
sel.addEventListener('select',selectHandler);
function selectHandler(e) {
// console.log(e);
// console.log(sel.selectionStart,sel.selectionEnd);
sel.value = sel.value.slice(0,sel.selectionStart)+sel.value.slice(sel.selectionStart,sel.selectionEnd).toUpperCase()+sel.value.slice(sel.selectionEnd);
}*/
scroll:滚动条滚动事件(不是滚轮滚动)
/*// scroll
// 滚动条滚动事件(不是滚轮滚动)
window.addEventListener("scroll", scrollHandler);
function scrollHandler(e) {
console.log("aa");
}*/
获得焦距focus 失去焦距blur
input 聚焦 focus 失去焦点 blur
input事件, 输入事件,当改变文本框内容时,激活该事件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
input{
color: #CCCCCC;
}
</style>
</head>
<body>
<span>什么样的elem能够focus获取焦距?能通过键盘上Tab键选中的元素</span>
<hr>
<hr>
<form action="#">
<input type="text" id="name" value="用户名">
<input type="text" id="pwd" value="密码">
<button>按钮</button>
</form>
<a href="#">超链接</a>
<script>
/*var $name = document.getElementById("name");
$name.addEventListener('focus',focusHandler);
$name.addEventListener('blur',focusHandler);
// 面试题:不使用placeholder 创建input类似于placeholder的效果
/!*
focus 聚焦
blur 失焦
*!/
function focusHandler(e) {
if(e.type === "focus"){
if(this.value === "用户名")
this.value = "";
this.style.color = "#000000"
}else if(e.type === "blur"){
if(this.value.trim().length === 0){
this.style.color = "#cccccc";
this.value = "用户名"
}
}
}*/
// input事件, 输入事件,当改变文本框内容时,激活该事件
var username = document.getElementById("name");
username.addEventListener("input", inputHandler);
/*
* e.data 当前输入的内容
* inputType 输入的类型,插入文本,删除文本
* isComposing 是否开启输入法
*
* */
function inputHandler(e) {
console.log(e);
}
</script>
</body>
</html>


键盘事件:
<script>
document.addEventListener("keydown",keydownHandler);
document.addEventListener("keyup",keydownHandler);
/*
* e.code 当前按下的键 Key+键名
* e.key 当前按下的键 键名
* e.keyCode 键码值 用这个...
*
* 左上右下 37,38,39,40
* */
function keydownHandler(e) {
console.log(e);
}
</script>
滚轮(鼠标滚轮+笔记本触控板滚动)事件:

<script>
/*
* 火狐 DOMMouseScroll
* 谷歌和IE mousewheel
* 滚轮事件
*
* mousewheel
* deltaX:-0
* deltaY:-100 纵向向上 -100,向下是100
* deltaZ:0
* detail:0
* wheelDelta:120
* wheelDeltaX:0
* wheelDeltaY:120 纵向向上 120 向下 -120
*
* DOMMouseScroll
* detail: -3 滚轮向上-3 滚轮向下3;
*
*
* */
document.addEventListener("DOMMouseScroll", mouseHandler);
document.addEventListener("mousewheel", mouseHandler);
function mouseHandler(e) {
console.log(e);
}
</script>
小案例:下拉菜单

源代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
#dropMenu
{
position: relative;
}
button
{
width: 120px;
height: 30px;
background-color: transparent;
border: 1px solid #000000;
box-shadow: 1px 1px 1px #999999;
position: relative;
}
button span:first-child
{
margin-right: 20px;
font-size: 16px;
}
#sanjiao
{
display: inline-block;
width: 0;
height: 0;
border-top:10px solid #000000;
border-left:8px solid transparent;
border-right:8px solid transparent;
position: absolute;
right:10px;
top:10px;
}
ul{
width: 118px;
list-style: none;
border: 1px solid #000000;
position: absolute;
top:30px;
box-shadow: 1px 1px 1px #999999;
display: none;
}
li
{
background-color: #FFFFFF;
line-height: 30px;
cursor: default;
text-align: center;
padding-right: 10px;
border-bottom: 1px solid #000000;
}
li:last-of-type
{
border-bottom: none;
}
li:hover
{
background-color: #CCCCCC;
}
</style>
</head>
<body>
<div id="dropMenu">
<button><span></span><span id="sanjiao"></span></button>
<ul id="menu">
</ul>
</div>
<script>
var city=["北京","上海","广州","武汉","西安","南京","石家庄","青岛"];
var button,menu,dropMenu;
init();
function init() {
button=document.getElementsByTagName("button")[0];
menu=document.getElementById("menu");
dropMenu=document.getElementById("dropMenu");
for(var i=0;i<city.length;i++){
var li=document.createElement("li");
li.textContent=city[i];
menu.appendChild(li);
}
button.firstElementChild.textContent=city[0];
dropMenu.addEventListener("mouseleave",mouseLeaveHandler);
button.addEventListener("click",clickHandler);
menu.addEventListener("click",menuClickHandler);
}
function mouseLeaveHandler(e) {
menu.style.display="none";
}
function clickHandler(e) {
menu.style.display="block";
}
function menuClickHandler(e) {
if(e.target.constructor===HTMLUListElement) return;
button.firstElementChild.textContent=e.target.textContent;
menu.style.display="none";
}
</script>
</body>
</html>
来源:https://www.cnblogs.com/XJT2018/p/11107714.html


