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