支流浏览器的内核
IE:tridentChrome:webkit/blinkfirefox:GeckoOpera:prestoSafari:webkit
引入JS的形式
页面内嵌标签(可在head内或body内)内部引入(罕用办法)
JS根本语法
变量:变量申明:申明,赋值合成。繁多var。 (var a=100)命名规定:变量名必须以英文字母,*,$结尾*变量名能够包含英文字母,,$,数字不能够用零碎的关键字,保留字作为变量名值类型(数据类型):不可扭转的原始值(栈数据):Number,Boolean,String,undefined,null栈内存和栈内存之间赋值是拷贝(互不影响)援用值(堆数据):array,Object,function,..data,RegExptypeof()可查看数据类型(返回number,string,boolean,object,undefined,function)类型转换:显式类型转换:Number(mix) 转换不了的就显示为NaN parseInt(string,radix) string以radix进制为基底转换为10进制 parseFloat(string) num.toString(radix) num转为radix进制 String(mix) Boolean() 隐式类型转换:isNaN() 先转为number,再与NaN比拟 ++/-- +/-(正负)转为数字类型 + 转为字符串 - * / % 转为数字类型 '1'*1=1 && || ! < > <= >= 字符串与数字比拟,转为数字再比拟。字符串与字符串比拟,比拟ascii码 == != 转为数字再比拟不产生类型转换:===,!==语句的根本规定:每一句前面要以分号完结(除函数,for语句,if语句...)js语法错误(低级谬误,逻辑谬误)会引发后续代码终止,但不会影响其余js代码块书写格局要标准,'=+/-'两边要有空格运算操作符:'+':数学运算,字符串连贯。 任何数据类型加字符串都等于字符串'-','*','/','%','=','()':'()'优先级最高,'='优先级最低 '++','--','+=','-=','/=','*=','%='e.g. var a = 10 ; var b = ++a - 1 + a++ (此时b等于21,a等于12) var a = 1 ; var b = a-- + --a (此时b等于0(先算--a,而后b=0+0=0),a等于-1) 比拟运算符:'>','<','==','>=','<=','!='(比拟后果为boolean值) NaN!=NaN逻辑运算符:'&&'(碰到假就停),'||'(碰到真就停),'!'(运算后果为实在的值)e.g. var a = 1 && 2+2 (a为4) var a = 0 && 2+2 (a为0) var a = 2+1 && 0 (a为0) var a = 1 || 3 (a为1) var a = 0 || 2 (a为2) (window.foo || (window.foo='bar')) (window.foo的值为bar(先看括号的))被认定为false的值:undefined,null,NaN,'',0,false条件语句:if,if else if,switch case,break,continue循环语句:for,while,do while
函数
定义:函数申明(function xxx(){})函数表达式(命名函数表达式:var test=function xxx(){}, 匿名函数表达式(罕用):var test=function (){})组成模式:函数名称(小驼峰准则 如theFirstName) 参数:形参(获取形参长度:函数名.length),实参(arguments示意的是实参列表,获取实参长度:arguments.length) 返回值e.g.1 求5的阶乘(递归) function mul(n){ if(n==1 || n==0) { return 1 } return n*mul(n-1); } mul(5);
作用域
作用域定义:变量和函数失效的区域(存储了运行期上下文的汇合)作用域的拜访程序:函数外面的能够拜访里面的值(外面的能够拜访里面的,里面的不能拜访外面的)函数被定义时,会在作用域链中生成一个GO对象函数被执行时,会在作用域链中多生成一个AO对象,此时0号地位是AO,1号地位是GO当多个函数为蕴含关系时,各函数作用域链的变动: e.g. function a(){ function b(){ function c(){ } c(); } b(); } a(); a defined a.[[scope]] --> 0:GO a doing a.[[scope]] --> 0:aAO 1:GO b defined b.[[scope]] --> 0:aAO 1:GO b doing b.[[scope]] --> 0:bAO 1:aAO 2:GO c defined c.[[scope]] --> 0:bAO 1:aAO 2:GO c doing c.[[scope]] --> 0:cAO 1:bAO 2:aAO 3:GO with会扭转作用域链:with(拜访的对象){执行的代码} 若拜访的对象没有对应的变量,则在本来执行的这个函数体中找变量。 e.g. var obj={name:'obj'}; function test(){ var age=123; var name='scope'; with(obj){ console.log(name); //输入obj console.log(age); //输入123 } }
JS三部曲(预编译重点)
语法分析预编译(产生在函数执行的前一刻)解释执行预编译:函数申明整体晋升 变量申明晋升预编译前奏:imply global暗示全局变量:即任何变量,如果变量未经申明就赋值,此变量为全局对象(window)所有(var a=b=123(b为经申明就赋值,归window所有。所以window.a为undefined,window.b为123)) 所有申明的全局变量,全是window的属性(var a=123 => window.a=123)预编译过程四部曲:创立AO对象 找形参和变量申明,将变量和形参名作为AO属性名,值为undefined 将实参值和形参对立 在函数体外面找函数申明,值赋予函数体e.g. function fn(a){ 1.创立AO对象(执行期上下文) console.log(a); 2.找形参和变量申明 var a=123; AO{a:undefined,b:undefined} console.log(a); 3.将实参和形参对立 function a(){}; AO{a:1,b:undefined} console.log(a); 4. 找函数申明 var b=function(){} AO{a:function a(){},b:undefined,d:function d(){}} console.log(b); function d(){} } fn(1)所以第一个console.log(a)打印的是function a(){} 此时执行var a=123,所以此时AO{a:123,b:undefined,d:function d(){}}第二个console.log(a)打印的是123此时不必再看function a(){}(因为预编译曾经看过了)第三个console.log(a)打印的是123此时执行var b=function (){},所以此时AO{a:123,b:function (){},d:function d(){}}第四个console.log(b)打印的是function (){}若一个变量未经申明就赋值,会把此变量放到GO对象(window)中e.g.1 console.log(test); function test(test){ console.log(test); var test=234; console.log(test); function test(){}; } test(1); var test=123; 先创立GO对象:GO{test:function (){...}} 再创立AO对象:AO{test:function (){}} 所以第一个console.log(test)为function(){} 第二个为function(){} 执行var test=234,所以AO{test:234} 第三个为234 e.g.2 global=100; function fn(){ console.log(global); global=200; console.log(global); var global=300; } fn(); var global; 先创立GO:{global:100} 再创立AO:{global:undefined} 此时第一个输入为undefined(AO中有的就先从AO中找) 再执行global=200;此时AO:{global:200} 所以第二个输入为200 e.g.3 function test(){ console.log(b); if(a){ var b=100; } console.log(b); c=234; console.log(c); } var a; test(); a=10; console.log(c); 先创立GO:{a:undefined} 再创立AO:{b:undefined} 第一个输入为undefined 此时a为undefined,不能执行var b=100 所以第二个输入为undefined 执行c=234,AO里没有c,则把变量c增加到GO中,此时GO{a:undefined,c:234} 第三个输入为234 再执行a=10,此时GO{a:10,c:234} 第四个输入为234 e.g.4 var x=1; if(function f(){}){ x+=typeof f; } console.log(x); 因为(function f(){})为表达式,所以f是undefined 所以x输入为1undefined (未经申明的变量放在typeof中不会报错,为undefined) 对于GO和AO对象,若AO上没有相应变量,则再去GO上找 预编译时会疏忽掉判断的语句 GO和AO对象实则是执行期上下文
立刻执行函数
立刻执行函数次要针对初始化性能的函数(执行完就被销毁)(function (形参(可有可无)){}(实参(可有可无)))只有表达式能力被执行符号执行如:var test=function (){}(); +function test(){}(); (function test(){})();
闭包(重点)
闭包的生成:当外部函数被保留到内部的时候闭包的防备:闭包会导致多个执行函数共用一个私有变量,如果不是非凡须要,应尽量避免这种状况产生闭包的作用:实现私有变量(函数累加器) 能够做缓存(存储构造) 能够实现封装,属性私有化 模块化开发,避免净化全局变量可用立刻执行函数解决闭包e.g. 给4个li绑定点击事件 var li=document.getElementByTagName('li'); for(var i=0;i<li.length;i++){ (function (j){ li[j].onclick=function(){ console.log(j) }(i)) }
对象
属性的增,删,改,查:增:对象名.属性名=属性值删:delete 对象名.要删除的属性名改:对象名.要批改的属性名=新的属性值查:对象名.要查看的属性名对象的创立办法:1. 对象字面量/对象间接量 var obj={}2. 构造函数(大驼峰命名规定:如TheFirstName):零碎自带的构造函数Object():var obj=new Object() 自定义:function 函数名(){this.属性名=属性值...} var 对象名= new 函数名()3. var obj=Object.create(原型/null)(创建对象的同时可自定义原型)革新函数的外部原理:1.在函数体最后面隐式的加上this={}(AO:{this:{xxx}}) 2.执行this.xxx=xxx 3.隐式的返回this(构造函数中返回值不能返回原始值,会疏忽掉,主动返回this) 包装类:new String() new Boolean() new Number() e.g. var str='abc'; str+=1; var test=typeof(str); if(test.length==6){ test.sign='typeof的返回后果可能为String'; (原始值赋属性值要调用包装类,赋和没赋一样) //new String(test).sign='xxx' 随后delete } //new String(test).sign(为undefined) cosnole.log(test.sign); 输入的后果为undefined
原型
原型是function对象的一个属性,它定义了构造函数制作进去的对象的公共先人通过该构造函数产生的对象,能够继承该原型的属性和办法原型也是对象利用原型能够提取私有的属性对象查看原型:隐式属性__proto__ (函数名.prototype)对象查看对象的构造函数:constructor判断是否为本身的属性:对象名.hasOwnProperty(属性值)e.g. Person.prototype.name='sunny' function Preson(){} var person=new Preson(); Preson.prototype.name='cherry'; 此时 person.name='cherry' Person.prototype.name='sunny' function Preson(){} var person=new Preson(); Preson.prototype.name={name:'cherry'} 相似于 var obj={name:'a'}; var obj1=obj; obj={name:'b'};(新开的空间) 所以此时 person.name还是等于'sunny'(此时的__proto__还是指向原来的Person.prototype)原型链中绝大多数对象最终都会继承自Object.prototypeundefined和null没有原型扭转this指向:call,applycall:原来的函数名.call(this要指向的函数名,参数)apply:原来的函数名.apply(this要指向的函数名,[参数])call和apply的区别:传参数的模式不同 call是要把实参依照形参的个数传进去 apply是传一个arguments
继承模式
1. 传统模式(原型链):过多的继承了没用的属性2. 借用构造函数:不能继承借用构造函数的原型 每次构造函数都要多走一个函数3. 共享原型:不能轻易改变本人的原型4. 圣杯模式 第一种写法: function inherit(Target,Origin){ function F(){}; F.prototype=Origin.prototype; Target.prototype=F.prototype; Target.prototype.constructor=Target; Target.prototype.uber=Origin.prototype; } 第二种写法: var inherit=(function (){ var F=function (){}; return function(Target,Origin){ F.prototype=Origin.prototype; Target.prototype=F.prototype; Target.prototype.constructor=Target; Target.prototype.uber=Origin.prototype; } }())
命名空间
治理变量,避免净化全局,实用于模块化开发可应用闭包的办法实现变量私有化,从而避免变量净化var name='bcd';var init=(function (){ var name='abc'; function callName(){ console.log(name); } return function(){ callName(); }}())init();此时打印进去的name还是abc还可应用Webpack等
JS实现链式调用模式(仿JQ)
如:obj.eat().smoke().drink()在每个办法前面return this
对象枚举
数组遍历:for循环数组长度对象遍历:for in循环for(var xxx(自定义) in 对象名){console.log(对象名[xxx])}
辨别数组,对象的三种办法
办法一:instanceof判断A对象是不是B构造函数结构进去的(判断A对象的原型链上有没有B的原型):A instanceof B数组:[] instanceof Array --> true 对象:{} instanceof Object --> true办法二:constructor对象:obj={},obj.constructor --> function Object()数组:arr=[],arr.constructor --> function Array()办法三:toString()数组:Object.prototype.toString.call([]) --> [object Array]对象:Object.prototype.toString.call([]) --> [object Object]
对于this
函数预编译过程 this -> window全局作用域里 this -> windowcall/apply可扭转函数运行时的指向obj.func(); func()外面的this指向obj(谁调用this指向谁)e.g.1 var name='222'; var a={ name:'111', say:function(){ console.log(this.name); } } var fun=a.say; fun(); //全局调用 a.say(); //a调用 var b={ name:'333', say:function(fun){ fun(); } } b.say(a.say); //没有阐明是this调用,只是把a.say这个办法传进来执行(相当于借用这个办法在b外面执行),此时还是全局调用 b.say=a.say; b.say(); //此时为b调用 顺次的输入后果为:222,111,222,333 e.g.2 var foo=123; function print(){ this.foo=234; console.log(foo); } print(); 执行this.foo=234时,此时this指向window,扭转GO中foo的值为234 所以输入后果为234 若把上题的print()改为new print():因为此时的this=Object.create(print.prototype),this不指向window了 所以此时输入后果为123 e.g.3 var a=5; function test(){ a=0; alert(a); alert(this.a); var a; alert(a); } test(); 顺次输入0 5 0 new test(); 顺次输入0 undefined(this下面没有a) 0 e.g.4 var bar={a:'002'}; function print(){ bar.a='a'; Object.prototype.b='b'; return function inner(){ console.log(bar.a); console.log(bar.b); } } print()();(相当于先返回一个函数,再进行函数执行) 顺次输入为a,b arguments.callee:会指向本人的援用。援用该函数的函数体内的以后正在执行的函数。当函数名称未知时,例如在没有名称的函数表达式中(也称为“匿名函数”),此性能很有用。e.g. var num=(function(n){ if(n==1){ return 1 } return n * arguments.callee(n-1) }(100)) func.caller:返回调用指定函数的函数 留神:arguments.callee和func.caller在严格模式下都不能应用
克隆
浅层克隆和深层克隆的区别: 浅层克隆:当克隆援用值时,两个对象会共用一个援用地址,造成互相的烦扰,即我改,它也改 深层克隆:克隆进去的对象和原来的对象是互相独立的,互不影响。也就是对新对象的批改都不会反映到原对象中 浅层克隆: function clone(origin,target){ var target=target || {}; for(var prop in origin){ target[prop]=origin[prop]; } return target; } 深层克隆: 实现步骤: 1. 判断是不是原始值 (typeof) 2. 判断是数组还是对象(instanceof,toString(举荐应用),constructor) 3. 建设相应的数组或对象 4. 递归 function deepClone(origin,target){ var target=target || {}; var toStr=Object.prototype.toString; var arrStr="[object Array]"; for(var prop in origin){ if(origin.hasOwnProperty(prop)){ //要克隆本身的属性 if(origin[prop] !== "null" && typeof(origin[prop])=='object'){ if(toStr.call(origin[prop])==arrStr){ //克隆的属性是个数组 target[prop]=[]; //新建一个数组 } else{ //克隆的属性是个对象 target[prop]={}; //新建一个对象 } deepClone(origin[prop],target[prop]) } else{ //原始值间接拷贝 target[prop]=origin[prop]; } } }
数组和类数组
创立数组的办法:var arr=[];var arr=new Array(1,2,3,4);var arr=new Array(10); new Array():当为一个参数n时示意新开一个长度为n的数组空间 当为多个参数时示意数组里的值 数组的读和写: arr[n]:读,但不能够溢出读,要不然后果为undefined arr[n]=xxx:写,能够溢出写 数组罕用的办法: 会扭转原数组的:push(在数组开端增加数据) pop(剪切数组开端的数据) shift(剪切数组后面的数据) unshift(在数组后面增加数据) sort(数据排序,默认升序):arr.sort(function(a,b){return x(若x为正数时,那么后面的数放在后面。若x为负数,那么前面的数放在后面。若x为0,则不动。可间接利用return a-b进行升序,return b-a进行降序)}) 可利用sort生成一个乱序数组:xxx.sort(function(){ return Math.random()-0.5 }) reverse(数据反转倒序) splice(切片):splice(从第几位开始,截取多少长度,在切口处增加新的数据) 不会扭转原数组的:concat(数组拼接) join(连贯):join('x')依照'x'来连贯数组里的数据 split(拆分):solit('x')依照'x'来拆分数组里的数据,拆分为字符串 toString(变成字符串) slice(截取):slice(从该位开始截取,截取到该位) 类数组: 能够利用属性名模仿数组的个性 能够动静的增长length属性 如果强行让类数组调用push办法,则会依据length属性值的地位进行属性的裁减 属性要为索引(数字)属性,必须有length属性,最好加上push e.g. var obj={ "2" : "a", "3" : "b", "length" : 2, "push" : Array.prototype.push } obj.push('c'); obj.push('d'); 输入后果obj push的原理是: Array.prototype.push=function(target){ this[this.length]=target; this.length++; } 所以obj.push('c'),在这个obj中相当于obj[obj.length(即为2)]='c',而后再length++ 随后obj.push('d'),相当于obj[3]='d' 所以输入的obj为{ "2" : "c", "3" : "d", "length" : 2, "push" : Array.prototype.push } 实现数组的去重(在原型链上实现): Array.prototype.unique=function(){ var temp={}; var arr=[]; //搁置去重完后的数组 var len=this.length; for(var i=0;i<len;i++){ if(!temp[this[i]]){ //若没有对应的属性值 temp[this[i]]='abc'; arr.push(this[i]); } } return arr; }
Try...catch
在try外面的产生谬误,不会执行谬误后的try外面的代码,但还会仍然执行里面的代码try{}catch(e){}常见的错误信息(error.name的六种对应信息):1. EvalError:eval()的应用与定义不统一2. RangeError:数值越界3. ReferenceError:非法或不能辨认的援用数值4. SyntaxError:产生语法解析谬误5. TypeError:操作数类型谬误6. URLError:URL处理函数使用不当
es5严格模式
"use strict"(要写在页面逻辑的最顶端)不再兼容es3的一些不规则语法,应用全新的es5标准。两种用法:全局严格模式 部分函数内严格模式(举荐)"use strict"就是一行字符串,不会对不兼容严格模式的浏览器产生影响。不反对with,arguments,callee,func,caller,变量赋值前必须申明,部分this必须被赋值(Person.call(null/undefined)赋值什么就是什么),回绝反复属性和参数
DOM操作
DOM定义了示意和批改文档所需的办法。DOM对象即为宿主对象,由浏览器厂商定义。用来操作html和xml性能的一类对象的汇合。对节点的增删改查查: (除了getElementsById匹配进去是一个,其余匹配进去都是类数组(要在开端加上[n(0,1,2,...)])) document.getElementById('id名') 依据元素id匹配相应的元素(在IE8以下的浏览器不辨别id名大小写) document.getElementsByTagName('标签名') 依据元素标签名匹配相应的元素 document.getElementsByName('name名') 依据元素的标签name匹配相应的元素 document.getElementsByClassName('类名') 依据元素标签名匹配相应的元素(在IE8和IE8以下的浏览器没有,能够多个class一起) document.querySelector('CSS选择器字符串') 匹配指定 CSS 选择器的一个元素(在IE7和IE7以下的版本没有)不能实时更新 document.querySelectorAll('CSS选择器字符串') 匹配指定 CSS 选择器的一组元素(在IE7和IE7以下的版本没有)不能实时更新增: document.createElement():创立元素节点 document.createTextNode():创立文本节点 document.createComment():创立正文节点 document.createDocumentFragment():创立虚构的节点对象(可在其中增加DOM节点以构建屏幕外DOM树)插: 要增加到的区域.appendChild(要增加的节点):从前面增加一个子节点到页面(是一种剪切操作) 要增加到的区域.insertBefore(要增加的节点,要在此节点前增加的节点):从后面增加一个子节点到页面 封装函数insertAfter(): Element.prototype.insertAfter(targetNode,afterNode){ var beforeNode=afterNode.nextElementSibling; if(beforeNode==null){ //若是最初一个节点,则间接在其前面插入 this.appendChild(targetNode); } else{ //在要插的下一个节点前插入(相当于插在要插节点的前面) this.insertBefort(targetNode,beforeNode); } }删: 父节点.removeChild():父节点移除子节点(剪切操作) 节点.remove():节点本人移除本人(删除操作)替换: 父节点.replaceChild(new,origin):替换子节点 遍历节点树:parentNode:父节点(最顶端的parentNode为#document)childNodes:子节点们firstChild:第一个子节点lastChild:最初一个子节点nextSibling:后一个兄弟节点previousSibling:前一个兄弟节点节点的类型:元素节点(1) 属性节点(2) 文本节点(3) 正文节点(8) document(9) DocumentFragment(11) 基于元素节点树的遍历:parentElement:返回以后元素的父元素节点(IE不兼容)children:只返回以后元素的元素子节点node.childElementCount(相当于node.children.length):返回以后元素节点的子元素个数firstElementChild:返回第一个元素节点(IE不兼容)lastElementChild:返回最初一个元素节点(IE不兼容) nextElementSibling:返回后一个兄弟元素节点previousElementSibling:返回前一个兄弟元素节点(IE不兼容都是指IE9和IE9以下浏览器不兼容)节点的四个属性:nodeName:元素的标签名,以大写模式示意,只读nodeValue:Text节点或Comment节点的文本内容,可读写nodeType:该节点的类型,只读attribute:Element节点的属性汇合节点的一个办法:Node.hasChildNodes()(判断是否有子节点)Element节点的一些属性:innerHTML:增加HTML构造内容innerText/textContent:增加文本构造内容(innerText 火狐不兼容,textContent IE老版本不好使)Element节点的一些办法:ele.setAttribute(属性名,属性值):设置节点属性ele.getAttribute(属性名):获取节点属性
date(日期)对象
零碎提供的var date=new Date();具体性能办法可参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
定时器 , 延时器
设置定时器:定时器名=setInterval(function(){ .....},1000)革除定时器:clearInterval(定时器名)设置延时器:延时器名=setTimeout(function(){ .....},1000)革除延时器:clearInterval(延时器名)
获取窗口属性,dom尺寸
查看滚动条的滚动间隔:window.pageXOffset/pageYOffset(横向/纵向) (IE8/IE8以下不兼容)document.body/documentElement.scrollLeft/scrollTop (兼容性凌乱)(应用的时候可两者相交融(相加),适应兼容性)如:document.body.scrollLeft+document.documentElement.scrollLeft封装兼容性办法:getScrollOffset(){ if(0 && window.pageXOffset){ return{ x:window.pageXOffset, y:window.pageYOffset } } else{ return{ x:document.body.scrollLeft+document.documentElement.scrollLeft, y:document.body.scrollTop+document.documentElement.scrollTop } } } 查看视口的尺寸:window.innerWidth/innerHeight(查看窗口的宽高)(IE8/IE8以下不兼容)document.documentElement.clientWidth/clientHeight(规范模式下任何浏览器兼容)document.body.clientWidth/clientHeight(实用于怪异模式下的浏览器)判断是否为怪异模式:document.compatMode:CSS1Compat(失常模式),backCompat(怪异模式)封装兼容性办法:getViewportOffset(){ if(0 && window.innerWidth){ return { w:window.innerWidth, h:window.innerHeight } } else{ if(document.compatMode==='BackCompat'){ //怪异模式下 return { w:document.body.clientWidth, h:document.body.clientHeight } } else{ return { w:document.documentElement.clientWidth, h:document.documentElement.clientHeight, } } } }查看元素的几何尺寸:domEle.getBoundingClientRect() 返回一个对象,蕴含left,top,right,bottom,width,height等属性(但width,height在IE老版本中没有显示) 返回后果不实时 查看元素的尺寸:dom.offsetWidth,dom.offsetHeight查看元素的地位:dom.offsetLeft,dom.offsetTop dom.offsetParent(返回最近的有定位的父级,若无则返回body。body.offsetParent返回null) 封装函数:getElementPosition(求绝对于文档的坐标)使滚动条滚动的三个办法:scroll(x,y):滚动到... scrollTo(x,y):滚动到... scrollBy(x,y):滚动了...(会累加)
脚本化CSS
读写元素css属性:dom.style.prop可读写行间款式,没有兼容性问题,碰到float这样的保留字属性,后面应加css(即float --> cssFloat)复合属性尽量拆解组合单词变成小驼峰式写法查问计算款式:window.getComputedStyle(ele,null)[prop]计算款式只读返回的计算款式的值都是绝对值,没有绝对单位IE8及IE8以下不兼容 null用在获取伪元素时,扭转null(如:window.getComputedStyle(ele,'after').width)查问款式(IE8及IE8以下可用,IE独有):ele.currentStyle.prop计算款式只读返回的计算款式的值不是通过转换的绝对值封装兼容性办法:getStyle(ele,prop){ if(window.getComputedStyle){ return window.getComputedStyle(ele,null)[prop]; } else{ return ele.currentStyle.prop; } }
事件
绑定事处理函数: ele.onxxx=function(e){} 兼容性很好,然而一个元素的同一个工夫上只能绑定一个处理程序 this指向元素自身 obj.addEventListener(type,fn,false){} IE9以下不兼容,可为一个事件绑定多个处理程序 this指向元素自身 obj.attachEvent('on'+type,fn){} IE独有,一个事件同样能够绑定多个处理程序 this指向window 封装兼容性的函数办法:addEvent(ele,type,handle){ if(ele.addEventListener){ ele.addEventListener(type,handle,false); } else if(ele.attachEvent){ ele.attachEvent('on'+type,function(){ handle.call(ele); }) } else{ ele['on'+type]=handle; } } 解除事件处理函数:ele.onclick=false/null/''ele.removeEventListener(type,fn,false)ele.detachEvent('on'+type,fn) 事件处理模型:事件冒泡:构造上(非视觉上)嵌套关系的元素,会存在事件冒泡的性能,即同一事件,自子元素冒泡向父元素(自底向上)(focus,blur,change,submit,reset,selectd等事件不冒泡)勾销冒泡事件产生:e.stopPropagation()(不反对IE9以下的版本) e.cancelBubble=true(IE独有)事件捕捉:构造上(非视觉上)嵌套的关系的元素,会存在事件捕捉的性能,即同一事件,自父元素捕捉至子元素(事件源元素) (自顶向下) IE没有捕捉事件把addEventlistener中第三个参数改为true可触发事件捕捉触发程序:先捕捉后冒泡阻止默认事件(表单提交,a标签跳转,右键菜单等):return false:以对象属性的形式注册的事件才失效e.preventDefault() (IE9以下不兼容)e.returnValue=false (兼容IE9)事件对象:event(非IE浏览器都有) || window.event(用于IE浏览器)事件源对象:event.target (火狐只有这个)event.srcElement (IE只有这个)下面两种chrome都有事件委托:利用事件冒泡和事件源对象进行解决长处:性能不须要循环所有的元素一个个绑定事件 灵便,当有新的元素时不须要从新绑定事件 事件分类:鼠标事件:click,mousedown,mousemove,mouseup,contextmenu,mouseover,mouseout,mouseenter,mouseleaveevent中的button属性可辨别鼠标按键(左键为0,右键为2)键盘事件:keydown,keyup,keypress(keydown > keypress > keyup)keydown和keypress的区别:keydown可响应任意键盘按键 keypress只响应字符类键盘按键,可返回ASCII码并转换成相应字符 文本操作事件:input(实时获取文本的值),focus,blur,change(失焦后才获取文本的值)窗体操作类(window上的事件):scroll,load
JSON
一种传输数据的格局(以对象为样板,实质上是对象,但用处有区别,对象就是本地用的,json是用来传输的)JSON中,属性名必须带双引号JSON.parse():string -> jsonJSON.stringfy():json -> string
异步加载js
js加载的毛病:加载工具办法没必要阻塞文档,使得js加载会影响页面效率,一旦网速不好,那么整个网站将期待js加载而不进行后续渲染等工作js异步加载的三种计划:1. defer异步加载,等到dom文档全副解析完才会被执行。只有IE能用,也可将代码写到外部。2. async异步加载,加载完就执行,async只能加载内部脚本,不能把js写在script标签里3. 创立script,插入到DOM中,加载结束后callback(其中第一和第二个办法执行时也不阻塞页面)
js加载的工夫线
1. 创立Document对象,开始解析web页面。解析HTML元素和他们的文本内容后增加Element对象和Text节点到文档中。 (document.readyState='loading')2. 遇到link内部css,创立线程加载,并持续解析文档3. 遇到script内部js,并且没有设置async,defer,浏览器加载,并阻塞,期待js加载实现并执行该脚本,而后持续解析文档4. 遇到script内部js,并且设置有async,defer,浏览器创立线程加载,并持续解析文档。对于async属性的脚本,脚本加载实现后立刻执行。(异步禁止应用document.write())5. 遇到img等,先失常解析dom构造,而后浏览器异步加载src,并持续解析文档6. 当文档解析实现,document.readyState='interactive'7. 文档解析实现后,所有设置有defer的脚本会依照程序执行8. document对象触发DOMContentLoaded事件,标记着程序执行从同步脚本执行阶段,转化为事件驱动阶段9. 当所有async的脚本加载实现并执行后,img等加载实现后,document.readyState='complete',window对象触发load
正则表达式
转义字符:'\'/^结尾,结尾$/正则表达式作用:匹配特殊字符或有非凡搭配准则的字符的最佳抉择两种创立形式:间接量(举荐):var reg=/.../(前面可加i(疏忽大小写)/g(全局匹配)/m(多行匹配)) new RegExp():var reg=new RegExp('...','i/g/m') 正则表达式上的办法:reg.test(str)(检索字符串中指定的值。返回 true 或 false) reg.exec(str)(检索字符串中指定的值。返回找到的值,并确定其地位) ... 反对正则表达式的string对象的办法:str.match(reg)(在字符串内检索指定的值,或找到一个或多个正则表达式的匹配) str.search(reg)(检索与正则表达式相匹配的值。返回str中第一个与 reg相匹配的子串的起始地位,若没有找到任何匹配的子串,则返-1) str.replace(reg/str,replacement)(用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串) ...正则表达式中一些元字符对应的表达式:\w===[0-9A-z_],\W===[^\w] \d===[0-9],\D===[^\d] \s===[\t\n\r\v\f],\S===[^\s] \b===单词边界,\B===非单词边界 .===[^\r\n] 正则表达式的一些量词:n+(呈现一次到屡次) n*(呈现0次到屡次) n?(呈现0到1次) n{x}(呈现x次) n{x,y}(呈现x到y次) 以上量词遵循贪心匹配准则(尽可能匹配多的) 正向预查(从左到右进行匹配):?=xxx(匹配前面跟着xxx的货色) ?!xxx(匹配前面不跟着xxx的货色)负向预查(从右到左进行匹配):?<=xxx(匹配紧跟xxx前面的货色) ?<!xxx(不匹配紧跟xxx前面的货色) e.g.1 测验一个字符串首尾是否含有数字 var reg=/^\d|\d$/g; var str='123abc'; reg.test(str) -> true e.g.2 测验一个字符串首尾是否都含有数字 var reg=/^\d[\s\S]*\d$/g; var str='123abc123'; reg.test(str) -> true e.g.3 输入以下replace后的后果 var str='aa'; //var reg=/a/; console.log(str.replace('a'/reg,'b')) 后果为ba(个别状况下只匹配到一个) var reg=/a/g; console.log(str.replace(reg,'b')) 后果为bb(全局匹配可匹配多个) e.g.4 把aabb转成bbaa var reg=/(\w)\1(\w)\2/g; var str='aabb'; console.log(str.replace(reg,'$2$2$1$1')); 或:console.log(str.replace(reg,function($,$1,$2){ return $2+$2+$1+$1 })); e.g.5 把一串数字用迷信计数法示意(从右往左,每三个数打一个点) var str='10000000000'; var reg=/(?=(\B)(\d{3})+$)/g; str.replace(str,'.'); 详情可参考网址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp 或https://www.w3school.com.cn/jsref/jsref_obj_regexp.asp
一些杂碎
一旦经验了var的操作,所得出的window上的属性,这种属性叫做不可配置的属性,delete不掉undefined和null不与数字比拟typeof(arguments):objectdocument.documentElement等于html在正则表达式中,加上?可突破贪心匹配