【学习笔记九】
来源:互联网 发布:网络储备人才招聘 编辑:程序博客网 时间:2024/06/14 18:29
写在前面:
这篇是《js高程》13.4-13.6和14.1-14.4的笔记,记在网上也是方便自己以后随时随地可以回看。
13章前面的内容在 JS冒泡与捕获 那篇单独拎出来整理了。
其他详见代码注释 : )
PS :前面的EventUtil具体怎么来的可以看冒泡和捕获那篇↑
var EventUtil={ addHandler:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent('on'+type,handler); }else{ element['on'+type]=handler; } }, getEvent:function(event){ return event?event:window.event; }, getTarget:function(event){ return event.target||event.srcElement; }, preventDefault:function(event){ if(event.preventDefault){ event.preventDefault(); }else{ event.returnValue=false; } }, removeHandler:function(element,type,handler){ if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else(element.detachEvent){ element.detachEvent('on'+type,handler); }else{ element['on'+type]=null; } }, stopPropagation:function(event){ if(event.stopPropagation){ event.stopPropagation(); }else{ event.cancelBubble=true; } }};
【事件类型】
// UI事件-load\unloadvar isSupport=document.implementation.hasFeature('HTMLEvents','2.0');//两种指定方式//一:js,推荐//这里传入的event对象不包含有关这个事件的任何附加信息,//但在兼容DOM的浏览器中event.target被设为document,//而IE并不会为这个事件设置srcElement属性EventUtil.addHandler(window,'load',function(event){ alert('Loaded!');});//二:向后兼容 <body onload="alert('...')">//在图像上触发load时,要先指定事件再指定src,因为图像在指定src属性后就会开始下载EventUtil.addHandler(window,'load',function(){ //先向window添加load,因为要在dom中添加新元素,首先要确保文档加载完毕 var image=document.createElement('img'); EventUtil.addHandler(image,'load',function(event){ event=EventUtil.getEvent(event); alert(EventUtil.getTarget(event).src); }); document.body.appendChild(image); image.src='...';});//注:在不属于DOM文档的图像上触发load,IE8及以前版本不会生产event对象//IE9+、Firefox、Opera、Chrome、Safari3+中,<script>也可触发load//不同于img,只有在设置了<script>的src属性并将添加到文档后,才会开始下载js文件//所以指定事件处理程序和src属性的先后顺序就不重要//IE和Opera支持<link>上的load,未指定href并添加到文档之前也不会下载样式表EventUtil.addHandler(window,'unload',function(event){ alert('Unloaded!');});//生成的event对象在兼容dom的浏览器中只包含target,IE8及以前提供了srcElement
//鼠标与滚轮事件//dom通过event的relatedTarget属性提供相关元素信息,//这个属性只对mouseover、mouseout才包含值,对其他事件来说为null,//IE8及以前不支持relatedTarget,但在mouseover中有fromElement,在mouseout中有toElement//添加取得相关元素方法:var EventUtil={ //...其他代码 getRelatedTarget:function(event){ if(event.relatedTarget){ return event.relatedTarget; }else if(event.toElement){ return event.toElement; }else if(event.fromElement){ return event.fromElement; }else{ return null; } }, //...};var div=document.getElementById('myDiv');EventUtil.addHandler(div,'mouseout',function(event){ event=EventUtil.getEvent(event); var target=EventUtil.getTarget(event); var relatedTarget=EventUtil.getRelatedTarget(event); alert('moused out of'+target.tagName+'to'+relatedTarget.tagName);});//鼠标按钮//对mouseup和mousedown,event有一个button属性://值为0表示左键,1滚轮,2右键//IE8及以前://0没有按,1左键,2右键,3左右,4滚轮,5左键滚轮,6右键滚轮,7左右滚轮//Opera中不是操作左键不会触发mouseup和mousedownvar EventUtil={ //... getButton:function(event){ if(document.implementation.hasFeature('MouseEvents','2.0')){ return event.button; }else{ switch(event.button){ case 0: case 1: case 3: case 5: case 7: return 0;//01357都返回0 case 2: case 6: return 2;//26都返回2 case 4: return 1;//4返回1 } } }, //...};var div=document.getElementById('myDiv');EventUtil.addHandler(div,'mousedown',function(event){ event=EventUtil.getEvent(event); alert(EventUtil.getButton(event));});//鼠标滚轮事件//mousewheel事件对应的event有一个wheelDelta属性,向前滚动是值为120的倍数,向后-120的倍数//Opera9.5以前正负相反//Firefox支持DOMMouseScroll事件,detail属性,向前是-3的倍数,向后3的倍数
//键盘与文本事件//IE9、Firefox、Chrome、Safari的event支持一个charCode属性,//只有在发生keypress时才包含值,保存按键代表字符ASCII码,//keyCode通常为0或按键键码;//IE8及以前和Opera则在keyCode中保存ASCII码;var EventUtil={ //... getCharCode:function(event){ if(typeof event.charCode=='number'){ //先检查charCode是否包含数值,在不支持这个属性的浏览器中值为undefined return event.charCode; }else{ return event.keyCode; } }, //...};var textbox=document.getElementById('myText');EventUtil.addHandler(textbox,'keypress',function(event){ event=EventUtil.getEvent(event); var ch=EventUtil.getCharCode(event); alert(ch); alert(String.fromCharCode(ch)); //取得字符编码后可用String.fromCharCode()将其转换成实际字符});
//HTML5事件//contextmenu事件,用以表示合适应该显示上下文菜单,冒泡,属于鼠标事件//IE、Firefox、Safari、Chrome、Opera 11+EventUtil.addHandler(window,'load',function(event){ var div=document.getElementById("myDiv"); EventUtil.addHandler(div,'contextmenu',function(event){ event=EventUtil.getEvent(event); EventUtil.preventDefault(event);//取消浏览器默认菜单 var menu=document.getElementById('myMenu'); menu.style.left=event.clientX+'px'; menu.style.top=event.clientY+'px';//确定放置菜单(<ul>)的位置 menu.style.visibility='visible';//显示菜单 }); EventUtil.addHandler(document,'click',function(event){ document.getElementById('myMenu').style.visibility='hidden'; });//单词鼠标隐藏菜单});//beforeunload事件,在页面卸载操作之前阻止卸载操作//IE、Safari、Firefox、Chrome支持,但Opera11及以前不支持EventUtil.addHandler(window,'beforeunload',function(event){ event=EventUtil.getEvent(event); var message="Sure to navigate away from this page?"; event.returnValue=message;//IE、Firefox return message;//Safari、Chrome});
【内存与性能】
//事件委托,是对"事件处理程序过多"的解决方案,利用冒泡,只指定一个事件处理程序,管理某一类型所以事件。//最适合采用事件委托的事件有:click、mousedown、mouseup、keydown、keyup、keypress//如果可行,也可在document对象上添加一个事件处理程序,用以处理某种特定类型的事件/*<ul id="myLinks"> <li id="goSomewhere">Go somewhere</li> <li id="doSomething">Do something</li> <li id="sayHi">Say hi</li></ul> */var list=document.getElementById('myLinks');EventUtil.addHandler(list,"click",function(event){ event=EventUtil.getEvent(event); var target=EventUtil.getTarget(event); switch(target.id){ case "doSomething": document.title="I changed the document's title"; break; case "goSomewhere": location.href="http://www.wrox.com"; break; case "sayHi": alert("hi"); break; }});//移除事件处理程序//内存中留有那些过时不用的"空事件处理程序"的两种原因://1、从文档中移除带事件处理程序的元素,如纯粹DOM操作:removeChild()、replaceChild(),或用innerHTML替换 btn.onclick=function(){ btn.onclick=null;//先移除事件处理程序再替换 document.getElementById("myDiv").innerHTML="..."; };//注:在事件处理程序中删除按钮也能阻止事件冒泡,元素在文档中是冒泡的前提//2、卸载页面时(可能是在两个页面来回切换或刷新),内存中滞留的对象数目会增加// 最好的做法是,卸载之前先通过onunload事件处理程序移除所有事件处理程序
//可用js在任意时刻触发特定事件,在测试时非常有用//DOM中的事件模拟//在document对象上使用createEvent()创建event对象,接收一个参数,表示要创建事件类型的字符串//如:UIEvents\MouseEvents\MutationEvents\HTMLEvents//调用dispatchEvent()触发事件,接收一个参数,表示要触发事件的event对象,这样触发的事件照样冒泡//模拟鼠标事件//创建的对象有一个initMouseEvent()方法,用于指定与该鼠标事件有关的信息,接收15个参数,前5个为://type要触发的事件类型、bubbles是否冒泡、cancelable是否可以取消、view与事件关联的视图、detail与事件有关的详细信息var btn=document.getElementById("myBtn");var event=document.createEvent("MouseEvents");//初始化对象event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);btn.dispatchEvent(event);//模拟键盘事件var textbox=document.getElementById("myTextbox"),event;//以DOM3级方式创建事件对象if(document.implementation.hasFeature("KeyboardEvents","3.0")){ event=document.createEvent("KeyboardEvent"); event.initKeyboardEvent("keydown",true,true,document.defaultView,"a",0,"Shift",0); //'a' 按下的键码-按下了哪里的键,0是主键盘-空调图-在一行中按了多少次这个键,0}textbox.dispatchEvent(event);//在Firefox中var textbox=document.getElementById("myTextbox"),event;event=document.createEvent("KeyEvents");event.initKeyEvent('keypress',true,true,document.defaultView,false,false,false,false,65,65);//ctrl-alt-shift-meta-keyCode键码-charCode ASCII码textbox.dispatchEvent(event);//其他浏览器中,创建一个通用的事件var textbox=document.getElementById("myTextbox"),event;event=document.createEvent("Events");event.initEvent(type,bubbles,cancelable);event.view=document.defaultView;event.altKey=false;event.ctrlKey=false;event.shiftKey=false;event.metaKey=false;event.keyCode=65;event.charCode=65;textbox.dispatchEvent(event);//像这样模拟事件虽然会触发键盘事件,但却不会向文本框中写入文本,这是由于无法精确模拟键盘事件造成的//DOM3还定义了自定义事件,调用createEvent("CustomEvent"),//返回的对象有一个initCustomEvent()方法,接收四个参数://type、bubbles、cancelable、detail//IE9+、Firefox6+var div=document.getElementById('myDiv'),event;EventUtil.addHandler(div,'myevent',function(event){ alert('DIV:'+event.detail);});EventUtil.addHandler(document,"myevent",function(event){ alert('DOCUMENT:'+event.detail);});if(document,implementation.hasFeature("CustomEvents","3.0")){ event=document.createEvent("CustomEvent"); event.initCustomEvent("myevent",true,false,"hello world!"); div.dispatchEvent(event);}//IE中的事件模拟//调用document.createEventObject(),无参数,返回一个通用event对象,要手动添加必要信息,//在目标上调用fireEvent()方法,接收两个参数:事件处理程序名称和event对象,//在调用这个方法时会自动为event对象添加srcElement和type属性,其他属性手动添加var btn=document.getElementById('myBtn');var event=document.createEventObject();event.screenX=100;event.screenY=0;event.clientX=0;event.clientY=0;event.ctrlKey=false;event.altKey=false;event.shiftKey=false;event.button=0;btn.fireEvent("onclick",event);var textbox=document.getElementById("myTextbox");var event=document.createEventObject();event.altKey=false;event.ctrlKey=false;event.shiftKey=false;event.keyCode=65;textbox.fireEvent("onkeypress",event);
【表单基础】
//避免多次提交表单EventUtil.addHandler(form,'submit',function(event){event=EventUtil.getEvent(event);target=EventUtil.getTarget(event);var btn=target.elements['submit-btn'];btn.disabled=true;});
//focus()\blur()EventUtil.addHandler(window,'load',function(event){document.forms[0].elements[0].focus();});//如果第一个表单字段是<input>,且type为'hidden',上面代码会出错//如果css的display和visibility隐藏了该字段,同样致错//HTML5新增autofocus属性,自动把焦点移到相应字段//Firefox4+、Safari5+、Chrome、Opera9.6//<input type='text' autofocus>EventUtil.addHandler(window,'load',function(event){var element=document.forms[0].elements[0];if(element.autofocus!==true){//autofocus在支持的浏览器中是true,不支持的是空字符串element.focus();}});
//change事件常用于验证用户在字段中输入的数据var textbox=document.forms[0].elements[0];EventUtil.addHandler(textbox,'focus',function(event){event=EventUtil.getEvent(event);var target=EventUtil.getTarget(event);if(target.style.backgroundColor!='red'){target.style.backgroundColor='yellow';}});EventUtil.addHandler(textbox,'blur',function(event){event=EventUtil.getEvent(event);var target=EventUtil.getTarget(event);if(/[^\d]/.test(target.value)){target.style.backgroundColor='red';}else{target.style.backgroundColor='';}});EventUtil.addHandler(textbox,'change',function(event){event=EventUtil.getEvent(event);var target=EventUtil.getTarget(event);if(/[^\d]/.test(target.value)){target.style.backgroundColor='red';}else{target.style.backgroundColor='';}});
【文本框脚本】
//选择文本select(),无参。//应用:让用户在文本框获得焦点时选择所有文本,不必一个一个删除。//IE9+、Opera、Firefox、Chrome、Safari,只有用户选择且释放鼠标才触发select事件;//IE8及以前,只要选择一个字符,不释放鼠标,就触发;//调用select()会触发select事件;//HTML5新增selectionStart和selectionEnd属性//IE9+、Opera、Firefox、Chrome、Safari//IE8及以前用document.selection对象,保存着用户在整个文档范围选择的文本信息function getSelectedText(textbox){if(typeof textbox.selectionStart=='number'){return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd);}else if(document.selection){return document.selection.createRange().text;}}//HTML5选择部分文本:setSelectionRange(),两个参数,起始结束索引//IE9+、Opera、Firefox、Chrome、Safari//IE8及以前用范围选择文本function selectText(textbox,startIndex,stopIndex){if(textbox.setSelectionRange){textbox.setSelectionRange(startIndex,stopIndex);}else if(textbox.createTextRange){var range=textbox.createTextRange();range.collapse(true);//折叠范围,true表示折叠刀范围起点range.moveStart('character',startIndex);range.moveEnd('character',stopIndex-startIndex);range.select();}textbox.focus();}textbox.value='hello world!';selectText(textbox,0,textbox.value.length);
//过滤输入屏蔽字符//在Firefox中所有由非字符键触发的keypress事件对应字符编码0,Safari3以前为8EventUtil.addHandler(textbox,'keypress',function(event){event=EventUtil.getEvent(event);var target=EventUtil.getTarget(event);var charCode=EventUtil.getCharCode(event);if(!/\d/.test(String.fromCharCode(charCode))&&charCode>9&&!event.ctrlKey){EventUtil.preventDefault(event);}});
//剪切板事件://beforecopy、copy、beforecut、cut、beforepaste、paste//在Safari、Chrome、Firefox中三个before事件只会显示针对文本框的上下文菜单的情况触发,//IE会在触发copy、cut、paste之前先行触发before。////通过before可以向剪贴板发送数据,或者从剪贴板取得之前修改数据,//访问数据用clipboardData对象,IE中是window的属性,Firefox4+、Safari、Chrome中是event的属性,//在Firefox、Safari、Chrome中只有在处理剪贴板事件期间这个对象才有效,IE中可随时访问。////clipboardData的三个方法:getData()、setData()、clearData()//在Firefox、Safari、Chrome中只允许在onpaste事件处理程序中访问getData()////补充:可以在paste事件中确认剪贴板中的值是否有效,若无效可取消默认行为var EventUtil={//...getClipboardText:function(event){var clipboardData=(event.clipboardData||window.clipboardData);return clipboardData.getData('text');},setClipboardText:function(event){if(event.clipboardData){return event.clipboardData.setData('text/plain',value);}else if(window.clipboardData){return window.clipboardData.setData('text',value);}},//...};
//自动切换焦点//在前一个文本框字符数达到最大后,自动切换焦点到下一个文本框(function(){function tabForward(event){event=EventUtil.getEvent(event);var target=EventUtil.getTarget(event);if(target.value.length==target.maxLength){var form=target.form;for (var i = 0,len=form.elements.length; i < len; i++){if(form.elements[i]==target){if(form.elements[i+1]){form.elements[i+1].focus();}return;}}}}var textbox1=document.getElementById('txtTel1');var textbox2=document.getElementById('txtTel2');var textbox3=document.getElementById('txtTel3');EventUtil.addHandler(textbox1,'keyup',tabForward);EventUtil.addHandler(textbox2,'keyup',tabForward);EventUtil.addHandler(textbox3,'keyup',tabForward);//keyup会在用户输入了新字符后出发,此时是检测内容长度最佳时机})();
【选择框脚本】
//取得所有选中项//遍历选项集合,然后测试每个选项的selected属性function getSelectedOptions(selectbox){var result=new Array();var option=null;for (var i = 0,len=selectbox.options.length; i < len; i++) {option=selectbox.options[i];if(option.selected){result.push(option);}}return result;}
//动态创建选项的三种方法://1、DOM方法var selectbox=document.forms[0].elements['location'];var newOption=document.createElement('option');newOption.appendChild(document.createTextNode('Option text'));newOption.setAttribute('value','Option value');selectbox.appendChild(newOption);//2、使用Option构造函数//IE中存在bug,不能正确设置新选项的文本var newOption=new Option('Option text','Option value');selectbox.appendChild(newOption);//3、使用选择框的add(newOpt,relOpt)方法//该方法在relOpt之前插入newOpt,若要插入到最后,应将relOpt设为null,//IE中第二个参数可选,但必须是新选项之后选项的索引,//兼容DOM的浏览器要求必须指定第二个参数,//所以,//将relOpt设为undefined,兼容所有浏览器插入到最后//(插入其他位置用DOM+insertBefore()方法)var newOption=new Option('Option text','Option value');selectbox.add(newOption,undefined);
//移除选项的三种方式://1、DOM的removeChild()方法selectbox.removeChild(selectbox.options[0]);//2、使用选择框的remove()方法selectbox.remove(0);//3、将相应选项设为nullselectbox.options[0]=null;
//移动和重排选项//将第一个选择框中的第一个选项移动到第二个选择框var selectbox1=document.getElementById('selLocations1');var selectbox2=document.getElementById('selLocations2');selectbox2.appendChild(selectbox1.options[0]);//在选择框中向前移动一个选项的位置var optionToMove=selectbox.options[1];selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index-1]);//在选择框中向后移动一个选项的位置var optionToMove=selectbox.options[1];selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index+2]);//注:IE7存在页面重绘问题,有时用DOM方法重排的选项不能马上正确显示
【表单序列化】
function serialize(form){var parts=[],field=null,i,len,j,optLen,option,optValue;for(i = 0,len=form.elements.length; i < len; i++) {field=form.elements[i];switch(field.type){//type属性未定义的不需要序列化case "select-one":case "selsct-multiple":if(field.name.length){for(j=0,optLen=field.options.length;j<optLen;j++){option=field.options[j];if(option.selected){optValue='';if(option.hasAttribute){//兼容DOM的浏览器中optValue=(option.hasAttribute('value')?option.value:option.text);//如果不存在value特性,或存在但为空字符串,用选项的文本来代替}else{//IEoptValue=(option.attributes['value'].specified?option.value:option.text);}parts.push(encodeURIComponet(field.name)+'='+encodeURIComponet(optValue));}}}break;case undefined:case "file":case "submit":case "reset":case "button":break;case "radio":case "checkbox":if(!field.checked){break;}default://不包含没有名字的表单字段if(field.name.length){parts.push(encodeURIComponet(field.name)+'='+encodeURIComponet(optValue));}}}return parts.join("&");}
阅读全文
0 0
- J2ME学习笔记(九)
- Allegro学习笔记九
- 汇编语言学习笔记(九)
- C#学习笔记(九)
- HTML学习笔记九
- Struts2学习笔记九
- oracle11g学习笔记(九)
- 学习笔记(九)
- c++学习笔记九
- OpenGL学习笔记(九)
- Java学习笔记九
- Django 学习笔记(九)
- OOAD 学习笔记 九
- c++学习笔记九
- CUDA学习笔记九
- JavaScript学习笔记九
- Vue学习笔记九
- 【学习笔记九】
- 1104: 求因子和(函数专题)
- 最近在看的项目DEMO
- 155. Min Stack
- LeetCode 290. Word Pattern
- Failed to load class "org.slf4j.impl.StaticLoggerBinder"解决方案
- 【学习笔记九】
- linux源码阅读第一弹
- 1105: 判断友好数对(函数专题)
- 短信验证码
- JavaScript进阶之函数
- 2017-09-17 —— 2017-09-23 总结
- Java实现十进制到各种进制的转换
- Matlab实现BP神经网络
- 总结 lxs contest 4&5&6&7&8&9