(188js-007真人)大厅怎么js 登录验证??????????????????!!!!!!

改善js程序的188个建议笔记
1.正确处理js特殊值HTML 代码NaN是一个特殊的数量值,它不表示一个数组
typeof NaN === 'number' //true
NaN === NaN //false
isNaN(NaN) //true使用isNaN方法判断是否为可用数字
Infinity表示无穷大,-Infinity表示负无穷大
//inFinite函数能够检测NaN,正负无穷大如果为有限数值或者可转为有限数值返回true,如果是NaN,正负无穷大则返回false
//但是inFinite会试图把云算数转为数字
//可以自定义方法判断
var isNumber = function isNumber(value){
return typeof value ==='number' && isFinite(value);
}2.正确使用null和undefinedHTML 代码JavaScript有5种基本类型:String,Number,Boolean,Null和Undefined
Null和Undefined分别只有null和undefined两个值
null与对象引用有关,表示为空或者不存在的对象引用;
undefined:声明一个变量却没有给之赋值的时候,它的值就是undefined
typeof null //object
typeof undefined //undefined
null ==undefined
null !== undefined
//对于早期浏览器不支持undefined兼容
var undefined =
var undefined = void 1;
var undefined = function(){}();
//js中的假值
0,NaN,''false,null,undefined3.谨慎使用运算符HTML 代码===运算符:
1.先比较两个值的类型是否相同,如果不同,直接返回false
2.如果两个值的类型相同,在进步一比较
//逗号运算符
a = 1,2,3,4; // a=1
a = (1,2,3,4);// a=4
(a=1,2,3,4); // a=4
var a = 1,2,3,4 // a=null
var a = (1,2,3,4) // a=44.字符串是非值操作HTML 代码var a = &js&;
//字符串的复制和传递操作是为字符串建立了独立的副本,即新开辟一个区域进行存储,并把新空间的地址传递给栈区的变量进行存储
b = b.toUpperCase();
console.log(a); //js
console.log(b); //JS
1.字符串的复制,传递仅是对字符串串的引用进行操作,而不是对字符串的本身的值进行操作
2.修改字符串的值,需要使用值的方法进行操作,而不用修改对字符串的引用
3.修改字符串的值,不是在堆区原值本身上进行修改,而是通过服务进行修改
4.修改的字符串副本与原值没有任何联系,如果不把修改值复制给原值变量,则不会对原值产生影响
5.当把修改的字符串复制给原值变量时,会重新建立一个新的引用,并把修改值存储到堆区新的位置
6.原值引用的区域,如果还被其他变量引用,则继续保留,否则会被js回收程序回收
5.获取字节长度string.length属性和Array的length不同,string的length为只读属性,Array则不同HTML 代码String对象的length属性能够返回字符串的长度,不管字符是单字节还是双字节,都作为一个来计算
判断当前字符是单字节还是双字节:
1)通过charCodeAt来判断:
var a = &s&;
var b = &你&;
a.charCodeAt(0) // 115
b.charCodeAt(0) //20320
if(str.charCodeAt(i)&255){
}//循环,大于255的为双字节
2)使用escape:
if(escape(c).length & 4){
}else{b++;}
escape(a) //
escape(b)// %u4F60
3)使用正则:
for(var i=0;i&1;i++){
var c = this.cahrAt(i);
if(/^[u0000-u00ff]$/.test(c)){
}6.正确检测数组类型HTML 代码一:
var is_array = function (value){
return value && typeof value=== 'object' && value.constructor === Array && typeof value.length ==='number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
var is_array = function(value){
Object.prototype.toString.apply(value)==='[object Array]';
}7.理解数组长度的有限性和无限性HTML 代码js数组的length是没有上限的,如果用大于或等于当前Length的数字作为下标来保存一个元素,那么Length将增大以容纳新元素,不会发生数组边界错误
var myArray =[];
myArray.length //0
myArray[1000] =
myArray.length //1001
8.建议使用splice删除数组HTML 代码//splice方法第一个参数是数组中的一个序号,第二个参数是要删除的元素个数,任何额外的参数会在序号那个店的位置被插入数组中
var number =['zero','one','two','three','four','five'];
number.splice(2,1);//返回[&two&];原数组变为[&zero&, &one&, &three&, &four&, &five&];注意,方法会影响原来数组9.增强数组排序的sort功能HTML 代码//可以为sort方法提供比较函数
fuction f(a,b){
return (a-b);//或者其他处理逻辑TODO
var a =[3,1,2,4]
a.sort(f);//从小到大,-(a-b)从大到小10.不要拘泥于数字下标HTML 代码//js使用哈希表作为数据存储格式,因此对于下面的操作:
var a = [['张三',1],['李四',2]]
a[0][0];//用下标获取
//使用文本下标会更快
var a = [];
a[&张三&] =1;
a[&李四&] =2;
a[&李四&];//快速定位检索
//二维数组下标,如
var a = [];
a[0,0] =1;
a[0,1] =2;
a[1,0] =3;//js会将之当做逗号表达式,返回最后一个值,所以等于a[0]=1,a[1]=2,a[0]=3
//对象下标
//对象也可以作为数组下标,js会试图把对象转换为数值,如果不行则把它装换为字符串,然后以微博下标的形式进行操作
var a =[];
var b = function(){return 2;}
var a[b] = 1;
var s = b.toString();
a[s] ;//利用文本下标读取元素值
a[b()] = 1;//即a[2] = 1;11.使用arguments模拟重载HTML 代码function sayHello(){
switch(arguments.length){
case 0:return &hello&;
case 1:return &hello&+arguments[0];
}12.禁用Function构造函数HTML 代码//定于function的方法
//1.使用function语句
function f(x){return x};
//2.使用Functioin()构造函数
var f = new Function(&x&,&&);
//3使用函数直接量直接生成函数
var f = function(x){}
1)作用域比较:使用Function构造函数创建的函数具有顶级作用域,js解释器也总是把它作为顶级函数来编译,而function语句和函数直接量定义的函数都有自己的作用域(即局部作用域,或称为函数作用域)
//2)解析效率:js解释器在解析代码时,并非一行行地分析和执行程序,而是一段段的。使用function语句和函数直接量定义的函数结构总会被提取出来优先执行。只有在函数被解析和执行完毕之后,才会按顺序执行其他代码。但是使用Function构造函数定义的函数并非提前运行,而是在运行时动态地被执行,这也是Function构造函数定义的函数具有顶级作用域的根本原因
//3)兼容性:使用function语句定义函数不用考虑版本;而Function构造函数只能在js1.1及其以上版本使用,函数直接量仅在js1.2及其以上版本使用
13.比较函数调用模式HTML 代码//js中一共有4中调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式。这些模式在如何初始化关键参数this上存在差异
(1)方法调用模式
当一个函数被保存为一个属性时,将称为一个方法。调一个方法被调用时,this被绑定到该对象
var obj = {
increment:function(inc){
this.value +=typeof inc ==='number'?inc:1;
obj.increment();//1
obj.increment(2);//3
(2)函数调用模式
当一个函数并非一个对象的属性时,它将被当做一个函数来调用:
var sum = add(3,4);
//当函数以此模式调用时,this被绑定到全局对象。
//解决方案:定义一个变量存储this
var obj = {
doub:function(){
var that =
var helper = function(){
that.value = that.value*2;
obj.doub();
(3)构造器调用模式
js为了能够兼容基于类语言的编程风格,提供了一套类似语言的对象构建语法:如果在一个函数前面加上new运算符来进行调研,那么将创建一个隐藏链接到该函数的prototype原型对象的新实例对象,同时this将会绑定到这个新实例对象上。注意,new前缀也会改变return语句的行为
var F = function(string){this.status =}
F.prototype.get = function(){
return this.
var f = new F(&new object&);
f.get();//&new object&
(4)apply调用模式
使用这个方法可以调用函数,并修改函数体内的this值,包含两个参数,第一个参数设置绑定给this的值,第二个参数是包含函数参数的数组:
var array = [5,4];
var add = function(){
var i,sum=0;
for(i=0,i&arguments.i+=1)
sum +=arguments[i];
var sum = add.apply({},array);//9
var F = function(string){this.status=};
F.prototype.get = function(){
return this.
var obj = {status:'obj'}
var status = F.prototype.get.apply(obj);//obj14.使用闭包跨域开发HTML 代码function f(x){
var b = function(){
var c = f(1);
//闭包函数与普通函数没有什么不同,主要包含以下类型的标识符
1.函数参数(形参变量)
2.arguments属性
3.局部变量
4.内部函数名
5.this(指代闭包函数自身)
//其中this和arguments是系统默认的函数标识符,不需要特别声明。这些标识符在闭包体内的优先级是(其中做出优先级大于右侧):this -& 局部变量 -& 形参 -& arguments -& 函数名
function f(x){//外部函数
var a =//外部函数的局部变量,并把参数值传递给它
var b = function(){//内部函数
//访问外部函数中的局部变量
a++;//访问后,动态更新外部函数的变量
//内部函数
var c =f(5);//
c();// 615.建议通过Function扩展类型HTML 代码//通过给Function.prototype增加方法,使该方法对所有函数可用
Function.prototype.method = function(name,func){
if(!this.progotype[name]){
this.prototype[name] =
16.套用函数HTML 代码//将函数与传递给它的参数相结合产生一个新的函数
var add = function(n){
return function(m){
return n+m;
add(2)(3);//517.使用模块化规避缺陷HTML 代码//使用函数和闭包可以构建模块,即一个提供接口却隐藏状态与实现的函数或对象。通过这种模块,可以完全摒弃全局变量的使用
//全局变量存在很多潜在危害;同时,如果把变量定义在函数本身中,会带来运行时消耗,因为在该函数每次被执行时,这个方法都会被请求一次,理想的方式是将变量放入一个闭包,并扩展方法
var serial_maker = function(){
var prefix = '';
var seq = 0;
set_prefix:function(p){
prefix = String(p);
set_seq:function(s){
gensym :function(){
var result = prefix +
var seqer = serial_maker();
seqer.set_prefix('Q');
seqer.set_seq(1000);
var unique = seqer.gensym();//Q1000
var unique = sequer.gensym();//Q1001
//seqer包含的方法都没有用到this或that,因此没有办法损害seqer,除非调用对应的方法,否则无法改变prefix或seq的值。seqer就是一组函数的集合,而这些函数被授予特权,拥有使用或修改私有状态的能力18.惰性实例化HTML 代码//惰性实例化要解决的问题是:避免了在页面中js初始化的时候就实例化类,如果在页面中没有使用这个实例化的对象,就会造成一定的内存浪费和性能消耗
var myNamespace = function(){
var Configure = function(){
var privateName = &someone's name&;
var privateReturnName = function(){
return privateN
var privateSetName = function(name){
privateName =
setName:function(name){
privateSetName(name);
getName:function(){
return privvateReturnName();
getInstance:function(){
if(!instance)
{instance=Configure();}
myNamespace.getInstance().getName();19.推荐分支函数HTML 代码//解决浏览器直接兼容性的重复判断
var XHR = function(){
var standard = {
createXHR:function(){
return new XMLHttpRequest();
var newActionXObject ={
createXHR:function(){
return new ActionXObject(&Msxml2.XMLHTTP&);
var oldActionXObject={
createXHR:function(){
return new ActionXObject(&Microsoft.XMLHTTP&);
if(standard.createXHT()){
newActionXObject.createXHR();
return newActionXO
}catch(o){
oldActionXObject.createXHR();
return oldActionXO
//声明几个不同名称的对象,但为这些对象声明一个名词相同的方法。,这样不论返回哪一个对象,最后名词相同的方法都作为对外一致的接口20.惰性载入函数HTML 代码var addEvent = function(el,type,handle){
addEvent = el.addEventListener?function(e1,type,handle){el.addEventListener(type,handle,false);} : function(el,type,handle){
el.attachEvent(&on&+type,handle);
//第一次执行addEvent函数时,修改了addEvent函数之后,必须执行一次;
addEvent(el,type,handle);
21.函数绑定有价值HTML 代码//函数绑定就是为了纠正函数的执行上下文,特别是函数中带有this关键字的时候,函数绑定具有3个特征
1)函数绑定要创建一个函数,可以在特定环境中以指定参数调用另一个函数
2)一个简单的bind()函数接收一个函数和一个环境,返回一个在给定环境中调用给定函数的函数,并且将所有参数原封不动地传递过去
3)被绑定函数与普通函数相比有更多的开心,它们需要更多内存,同时也因为多重函数调用而稍微慢一点,最好只在必要时使用
var handler ={
message:'Event handled',
handleClick:function(){
alert(this.message);
var btn = document.getElementById('my-btn');
EventUtil.addHandler(btn,'click',handler.handleClick);//undefined
//出现上述结果的原因在于没有保存handler.handleClick()的上下文环境,所以this对象最后指向了DOM而非handler
可以使用闭包修正此问题:
EventUtil.addHandler(btn,'click',function(event){handler.handleClick(event);});//这边有感觉有点困惑,记录下以待细看
//bind()函数
function bind(fn,context){
return function(){
return fn.apply(context,arguments);
EventUtil.addHandleer(btn,&click&,bind(handler.handlerClick,handler));22.使用高阶函数HTML 代码//高阶函数只是满足下列条件之一:1.接受函数作为输入 2.输出一个函数
function map(array,func){
var res = [];
for(var i=0,len=array.i&i++){
res.push(func(array[i]))
var mapped = map([1,3,5,7,8],function(n){
return n = n+1;
print(mapped);//2,4,6,8,9
var mapped2 = map([&one&,&two&,&three&,&four&],function(item){
return &(&+item+&)&;
print(mapped2);//(one),(two)...
23.函数柯里化HTML 代码//柯里化是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回一个新函数,这个新函数能够接受原函数的参数
function adder(num){
return function(x){
return num+x;
var add5 = adder(5);
var add6 = adder(6);
print(add5(1));//6
print(add6(1));//7
//通俗点说就是利用已有的函数,再创建一个动态的函数,该动态函数内部还是通过已有的函数来发生作用,只是传入更多的参数来简化函数的参数方面的调用
function curry(fn){
var args = [].slice.call(arguments,1);
return function(){
return fn.apply(null,args.concat([].slice.call(arguments,0)));
function add(num1,num2){
return num1+num2;
var newAdd = curry(add,5);
console.log(newAdd(6));/1124.推荐作用域安全的构造函数HTML 代码//构造函数其实是一个使用new运算符的函数。当使用new调用时,构造函数的内部用到的this会指向新创建的实例
function Person(pname){
this.pname =
var person = new Person(&Tom&);
//在没有使用new运算符来调用构造函数的情况下,由于该this对象是在运行时绑定的,因此直接调用Person()会将该对象绑定到全局对象window上,这将导致错误属性意外增加到全局作用域上,这是由于this晚绑定造成的,在这里this被解析成了window对象
//解决方案:创建一个作用域安全的构造函数:
function Person(pname){
if(this instanceof Person){
this.pname =
return new Person(pname);
}25.正确理解执行上下文和作用域链HTML 代码//所有的js代码都是在某个执行上下文中运行的。在当前执行上下文中调用function会进一个新的执行上下文。该function调用结束后会返回到原来的执行上下文中。如果function在调用过程中抛出异常,并且没有将其捕获,有可能从多个执行上下文中退出。在function调用过程中,也可能调用其他的function,从而进入新的上下文,由此形成一个执行上下文栈。
//每个执行上下文斗鱼一个作用域链关联,该作用域链用来在function执行时求出标识符(identifier)的值。该链中包含多个对象,在对标识符进行求值过程中,会从链首的对象开始,然后依次查找后面的对象,直到在某个对象中找到与标识符名称相同的属性,在每个对象中进行属性查找时,会使用该对象的prototype链,在一个执行上下文中,与其关联的作用域链只会被with语句和catch子句影响
//在进入一个新的执行上下文时,会按顺序执行下面的操作
(1)创建激活(activation)对象
激活对象是在进入新的执行上下文时创建处来的,并且与新的执行上下文关联起来。在初始化构造函数时,该对象包含一个名为arguments的属性。激活对象在变量初始化时也会被用到,js代码不能直接访问该对象,但可以访问该对象的成员(如arguments)。
(2)创建作用域链
接下来的操作是创建作用域链,每个function都有一个内部属性[[scope]],它的值是一个包含多个对象的链。该属性的具体值与function的创建方式和代码中的位置有很大关系。此时的主要操作是将上一步创建的激活对象添加到function的[[scope]]属性对应的链的前面
(3)变量初始化
这一步对function中需要时候的变量进行初始化。初始化时使用的对象是创建激活对象过程中所创建的激活对象,不过此时称作变量对象。会被初始化的变量包括function调用时的实际参数、内部function和局部变量。在这一步中,对于局部变量,知识在变量对象中创建了同名的属性,其属性值为undefined,只有在functon执行过程中才会被真正赋值。全局js代码是在全局执行上下文中运行的,该上下文的作用域链只包含一个全局对象。
//函数总是在自己的上下文环境中运行,如读/写局部变量、函数参数,以及运行内部逻辑结构等。在创建上下文环境的过程中,js会遵循一定的运行规则,并按照代码顺序完成一系列操作:
1)根据调用时传递的参数创建调用对象
2)创建参数对象,并存储参数变量
3)创建对象属性,存储函数定义的局部变量
4)把调用对象放在作用域链的头部,以便检索
5)执行函数结构体内语句
6)返回函数返回值26.参照Object构造体系分析prototype机制HTML 代码//Object与Function都是高度抽象的类型,互为对方实例:
Object instanceof F//true
Function instanceof O//true
//Object与Function同时也是两个不同类型的构造器:
var f = new Function();
var o = new Object();
f instanceof F//true
o instanceof O//true
o instanceof F//false
o instanceof O//true
//Object 和Function都可以定义原型,Object被视为Function的子类。
Object.prototype.a = 1;
Function.prototype.a = 2;
Object.a;//2
Function.a;//2
var o = {};
var f1 = new Function();
var o1 = new Object();
o1.a;//127.分辨this和function调用关系HTML 代码//this的值取决于function被调用的方式,一共有5种
1.如果一个function是一个对象的属性,那么在function被调用时,this的值是这个对象
2.如果function调用的表达式包含句点(.)或[],那么this的值是句点或[]之前的对象。如造myObj.func和myObj[“func”]中,func被调用时的this是myObj
3.如果一个function不是作为一个对象的属性,那么在function被调用时,this的值是全局对象。
var myObj = {
myVal:&Hello World&,
func:function(){
alert(typeof this.myVal);//string
var self =
function inner(){
alert(typeof this.myVal);//undefined
alert(typeof self.myVal);//string
myObj.func();//inner被调用时,this指的是全局对象,这里通过保存在self中调用
4.如果在一个function之前使用new,则会创建一个新的对象,该function也会被调用,而this的值是新创建的那个对象
function User(name){
this.name =
var user1 = new User(&test&);
5.如果通过function的apply和call方法来指定它被调用时的this,那么apply和call的第一个参数都是要指定的this,不同之处在于apply后面传参数数组,而call中除了第一个外其他都是调用的实际参数
//所有的构造器都是对象,但并不是所有的对象都能成为构造器。能作为构造器的对象必须实现隐含的Construct方法。new操作符会影响function调用者的return语句行为。当调用function时有new作为前缀,如果返回的结果不是一个对象,那么新创建的对象将会被返回
function user(name){this.name =name}
function anotherUser(name){
this.name =
return{&badName&:name};
var u1 = new User(&Alex&);
typeof u1.//string
var u2 = new anoterhUser(&Alex&);
typeof u2.//undefined
typeof u2.badN//string
//函数anoterUser通过return语句返回了一个对象,因此u2引用的是返回的那个对象,而user没有使用return语句,因此u1引用的是新创建的user对象28.this是动态指针,不是静态引用HTML 代码//this所指向的对象时由this所在的执行域决定的,而不是由this所在的定义域决定,this是js执行作用域的一个属性,它的指针始终指向当前调用对象。只有当this被最后执行时才能准确缺点它所指代的对象。
var name = &this = window&;
name:&this = o&,
f:function(){
var o1 = {
name:&this = o1&,
var a = o1.f();
a.//&this = o1&,通过o1调用方法f
//尝试吧o的方法f()封装在闭包中:
name:&this = o1&,
f:function(){
return o.f;
var a = o1.f()();
a.//&this = window&;其实就是,o1.f()返回了一个o.f,o.f是什么呢?是一个function,也就是说,我们实际执行的是这个return的function,那么是谁执行的这个被return的function呢?可以看到在分别this和function调用关系中讲到,如果一个function不是作为一个对象的属性,那么function背调用时,this的值是个全局对象!。。。没错
//几个栗子
(1)指向当前DOM对象:
&input type=&button& value=&who am I& onclick=&this.value='it's me'&/&
(2)指向构造函数的实例对象
function F(){
this.name = &It's me&;
var f = new F();
f.//这里this就指向了new出来的这个实例对象f
(3)指向当前对象的直接量
name:&I'm an object&,
me:function(){
var who = o.me();
who.//谁.的me方法?没错,是o,那this就指向o
(4)指向全局对象
function f(){
this.name = &who am I&;
f();//等价于window.f()
//&who am I& this指向window
(5)this指向当前作用域对象
&input type=&button& value=&who am I& onclick =&f()&/&
function f(){this.value=&test&;}
29.建议使用封装类继承HTML 代码function extend(Sub,Sup){
var F = function(){};
F.prototype = Sup.
Sub.prototype = new F();
Sub.prototype.constructor = S
Sub.sup = Sup.
if(Sup.prototype.constructor == Object.prototype.constructor){
Sup.prototype.constructor = S
}30.慎重使用实例继承HTML 代码//对类进行实例化操作就会产生一个新的对象,这个实例对象将继承类的所有特性和成员,而实例继承正是对于这种实例化过程的一种概括。类继承和原型继承在客户端是无法继承DOM对象的,同时它们也不支持继承系统静态对象、静态方法等。
(1)使用类继承法继承Date对象
function D(){
Date.apply(this,arguments);
var d = new D();
d.toLocaleString();//[object Object] 说明使用类继承无法实现对静态对象的继承
(2)使用原型继承无法继承Date对象
function D(){}
D.prototype = new Date();
var d = new D();
d.toLocaleString();//错误
//上面的示例说明了使用原型继承也无法实现对今天对象的继承。
//不过,使用实例继承法能够实现对所有js核心对象的继承:
function D(){
var d = new Date();
d.get = function(){console.log(d.toLocaleString());}
var d = new D();
d.get();31.避免使用复制继承HTML 代码//复制继承
function F(x,y){
this.add = function(){return this.x+this.y;}
F.prototype.mul = function(){
return this.x * this.y;
var f= new F(2,3);
var o ={};
for(var i in f){
o[i] = f[i];
o.add();//5
o.mul();//6
//可以将其封装,扩展Function
Function.prototype.extend = function(o){
for(var i in o){
this.constructor.prototype[i] = o[i];
var o = function(){};
o.extend(new F(2,3));
1)由于是反射机制,复制继承法不能继承非枚举类型的方法,系统核心对象的只读方法和属性也是无法继承的。
2)通过反射机制来复制对象成员的执行效率会非常差,对象结构越庞大,这种低效就表现得越明显
3)如果当前类型包含同名成员,那么这些成员肯呢个会被父类的动态复制所覆盖
4)在多重继承的情况下,复制继承不能够清晰地描述父类与子类的相关性
5)只有在类被实例化后,才能实现遍历成员和复制成员,因此它不能够灵活支持动态参数
6)由于复制继承法仅是简单地引用赋值,如果父类成员包含引用类型,那么用复制继承法继承后,与原型继承法一样副作用很多
Function.prototype.clone = function(o){
function Temp(){};
Temp.prototype =
return new Temp();
var o = Function.clone(new F(2,3));
o.add();//5
o.mul();//6
32.推荐使用混合继承各类继承比较HTML 代码function A(x,y){
A.prototype.add = function(){
return this.x + this.y;
function B(x,y){
A.call(this,x,y);//类继承实现
B.prototype = new A();//原型继承实现
var b = new B(10,20);
b.add();//3033.使用享元类HTML 代码//享元类就是类的类型,即创建类型的类:
function O(x){
return function(){
this.get = function(){
console.log(this.x);
var o = new O(1);
var f = new o();
f.get();//134.使用掺元类HTML 代码//掺元类就是共享通用的方法和属性,将差异比较大的类中相同功能的方法集中到一个类中声明
var F =function(x,y){//掺元类F
F.prototype = {
getx:function(){return this.x;},
gety:function(){return this.y;}
A = function(x,y){
F.call(this,x,y);
B = function(x,y){
F.call(this,x,y);
}35.建议先检测浏览器对DOM支持程度HTML 代码//可以调用DOMImplementation对象的hasFeature()方法检测
var dom = &HTML&;//指定DOM模块
var ver = &1.0&;//指定dom级别
if(document.implementation){
if(document.implementation.hasFeature(dom,ver)){console.log(&support&);}else{
console.log(&Not support&)
console.log(&Don't support DOMImplementation&);
36.应理清HTML DOM加载流程HTML 代码1.解析HTML结构
2.加载外部脚本和样式表文件
3.解析并执行脚本代码
4.构造HTML DOM模型
5.加载图片等外部文件
6.页面加载完毕
//一种间接的方法来实现稳定结构有序显示:
function f(){
if(document && document.getElementByTagName && document.getElementById && document.body){
clearInterval(timer);
var timer = setInterval(f,10);
//在f()中,首先判断document对象的几个重要方法是否已经加载完毕,如果加载完毕,则说明dom结构已经加载完成,执行预定的js脚本 37.使用nextSibling抓取DOMHTML 代码//操作一个DOM周围的元素:(使用childNodes和nextSibling)
function testNextSibling(){
var e1 = document.getElementById('mydiv'),ch = e1.firstChild,name='';
name = ch.nodeN
}while(ch = ch.nextSibling);
function testChildNodes(){
var e1 = document.getElementById('mydiv'),ch = e1.childNodes,len = ch.length,name='';
for(var count =0;count&count++){
name = ch[count].nodeN
//在旧版本IE中,使用nextSibling抓取dom是首选,在其他情况下,主要依靠个人和团队的使用习惯而定38.实现DOM原型继承机制HTML 代码//符合DOM标准的浏览器都支持HTMLElement类,DOM文档中所有元素都继承于这个类,而HTMLElement对象又继承于Element类(Element类继承于Node类),这样通过在HTMLElement类的原型对象上定义方法,为html dom文档中所有元素绑定函数和数据:
HTMLElement.prototype.pre = function(){
var e = this.previousS
while(e && e.nodeType !=1){
e = e.previousS
//注意,在函数体内,应该通过关键字this来指向当前元素对象,而不用从参数变量中获取当前元素,使用:
window.onload = function(){
var e = document.getElementsByTagName(&div&)[0];
e = e.pre();
console.log(e.nodeName);
//但ie隐藏了这个类,禁止通过js脚本来访问它,为了兼容ie:
var DOMElement ={
extend:function(name,fn){
//添加名称为name的方法fn
if(!document.all)
//IE之外的浏览器都能访问到HTMLElement这个类
eval(&HTMLElement.prototype.&+name+& = fn&);
//重写createElement,getElementById,getElementsByTagName等方法
var _createElement = document.createE
document.createElement = function(tag){
var _elem = _createElemnt(tag);
eval(&_elem.&+name+&=fn&);
var _getElementById = document.getElementById;
document.getElementById = function(id){
var _elem = _getElementById(id);
eval(&_elem.&+name+&=fn&);
var _getElementsByTagName = document.getElementsByTagN
document.getElementsByTagName = function(tag){
var _arr = _getElementsByTagName(tag);
for(var _elem=0;_elem&_arr._elem++)
eval(&_arr[_elem].&+name+&=fn&);
}39.推荐使用css选择器HTML 代码
var elements = document.querySelectorAll('#menu a');
//elements的值将包含一个引用列表,指向哪些具有Id=&menu&属性的元素。函数querySelectorAll()接收一个css选择器字符串参数并返回一个NodeList,此函数不返回HTML集合,这就避免了HTML集合所有固有的性能问题以及潜在的逻辑问题
//如果不是要querySelectorAll(),达到同样的目标的代码会冗长一些
var elements = document.getElementById('menu').getElementsByTagName_r('a');
//在这种情况下,elements僵尸一个HTML集合40.减少DOM重绘和重排次数HTML 代码//浏览器在完成所有页面HTML标记,JS,CSS,图片下载后,将解析文件并创建两个内部数据结构:
1.一颗DOM树:表示页面结构
2.一颗渲染树:表示DOM节点如何显示(在渲染树中为每个需要显示的DOM树节点存放至少一个节点,隐藏的DOM元素在渲染树中没有对应节点,将渲染树上的节点称为框或者盒,符合css模型的定义,将页面元素看做一个具有填充、边距、边框和位置的盒,一旦dom树和渲染树构造完毕,浏览器就可以绘制页面上的元素了)
//根据改变的性质,渲染树上或大或小的一部分需要重新计算,以下情况会发生重排版
1.添加或删除课件的DOM元素
2.元素位置改变
3.元素尺寸改变(因为边距、填充、边框宽度、宽度、高度等熟悉改变)
4.内容改变,如文本改变或图片呗另一个不同尺寸的图片所替代
5.最初的页面渲染
6.浏览器窗口改变尺寸
//因为计算量与每次重排版有关,因此大多数浏览器都通过队列化修改和批量显示来优化重排版过程。使用了一下方法也会强迫队列进行刷新并要求立刻应用所有计划改变的步伐,获取布局信息的操作将导致刷新队列动作:
1.offsetTop、offsetLeft、offsetWidth、offsetHeight
2.scrollTop、scrollLeft、scrollWidth、scrollHeight
3.clientTop、clientLeft、clientWidth、clientHeight
4.getComputedStyle()(ie中为currentStyle)
//布局信息是由这些方法返回最新的数据,浏览器不得不运行渲染队列中待改变的项目并重新排版以返回正确的值。
var e1 = document.getElementById('mydiv');
e1.style.borderLeft ='1px';
e1.style.borderRight='2px';
e1.style.cssText='border-left:1border-right:2';
//一些建议
1.当需要对DOM元素进行多次修改时,可以通过以下步骤减少重绘和重排版的次数
1.从文档流中摘除该元素
2.对其应用多重改变
3.将元素带回文档中
//更多方法
1.隐藏元素,进行修改,然后再显示它
2.使用一个文档判断再已存DOM之外创建一个子树,,然后将它复制到文档中(document.createDocumentFragment)
3.将原始元素复制到一个脱离文档的节点中,修改副本,然后覆盖元素元素
41.使用DOM树结构托管事件HTML 代码document.getElementById('menu').onclick = function(e){
e = e|| window.
var target = e.target || e.srcE
var pageid,
if(target.nodeName !=='A'){
if(typeof e.preventDefault ==='function'){
e.preventDefault();
e.stopPropagation();
e.returnValue =
e.cancelBubble =
}42.推荐网页工人线程HTML 代码//它引入一个接口,使代码运行而不占用浏览器UI线程时间,由于网页工人线程不绑定浏览器UI线程,也就意味着它们将不能访问许多浏览器资源
var worker = new Worker(&code.js&);
//为指定文件创建一个新线程和一个新的工人线程运行环境。此js文件被异步下载,知道下载并运行完此文件之后才启动工人线程。
//工人线程和网页代码通过事件接口进行交换,网页代码可以通过postMessage()方法向工人线程传递数据,此外,在工人线程中海油onmessage事件句柄用户接收信息:
var worker = new Worker(&code.js&);
worker.onmessage = function(event){
alert(event.data);
worker.postMessage(&Nicholas&);
//网页工人线程从message事件中接收数据。这里定义了onmessage事件句柄,事件对象具有一个data属性用于存放传入的数据。网页工人线程可以通过它自己的postMessage()方法将信息返回给页面:
self.onmessage = function(event){
self.postMessage(&Hello,&+event.data+&!&);
//工人线程以阻塞方式调用importScripts(),直到所有文件加载完成并执行之后,脚本才继续运行
importScripts(&file1.js&,&file2.js&);
self.onmessage=function(event){
self.postMessage(&Hello&+event.data);
e.g:解析一个很大的json字符串,可能耗时过长,则可以通过工人线程:
var worker = new Worker(&jsonparser.js&);
worker.onmessage = function(event){
var jsonData = event.
evaluateData(jsonData);
worker.postMessage(jsonText);
//工人线程代码负责json解析:
self.onmessage = function(event){
var jsonText = event.
var jsonData = JSON.parse(jsonText);
self.postMessage(jsonData);
//页面使用postMessage()将一个JSON字符串传给工人线程,工人线程在它的onmessage事件句柄中收到这个字符串,也就是event.data,然后开始解析它。完成解析时所产生的JSON对象通过工人线程的postMessage()方法传回页面,伺候此对象便成为页面onmessage事件句柄的event.data
43.设计鼠标拖放方案HTML 代码//初始化拖放对象
var box = document.getElementById(&box&);
box.style.position = &absolute&;
box.style.width = &160px&;
box.style.height =&120&
box.style.backgroundColor=“red”;
//初始化变量,标准化事件对象
var mx,my,ox,
function e(event){
if(!event){
event = window.
event.target = event.srcE
event.layerX = event.offsetX;
event.layerY = event.offsetY;
event.mx = event.pageX || event.clientX+document.body.scrollL//计算鼠标指针的x轴距离
event.my = event.pageY || event.clientY+document.body.scrollT
//定义鼠标事件处理函数
document.onmousedown = function(event){
event = e(event);
o = event.
ox = parseInt(o.offsetLeft);
oy = parseInt(o.offsetTop);
mx = event.
my = event.
document.onmousemove =
document.onmouseup =
function move(event){
event = e(event);
o.style.left = ox+ event.mx-mx+&px&;
o.style.top = oy+event.my-my+&px&;
function stop(event){
event = e(event);
ox = parseInt(o.offsetLeft);
oy = parseInt(o.offsetTop);
mx = event.
my = event.
o = document.onmousemove = document.onmouseup =
}44.设计鼠标指针定位方案HTML 代码//由于clientX和clientY属性是以window对象为坐标系,并且ie支持它们,因此可以选用它们,不过考虑window对象可能出现滚动条偏移量,还应加上相对于window对象的页面滚动的偏移量。
//定义一个封装函数:
var pos = function(o,x,y,event){
var posX =0,posY = 0;
var e = event || window.
if(e.pageX || e.pageY){
posX = e.pageX;
posY = e.pageY;
else if(e.clientX || e.clientY){
posX = e.clientX+document.documentElement.scrollLeft+document.body.scrollL
posY = e.clientY + document.documentElement.scrollTop+document.body.scrollT
o.style.position = &absolute&;
o.style.top = (posY+y)+&px&;
o.style.left =(posX+x)+&px&;
//调用,鼠标跟随效果
var div1 = document.getElementById(&div1&);
document.onmousemove = function(event){
pos(div1,10,20,event);
}45.妥善使用DOMContentLoaded事件HTML 代码//在DOM文档结构加载完毕的时候被触发,要比load事件先被处罚。IE和Safari浏览器还不支持:
window.onload = f1;
if(document.addEventListener){
document.addEventListener(&DOMContentLoaded&,f,false);
function f(){
alert(&提前执行&);
function f1(){
alert(&页面初始化完毕&);
//由于ie不支持DOMContentLoaded事件,兼容:
if(window.ActiveXObject){
document.write(&&script id=ie_onload defer src=javascript:void(0)&&/script&&);
document.getElementById(&ie_onload&).onreadystatechange = function(){
if(this.readyState == &complete&){
this.onreadystatechange =
//针对safari浏览器,我们可以使用setInterval()函数周期性地检测document对象的readyState属性
if(/WebKit/i.test(navigator.userAgent)){
var _timer = setInterval(function(){
if(/loaded|complete/.test(document.readyState)){
clearInterval(_timer);
}46.正确计算区域大小47.比较常用的服务器请求方法HTML 代码(1)XHR
var url = '/data.php';
var params =['id=1','limit=2'];
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
if(req.readyState ===4){
var responseHeaders = req.getAlllResponseHeaders();
var data = req.responseT
req.open('GET',url+'?'+parames.join('&'),true);
req.setRequestHeader('X-Requested-With','XMLHttpRequest');
req.send(null);
(2)动态脚本标签插入
var scriptElement = document.createElement('script');
scriptElement.src='/lib.js';
document.getElmentsByTagName(&head&)[0].appendChild(scriptElement);
55 总笔记数
6.3万 总阅读量
Copyright &
All Rights Reserved.
合作伙伴:

我要回帖

更多关于 js判断用户是否登录 的文章

 

随机推荐