【Python全栈-JavaScript】js Event()对象
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个阶段
捕获阶段 ---> 目标阶段 ---> 冒泡阶段
-->
- 北京
- 昌平
- 沙河
- 城关
- 回龙观
- 天通苑
- 海淀
- 朝阳
- 东城
- 西城
- 昌平
- 山东
- 山西
- 河北
- 保定
- 石家庄
- 张家口
- 张北
- 崇礼
- 下花园
- 宣化
- 承德
- 邯郸
- 河南
- 郑州
- 许昌
- 洛阳
- 驻马店
- 信阳
- 罗山
- 竹竿镇
- 楠杆镇
- 子路镇
- 青山镇
- 灵山镇
- 莽张镇
- 周党镇
- 光山
- 息县
- 潢川
- 新县
- 正阳
- 商城
- 固始
- 淮滨
- 罗山
阻止系统默认事件:
/* * 阻止系统默认事件的几种类型: * 1.阻止提交表单(跳转) * 2.阻止系统右键菜单(contextmenu事件中使用) * 3.阻止图片拖动时的禁用效果 * * *//* 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
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(); 阻止默认事件,鼠标右击不会呼出菜单 }
设置DOM对象的位置
小案例-div跟随鼠标:
源代码:
Title
拖拽效果:
拖拽1-拖拽 0123
小案例-拖拽碰撞
源代码:
知识点:分开写 拖拽函数,随机位置函数,碰撞函数 ,将这些常用的功能函数放在 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; } } })();Utils.js
拖拽碰撞2-拖拽碰撞 01
Event对象
form对象的一些事件

change: 单选框改变触发 ,或者select 下拉框选择改变也会触发事件。
//------------------------------------------------------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判断加载完成
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窗口缩放时触发事件
form对象的一些事件
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事件, 输入事件,当改变文本框内容时,激活该事件
超链接Title 什么样的elem能够focus获取焦距?能通过键盘上Tab键选中的元素
键盘事件:
滚轮(鼠标滚轮+笔记本触控板滚动)事件:
小案例:下拉菜单
源代码:
Title