本内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。
DOM规范并没有包括所有浏览器支持的所有事件,很多浏览器实现了一些自定义的事件,这些事件后来都被HTML5所支持;
上下文菜单(contextmenu)事件:
Win95在PC应用程序中引入的上下文菜单的概念,即鼠标右击调出的菜单或者按下键盘上的菜单键时调出的菜单,后来,这个概念被引入Web领域;为了实现上下文菜单,需要确定何时应该显示上下文菜单,以及如何屏蔽与该操作关联的默认上下文菜单;为了解决这个问题,就出现了contextmenu这个事件,以便开发人员取消默认的上下文菜单而提供自定义的菜单;
document.addEventListener("contextmenu",function(event){console.log(event);//MouseEventevent.pventDefault();},false);
contextmenu事件属于鼠标事件类型,所以其事件对象中包含与鼠标位置有关的所有属性;为了表明它是鼠标事件类型且是右击,所以其button值为2、which值为3;其target为发生用户操作的元素
该事件是冒泡的,因此可以为document指定一个事件处理程序,用以处理页面中所有此类事件;
通常使用contextmenu事件来显示自定义的上下文菜单,而使用onclick事件处理程序来隐藏该菜单;
style#contextmenu{width:px;height:px;background-color:lightblue;z-index:;position:absolute;border:1pxsolidgray;box-shadow:2px2px3px#;}.show{visibility:visible;}.hidden{visibility:hidden;}/stylescriptwindow.onload=function(){varmenu=document.cateElement("div");menu.id="contextmenu";menu.className="hidden";document.body.appendChild(menu);bindEvent(document,"contextmenu",openContextMenu);bindEvent(document,"click",closeContextMenu);functionopenContextMenu(event){event.pventDefault();event=event
window.event;varbutton=event.button;if(button==2){varpos=getContextMenuPosition(event);menu.style.left=pos.left+"px";menu.style.top=pos.top+"px";menu.className="show";}}functioncloseContextMenu(event){menu.className="hidden";}//防止菜单超出了边界functiongetContextMenuPosition(event){varx=event.clientX,y=event.clientY;varvx=document.documentElement.clientWidth,vy=document.documentElement.clientHeight;varmw=menu.offsetWidth,mh=menu.offsetHeight;turn{left:(x+mw)vx?(x-mw):x,top:(y+mh)vy?(y-mh):y}}functionbindEvent(element,eventType,callback){varieType="on"+eventType;if(ieTypeinelement)element[ieType]=callback;elseif("attachEvent"inelement)element.attachEvent(ieType,callback);elseelement.addEventListener(eventType,callback,false);}}/script
befounload卸载前事件:
当浏览器窗口关闭或刷新时,会触发该事件,该事件应该注册在window对象上,当触发这个事件时,当前页面不会直接关闭,可以通过它来取消卸载并继续使用原有页面,目的是为了让开发人员有可能在页面卸载前阻止这一操作,但不能彻底取消这个事件,意图是将控制权交给用户,其会显示消息告知用户当前页面将要被卸载,询问用户是否真的要关闭页面,由用户来决定;
该事件不冒泡;
window.addEventListener("befounload",function(event){debugger;console.log(event);//BefoUnloadEvent});
在此事件中不能调用window.alert(),window.confirm()以及window.prompt()方法,因为对于befounload和unload事件,要求事件处理函数内部不能阻塞当前线程,而这些方法都会阻塞当前线程,因此H5规范中明确规定在befounload和unload中直接无视这几个方法的调用;
为了显示对话框,询问用户是否真的要离开该页面,根据规范,应该在事件处理程序中调用pventDefault()方法,但并不是所有浏览器都遵守这个规范,如:
window.addEventListener("befounload",function(event){event.pventDefault();console.log(event);//BefoUnloadEvent});
IE会显示一个默认的对话框(确实要离开此页吗?离开此面/留在此页),但其它浏览没有反应;
如果要实现自定义的提示,可以让事件处理程序返回一个字符串,或者将event.turnValue的值设置为要显示的字符,如:
turn"确实要走吗?";//或event.turnValue="不要走啊";
IE会显示对话框,并且包括返回的字符串,但其它浏览器不支持,其他浏览器必须将它作为函数的值返回,如:
window.addEventListener("befounload",function(event){event.pventDefault();turnevent.turnValue="不要走啊";});
示例:自动保存数据:
forminputid="username"type="text"/inputid="userage"type="text"//formscriptwindow.onload=function(event){varobj=localStorage.getItem("userObj");if(obj){obj=JSON.parse(obj);varusername=document.getElementById("username");varuserage=document.getElementById("userage");username.value=obj.username;userage.value=obj.userage;varh1=document.cateElement("h1");h1.innerHTML="自动保存的数据:";username.pantNode.insertBefo(h1,username);}}window.addEventListener("befounload",function(event){varusername=document.getElementById("username");varuserage=document.getElementById("userage");varobj={};if(username.value){obj.username=username.value;}if(userage.value){obj.userage=userage.value;}if(obj)localStorage.setItem("userObj",JSON.stringify(obj));});/script
befounload先于unload事件触发;
经常会有一些在用户离开页面前执行一些业务的应用场景,这都要用到onbefounload事件;比如记录用户停留时长的业务,在GA等页面访问统计的应用中都包含这个:
(function(){varstartTime=Math.ceil(newDate().getTime()/),getDuration=function(){vartime="",hours=0,minutes=0,seconds=0,endTime=Math.ceil(newDate().getTime()/),duration=endTime-startTime;hours=Math.floor(duration/);minutes=Math.floor(duration%/60);seconds=Math.floor(duration%%60);time=(hours10?"0"+hours:hours)+":"+(minutes10?"0"+minutes:minutes)+":"+(seconds10?"0"+seconds:seconds);turntime;};window.onbefounload=function(e){varduration=getDuration();//submitduration}})();
DOMContentLoaded事件:
window的load事件会在页面中的一切都加载完毕时触发,但这个过程可能会因为要加载的外部资源过多而等待的时间过长;DOMContentLoaded事件则在形成完整的DOM树之后就会触发,不需要等待图像、JS文件、CSS文件或其他资源是否已经下载完毕;
利用此事件,可以为document或window添加事件处理程序;
imgsrc="images/1.jpg"width=""/scriptdocument.addEventListener("DOMContentLoaded",function(event){console.log("DOM准备完毕");debugger;console.log(event);//Event},false);/script
该事件对象是Event类型,其不会提供任何额外的信息,也可以注册在window对象上,其target是document;
该事件始终会在load事件前触发,因此,该事件的目的,就是支持在页面下载的早期添加事件处理程序,使用户能够尽早地与页面进行交互;;
IE8及以下浏览器不支持该事件,可以在页面加载期间设置一个时间为0毫秒的超时调用:在页面下载和重构期时,只有一个js处理过程,因此超时调用会在该过程结束时立即触发;至于这个时间与DOMContentLoaded的时间能否同步,主要取决于浏览器和页面中的其他代码;为了确保有效,必须将其作为页面中的第一个超时调用;即使如此,也无法保证在所有环境中一定会早于load事件被触发,如:
setTimeout(function(){console.log("DOMContentLoaded");//后执行},0);console.log("begin");//先执行
还有两种方案:一种是创建空script标签,属性拥有defer,然后待onadystatechange为