码迷,mamicode.com
首页 > 编程语言 > 详细

javascript_tutorial 【转】

时间:2015-02-28 10:09:43      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:

   

5) 变量 (将注意力集中在常用、有效情况及组合,其它合理语法不过多关注)

     

    - 语句

    javascript语句以换行表示结束。也可以用semicolon ";"显示表示换行结束。但最佳方式是用";"。试想在压缩格式中,如果没有";"会发生什么?

    

    - 声明并且赋值

    可以直接使用使用变量,无需var声明。fullName = ‘Larry Ullman‘; 。但最佳的方式是用var显示声明并同时赋值

            var fullName = ‘Larry Ullman‘;

            

    同时声明多个变量

            var firstName = ‘Larry‘, lastName = ‘Ullman‘;

 

    - 引用

    javascript的引用具有向后引用的特性。一行语句可以引用在后面申明的简单变量、复杂变量、函数。

 

    - var是无类型的

    var没有类型,javascript隐式转换

            var fullName = ‘Larry Ullman‘;

            fullName =    2;

 

    - var值类型

    简单的值类型分成三种。更复杂的是array和object

        number类型:  不能用引号括起。可以使数字、"."、"e"、"+"、"-",但不能包含千位分隔符号"," 。

        string: 可以使空""。即可以用单引号括起,也可以用双引号括起。如果单双引号相互包含,最佳的方式是使用反斜杠转义。比如

                "I‘ve got an idea."    正确

                ‘I\‘ve got an idea.‘    正确

                "Chapter 4, \"Simple Variable Types\""  正确

         boolean:  其值为true 、false 。在控制结构中null、undefined、0、empty string均被看做false。      null、undefined不能用引号括起,而是

                          直接使用。

         特殊的值:  null和undefined。undefined表示变量声明但未被赋值,此外如果函数没有显示返回值,其返回值为undefined。

                          null表示操作没有结果。

 

    - 值操作

        number类型: + - * / %。%表示取余数 7%2=1 。

                              可以和=组合。

                              可以自增减 ++、--, 有前置和后置两种属性。

 

    - 变量作用域

    全局变量    

    在函数外声明变量,即成为全局变量,可以从其他的js文件访问。全局变量的隐含意义是它们自动成为window的属性或方法,所以自定义的全局变量或者函数均可以用

    window.globalVariable,window.myFunction()来访问。所以window.print()可以简写为print()。

    在函数内部声明为局部变量,只能在同一函数内才能访问。即是从同一文件的其它函数体中也无法访问这个局部变量。

    避免与browser变量服务冲突的方法是使用骆驼法命名变量,至少有一个驼峰。

    此外浏览器提供的对象也是全局。

 

    -closure(闭包)

    如果函数局部变量被函数域内其它自定义函数访问,顶层函数中的局部变量生命期将扩大,可能是到整个浏览器窗口关闭,但作用域不变。同时顶层函数被访问的是其运行值

    ,而不是定义值。

(function(){

    var i=1; 

    window.onload=function(){

        alert(i); 

    };

    i = 300;

})()        

     将输出300        

    

 

    6) 流向控制

 

    - if

    if(true){}else if(true){} else{}

 

    - switch

switch (expression) {

case value1:

// Execute these statements.

break;

case value2:

// Execute these statements instead.

break;

default:

// No, execute these statements.

break;

}    

          相等的判断为identical,而非equal。其express为任何值类型,比如string。

          尤其注意break,如果忘记break,所有的语句都将被执行一遍。

          常用的情况有case联合,如下

          switch (weekday) {

case ‘Monday’:

case ‘Wednesday’:

case ‘Friday’:

// Execute these statements.

break;

case ‘Tuesday’:

case ‘Thursday’:

// Execute these statements instead.

break;

default:

// The default statements.

break;

}                          

 

    - CrYPtiC Conditionals

    格式

    (condition) ? return_if_true : return_if_false;

 

    - 循环控制

    for (initial expression; condition; after expression) {

        // Execute these statements.

    }    

    initial expression仅仅执行一次。当condition为true时候,进入循环体。当循环体执行完毕后,将执行after expression。

    一个比较复杂的循环例子。

    for (var i = 1, var j = 0; (i + j) <= 10; i++, j += i) {

        // Do something.

    }

 

    while (condition) {

        // Statements to be executed.

    }

    condition满足才进入循环体。

 

    do {

        // Statements to be executed.

    } while (condition);

    先执行循环体。退出时判断condition,为true,进入下一轮循环体。

 

    break

    退出整个循环。

 

    continue

    退出本轮循环,进入下一轮循环体。

 

 

        

    7) 注释

 

    //

    /*

     *

     */

 

    8) 流控制中逻辑运算及真值判断

     

    - 真值判断

    非假为真值。

    假值的情况包括, 所以-1将等价于true。

    • 0
    • false
    • NaN(Not a number)
    • null
    • undefined
    • empty string( ""或‘‘)

 

    - 逻辑运算(比较运算)

    在javascript中称为比较运算。包括 

    • >=
    • <=
    • ==           相等
    • !=
    • ===        identical。当两边有相同的值和相同的值类型时,运算结果为真。
    • !== 
    • &&         and
    • ||             or
    • !              not

    

    因为javascript会进行隐含的转换,0,empty string等都被转换为假值。但是他们的类型并不一样,如果用==比较,

    结果为真,用===比较,结果为假,因为他们的类型不一样。

    当要精确地与0、false、empty string、null、undefined进行比较时候,使用===。

 

    9) number运算精度及number比较

 

    小数0.321可以表示为.321,这样 1 - 0.321可以表示为  1- .321。

 

    number算术运算的精度和有效位数规则不知。如果进行下列运算将会有下列结果。

    1-.8=0.19999999999999996

    .3-.1=0.19999999999999998

    1-.3=0.7

    所以,比较 1-.8==.3-.1, 结果将为false。减少影响的方法是使用toFixed(width)将裁剪结果后的小数位。

    var v=1-.8;

    v.toFixed(1);  //结果将为0.2



    NaN是javascript中有效的保留字,表示这不是一个数字。但是它不能用在比较运算中。下列返回false

    if( NaN==NaN)

    所以将NaN用在比较运算中没有意思。如果要判断一个变量是否为一个数字(意思是能全部转化为数字),使用isNaN函数

    比如if(isNaN(n))。可以用isFinite()来代替判断变量是否为数字,isFinite表示是否为有限的数字。



    11) 字符串比较运算及字符串分行

    

    字符串运算时大小写敏感的,如果要进行大小写不敏感的比较,先调用toLowerCase() 或 toUpperCase()。

    if (email.toLowerCase() == storedEmail.toLowerCase())



    判断字符串包含关系

    if (comments.indexOf(‘spam’) != -1) { // Contains spam!

   

    字符串分行

    使用反斜杠"\"分行, 经常和换行符组合起来,"\n\"。并且通常用单引号将包括字符串,这样就可以直接将双引号作为普通的字符包含在字符串之中

    。比如下列语句创建一个新的div

    c = document.createElement(‘div‘);

    c.id = ‘promptWindowArea‘;

    c.innerHTML =

‘\n\

<div id="promptWindow" style="width:300px; height:150px; background-color: #00CCFF; padding: 5px; margin: 10px;"> \n\

<p style="height:40px;width:100px;">hardware info</p> \n\

<div style="overflow:auto;"> \n\

<button id="okbutton" style="position:left">ok</button> \n\

<button id="cancelbutton" style="position:left">cancel</button> \n\

</div> \n\

</div> \n\ ‘;

    alert(‘hello \

              word‘);

    

 

    12) 类型判断(typeof操作符)

 

    if (typeof myVar == ‘number’)

    常用类型返回值对应表。注意NaN返回number。

    

 

    typeof可以准确判断一个变量不属于undefined。如果要准确判断对象的类型还可使用

    • instanceof

                    这种方法只用于new创建的对象上

                    var Rectangle = function(x,y,size){ };

                    var myRec = new Rectangle(100,100,30);

if( myRec instanceof Rectangle )

{

 console.log(‘true‘);

}else{

 console.log(‘false‘);

}

                    将返回true 

    • constructor

if( myRec.constructor == Rectangle )

{

 console.log(‘true‘);

}else{

 console.log(‘false‘);

}                    

                    将输出true。注意比较运算的两边均不是简单对象,所以它们在比较运算之前,先隐式的进行其它运算。

 

    

 

    11 ) 复杂对象(高级对象)

    

    - Date

    创建日期对象    

    var today = new Date();

 

    - array

    创建数组

var myList = new Array(1, 2, 3);

var people = new Array(‘Fred‘,‘Daphne‘, ‘Velma‘, ‘Shaggy‘);

var options = new Array(true, false);        

var myVar = [];

var myList = [1, 2, 3];

var people = new Array(‘Fred‘,‘Daphne‘, ‘Velma‘, ‘Shaggy‘);

    可以创建混合数组,但是这种情况比较少

        var collection = [1, ‘Fred’, ‘Daphne’, 2, false];

 

    访问数组长度

    people.length得到数组长度,其中空隙占位undefined也被计算在内。

 

    访问数组内容

    直接访问数组变量将得到它所有结果,console.log(people)将输出"Fred Daphne Velma Shaggy"。

    使用[]访问单个元素,console.log(people[0])将输出"Fred"。

 

    为数组做赋值运算

    使用[]为数组中的元素赋值。

    可以向数组任意位置赋值,空隙将用undefined值填充。向数组末尾添加元素的方法是people[people.length]

    多个数组值合在一起,使用concat,但是有些浏览器不支持。

var primes = [];

primes.concat(1, [3, 5, 7]); // [1, 3, 5, 7]

 

    任意操作数组中的连续块splice()

    splice可以插入、删除、替换连续的数据块。splice会返回移除的number_to_operate个元素。且r的类型为object。如果插入、替换、删除、取移除值被写入一个表达中,

    先执行取值,再执行其它操作。

var ng=[0,1,2,3,4,5];

r = ng.splice(2,3,91,92,93,94);

console.log(ng);

console.log(r);

    结果输出

[0, 1, 91, 92, 93, 94, 5]

[2, 3, 4]

    r=splice(base_index, number_to_operate, new value, new value)。base_index是操作的基准点,number是数据块的长度。后面是新值。

    •     插入

    number_to_operate通常0,表示是插入操作。

var ng=[0,1,2,3,4,5];

ng.splice(2,0,91,92,93,94);

console.log(ng);

     输出

[0, 1, 91, 92, 93, 94, 2, 3, 4, 5]

    •     删除

                        如果没有new value, 表示是删除操作

var ng=[0,1,2,3,4,5];

ng.splice(2,3);

console.log(ng); 

                        输出

                               [0, 1, 5]

    •     替换

                        如果number_to_operate非0,且存在new value,则是替换操作。number_to_operate是删除的个数,后面的新值可以是任意个数 

var ng=[0,1,2,3,4,5];

ng.splice(2,3,99,92);

console.log(ng);

                        输出

                                [0, 1, 99, 92, 5]

    splice可以用于方向操作,如果base_index为负数,则从数组末尾开始定位。-1定位在index=length-1处。但是number_to_operate的操作方向仍然是向右。

var ng=[0,1,2,3,4,5];

ng.splice(-2,3,99,92,93);

console.log(ng);         

    输出 [0, 1, 2, 3, 99, 92, 93]

 

    取出数组中任意连续位置的值slice()

    var r = slice(start_index_point, end_index_point)。如果end_index_point不存在将直接取到数组结束。注意取出的数据不包括end_index_point指向

    的元素!!!

var primes = [1, 3, 5, 7]; //

var aPrime = primes.slice(0); //  [1, 3, 5, 7]

var bPrime = primes.slice(1,2); // [3]

console.log(aPrime);

console.log(bPrime);    

    参数也可以为负数,这样从后开始计算,但是连续的方向仍是从左到右。

var primes = [1, 3, 5, 7]; // [1, 3, 5, 7]

var bPrime = primes.slice(-2,-1);

console.log(bPrime);

    得到结果 [5]

        

    搜索数组内容

    var people = new Array(‘Fred‘,‘Daphne‘, ‘Velma‘, ‘Shaggy‘);

    people.indexOf(‘Velma‘)将得到2。

 

    数组空洞

    最好使用undefined显示定义。

    var myList = [1, , 3, , 5];不推荐,最好使用

    var myList = [1, undefined, 3, undefined, 5];

    在循环中通常要空洞是否存在,使用

        if (myList[i] !== undefined) { // Exists!

    或者if (i in myList) { // Exists!

    i表示索引号。

    删除数组,使用delete方法,数组中将留下一个空洞 delete people[0];

 

    数组元素的结构化操作。

    向末尾加入元素,意思即是元素被加在了index=length处。使用函数push()

    var primes = [];

    primes.push(1); // [1]

    primes.push(3, 5, 7); // [1, 3, 5, 7]    

    相反的操作是unshift(),它将元素加入了队列的开头。但是unshift的速度执行慢,所以慎用。

    弹出数组最后一个元素, 意思是index=length-1处的元素,使用pop()。

var primes = [1, 3, 5, 7]; // [1, 3, 5, 7]

primes.pop(); // [7]

    弹出数组中第一个元素shift()。它比pop慢,慎用。    

 

 

    多维数组

    var grid = [[2, 4, 6, 8], [1, 3, 5]];

    grid.length; // 2

    grid[0].length; // 4

    grid[1].length; // 3

    grid[0][0]; // 2, first item in the first subarray

    

    有用的且常用函数

    array_var.join(‘+‘) 将数组每个元素用“+”连接起来,最后得到一个字符串。

    array_var.split(‘+‘) 将字符串中每个元素用 "+"分割开来。

 

    - Object

    Object是所有的基类。注意object中的属性出现顺序是不固定的,并不依赖于书写顺序。

    对象可看做是无序的一组属性集合,而array是有序的。

    

    声明对象

    var myObj = new Object();

    或者

    var myObj = {};

    

    为对象赋值(指属性和操作)

        var chapter = {

                                num: 6,

                                title: ‘Complex Variable Types‘,

                       };    

    或

        var chapter = new Object({num: 6, title: ‘Complex Variable Types‘});

    属性值可以是更复杂的数组或对象

var me = {

name: ‘Larry Ullman‘,

age: 42,

car: {

make:‘Honda‘,

model: ‘Fit‘,

year: 2008

},

favoriteColors: [‘Black‘, ‘Blue‘, ‘Gray‘],

tired: true

};

 

    向对象中动态加入属性

    如果对象中没有该属性,赋值操作将自动增加该属性

    chapter.startPage = 256; 该语句将会增加startPage属性。

    判断属性是否存在使用undefined,   if(undefined===object.property)表示不存在。

    使用if(object.property)不能准确判断属性是否存在,因为num为0时候,比较运算返回false。

    使用in操作也可, if( ‘property_name‘ in object),当存在这个元素时候,返回真。

var myObj={

  num:false,

  name:‘bicycle‘,

};

if( ‘numd‘ in myObj)

  console.log("exist");

else

  console.log("not exist");

    在知道属性的值类型时,使用typeof也可准确判断属性是否存在if( ‘value type‘==typeof(object.property_name))

 

    访问对象属性

    使用chaining object notation方法访问对象属性,object.property_name.property_name。

        me.car.model; // Fit

        me.favoriteColors[0]; // Black

    使用array notation书写方法访问对象属性,这时对象被看做是一维数组,属性被看做了位置属性。前面两句等价于

        me[‘car‘][‘model‘]; //Fit

        me[‘favoriteColors‘][0]; //Black

    在某种情况下,只能使用array notation书写方式访问对象属性,见<<moder javascript develop and design>> Page210

    现在举例。

        var car = {

  brand:‘sony‘,

  price:150000,

  engine:4,

        }

        for(p in car)

{

  console.log(car[p]);

}    

        将输出sony 150000 4

 

    遍历对象所有成员

    使用for in遍历。这种方法注意一者元素的出现顺序不固定,二者会看见父类的属性,三者速度较慢

for (var p in myObj) {

// Use myObj[p]. property_name

}    

 

    删除对象一个属性

    使用delete obj.property_name

 

    函数是一个对象

    函数也是一个对象,如果使用toString, 将得到函数的代码。使用typeof,将返字符串function。如果console.log(function_name),将得到

    function_name()。

    

    this

    在对象的函数成员中访问自己的属性,使用this.property的方式。

 

    对象之间赋值

    对象之间可以相互赋值

var car = {

 color:‘green‘,

 startToRun:function(){console.log(‘running‘)},

};

var toshibaCar = car;

console.log(‘toshiba car COLOR is:‘+toshibaCar.color);

toshibaCar.startToRun();

console.log(typeof(toshibaCar));

    将输出

toshiba car COLOR is:green

running

object    

 

    12) 函数

 

    - 基本

 

    定义函数

    函数也是对象,所以它定义的书写方式和其它变量的书写方式一样。

    function fname(arg_name, arg_name){}。参数列表中不需要像C语言那样定义类型,因为javascript是没有变量类型的,只有值类型。

    参数前面的不需var关键字。

 

    调用函数

    除了使用常规的方式外。

    如果传入的参数不够,不足的部分被定义为undefined。如果传入的参数过多,多出的部分将被自动截断。这两种情况均视为合理状况。

    通过这种方法,可以知道用户忘记传递那个参数。

function theBuy(bookName)

{

    if(undefined === bookName)

      console.log("please input para bookName");

    else

      console.log("have bought "+bookName+" book");

}

theBuy();

    输出 please input para bookName        

    如果想为函数设置缺省值,利用下列方法

function functionName(someVar) {

if (typeof someVar == ‘undefined’) {

someVar = ‘default value’;

}

}

    如果想跳过中间的参数,使用undefined。

function functionName(a, b, c) {

}

functionName(true, undefined, false);    

    还可以将参数值组成obj传递进去。这种方法可能更容易阅读。

var drawRectangle = function(obj){

  console.log( obj.x+‘ ‘+obj.y+‘ ‘+obj.size );

}

drawRectangle({x:50,y:50,size:300});    

    将输出

         50 50 300

 

    返回值

    不能显示去声明返回的变量。如果函数没有return语句,或者return语句后没有数据,等价于函数返回undefined。

    如果想返回多个值,使用数组。 return [‘h‘,‘o‘];

    当然也可返回对象 return {x: 1, y: 2};

 

    

    - 函数体内内置对象arguments

    

    arguments只在函数体有效,它是array-like的一种变量,但是不能向其中插入元素。arguments容纳实际的输入值,与函数定义中参数的

    名称和个数没有关系,即arguments只是与实参有关系,与形参没有关系。arguments.length表示传入参数的个数,如果定义了两个参数,

    但是只传入了一个,那么arguments.length的值

    仍为1。

function drawcar(size,color)

{

  console.log(arguments);

  console.log(arguments.length);

};

drawcar(100);    

    输出[100] 1

 

    用于可变长参数

    使用arguments.length设计可变长函数。?

function myJoin()

{

  var tol = ‘‘;

  for(var i=0,len = arguments.length;i<len;i++)

  {

    tol += arguments[i] + ‘ ‘;

  }

  console.log(tol);

}  

myJoin(‘quest‘,‘helen‘,‘nana‘)

     输出quest helen nana

    

    - 使用object构造可变长函数

    除了使用arguments外,还可使用object,好处在于向函数内部传递数据时候是reference。

function showCar(myObj)

{

  for(var p in myObj)

    console.log(myObj[p]);

}

showCar({

  size:‘500m‘,

  color:‘red‘

});

    输出 500 red    

 

    - 函数入口数据传递

    有两种方法,值传递和引用传递。简单值类型string,number,boolean是值传递。object和array是引用传递。

    

    - 使用符号作为函数名

    最灵活的是使用符号作为函数名,典型的例子是$。

 

    - 匿名函数(没有名字)

    可以创建一个匿名函数,再将它赋给一个变量。这种方法的用处是书写灵活。下例子等价于function getTwo(){}

var getTwo = function() {

return 2;

}    

    匿名函数也是一个对象,只是没有名字。所以需要将它赋给一个变量,或者作为其它函数的参数值。最重要的用处

    是为对象的属性赋予一个匿名函数,显然在这里不能用显示的函数命名。

    另一个优美的用法是立刻自我调用,注意,一定要跟着分号。

(function() {

// Function body goes here.

})();    

    这种方法的好处是变量可以从全局变量中分离开来。可以直接传递参数。

(function(str){ 
 alert(str); 

})(‘hello‘);        

    

 

    - 函数嵌套

    这时向函数传递的是一个动作。

 

    - chain 函数

    function().function().function(), 函数的返回值在函数之间从左到右传递,形同chain。为了取得chain书写效果,每个函数必须要返回

    一个合适的对象。

 

    - 判断browser中的对象是否提供某种功能支持

    if(obj.function_name),如果不存在function_name,将返回undefined.

 

   - 函数嵌套

    一个函数可以在另一个函数体中定义,并定义。有何用处?将(function(){})()作为程序主体可以很有用,其它有用的场景

    未知。

 

    - 递归

    递归是最重要的和常用的函数用法,一个递归函数包括入口、出口、循环体。循环体就是它自身。出口在函数开始处,入口在函数的末尾或循环体中,通过调用自己来

    实现。

    任何一个重复工作都可以使用递归实现,和循环体比较起来,可能的不利之处是递归依赖堆栈,可能会让堆栈崩溃。

    比如计算字符串长度用递归来实现。

function countLength(str)

{

    // 出口

    if(str == ‘‘)

    {

         return 0;

    }

    // 循环体和入口

    return 1+countLength(str.substring(1));

countLength(‘abcde‘);

          输出

                5

 

    - 函数是一个对象

    更加高级的话题是函数是一个对象。采用下面书写方式,明显的表明了函数是一个对象。

        var Rectangle= function(x,y,size){};

    左边var Rectangle的书写方式表明了函数与普通的变量声明一样,它也是一个对象。右边的匿名方式表明这是函数的值,形式上是一个函数体。

 

    为函数对象添加成员

    和普通的对象一样,可以向函数中添加属性成员和函数成员。和普通的对象一样,如果不存在这个属性,赋值运算后,它自动被加入函数对象之中

Rectangle.xis = 100;

          Rectangle.yis = 200;

Rectangle.draw = function(){

 console.log(‘rectangle drawed‘);

}

console.log(Rectangle.xis);

console.log(Rectangle.yis);

Rectangle.draw();        

    将输出

        100 200 rectangle drawed

    

    函数对象之间可以相互赋值

yourRec = Rectangle;

console.log(‘yourRec type is:‘ + typeof(yourRec));

yourRec.draw();    

    将输出

         yourRec type is:function

         rectangle drawed



    对函数执行new操作

    函数和普通对象的不同在于可以对函数对象执行new操作。这时候,除了返回一个对象外,函数体本身的代码会被执行。

        var Rectangle= function(x,y,size){

            console.log(‘in body‘);

        }

        var rectinstance = new Rectangle();

    输出

        in body

    上条语句可以直接写new Rectangle(), 它也将输出in body。

    当使用new时候,函数名体现了一种共同的特性,可以用于构造类系统。



 

 

 

    13) event

    

    - 位置

    起初的方法是在html文档中直接嵌入时间处理函数,但这种方法书写凌乱,不便于阅读,已被抛弃。

        <input type=‘button‘ value=‘clickme‘ onclick=‘alert("hello");alert("world");‘/>

    另一种方式是传统的方式,这种方法已经使用了10多年,在所有的浏览器上都能工作。下面是将一个匿名函数

    赋给了window对象的onload事件。

window.onload = function() {

// Do whatever.

}

    第三种是w3c推荐的addEventListener(),比如window.addEventListener(‘load’, init, false)。这里注意第一个参数是事件的

    名称,它不是window的属性。第二参数表示时间的处理函数。

 

   -  事件传统书写方式详解

    在传统方式中如果想取消一个事件的处理函数,使用null。

          window.onload=null;

    新的事件处理函数将会覆盖掉以前处理函数。下面代码calculate处理函数将会取代process处理函数。所以这种方式无法添加多个

    事件处理函数。

document.getElementById(‘theForm’).onsubmit = process;

document.getElementById(‘theForm’).onsubmit = calculate; // Oops!    

    

    - w3c addEventListener详解

    添加多个事件处理函数addEventListener,但最不幸的是ie9以前的版本不支持该函数!。这个函数不会覆盖以前的事件处理函数,

   也不会覆盖使用传统书写方式添加的事件处理函数。下例子中load事件拥有两个事件处理函数

window.addEventListener(‘load’, process, false);

window.addEventListener(‘load’, calculate, false);

    删除事件处理函数removeEventListener。不方便,删除时候参数填写必须和添加时完全一致。

          window.removeEventListener(‘load’, process, false);      

    在ie9以前使用attachEvent()和detachEvent()添加和删除函数,比如下例。但是要注意使用的onload,这个应该是window的属性。

    同时attachEvent也能添加多个处理函数。

        window.attachEvent(‘onload’, init);

 

    - ie事件添加函数兼容性检查

    ie是在9中遵守w3c标准,老版本中使用的是attachEvent。需要判断浏览器版本。依据的方法是如果对象不存在函数,obj.func将

    返回undefined, 如果存在,obj.func将返回function()。

if (window.addEventListener) { // W3C

window.addEventListener(‘load’, init, false);

} else if (window.attachEvent) { // Older IE

window.attachEvent(‘onload’, init);

}

 

    - 已存事件快速浏览

    按照这个分类方法认识所有的事件input device, browser,keyboard,form。

 

    input device event

    input device是光标驱动的设备。常见的事件有mousedown、click、mouseup、mouseout、mousemove(会降低性能,尽量少用,当鼠标移动时候激发。只有在

    目标元素上才会激发,出了目标元素的区域,失效)    、mouseover(光标进入元素区域)



    keyboard常见的事件是keydown、keypress、keyup



    browser常见的事件有load、unloaded(当其它资源从browser中释放时候触发)、resize(调整window大小)、scroll(滚动窗口时候触发)、focus(当浏览器得到焦点时)、

    blur(当浏览器失去焦点时候)。



    form常见event有reset(当点击form的reset按钮)、change(当form中的元素被修改时发生,对于复选框等改变时候即发出该事件,对于文本输入框,当它失去焦点

    时候发出change事件)、select(当选中文本输入框时候)

 

    - 访问事件环境和自身信息

    浏览器通过参数向事件处理函数传递环境信息。e表示处理函数对应的事件。在ie9及其它浏览器上,这个名字可以任意命名,通常使用最简洁的方式e。

function someEventHandler(e) {

// Use e.

}    

    在ie8及老版本中,事件对象放在了window.event之中。所以用这种格式访问。

function someEventHandler() {

// Use window.event.

}    

   但是如果使用inline event方式处理,处理函数的参数必须命名为event。像这样。

        <a href=”somepage.html” onclick=”doSomething(event);”>Some Link</a> 

    事件处理函数跨浏览器访问事件的方法是使用下列方式

function someEventHandler(e) {

if (typeof e == ‘undefined’) e = window.event;

// Use e.

}

    或

           e = e || window.event;    //所以javascript逻辑运算与c语言逻辑运算有差别。c逻辑运算最后只有真假。但javascript逻辑运算它可以

           返回一个有意义的值。

    或

            e = e || window.event;

    

    访问对应元素的方法,在ie8及老版本中是使用target属性,在ie9及其它浏览器中是使用srcElement,统一这两种方式跨浏览器的方法是

            var target = e.target || e.srcElement;

       

    this变量

    在ie9及其它浏览器中,this代表的正是我们所期望的html元素。但是在ie8及老版本中,它代表的window对象。所以如果在事件处理函数中

    使用this变量,需要发明兼容性的书写方式。

 

    获取按下键值及key pressed事件

    键盘一个按键有character和keyCode两种值。按键的keyCode唯一,它对应的character可能有多个,最常见的是大小写。举例子来说‘a‘

    按键的keyCode是65, 它的character有两个‘A‘和‘a‘。‘A‘的unicode编码是65 ,‘a‘的unicode是97。

    要获取按下键的键值,在ie中使用keyCode,在其它浏览器使用which。但实际ie的情况更为复杂。

    在ie中,当keypress事件发生时候,keyCode存放的是character code,当keydown和keyup发生时候, keyCode存放是按键值。

    跨浏览器的书写方式是

        var charCode = e.which || e.keyCode;

    或更加精确的方式

        var charCode = (typeof e.which == ‘number’) ? e.which : e.keyCode;

    这里经常用到方法是将数字装换为字符,使用String库函数

        var ch = String.fromCharCode(97)   //得到a

    存在一些特殊的key。alt, shift,ctrl在event对象中有自己对应的布尔属性,表示是否按下,它们是shiftKey, ctrlKey, altKey。同时单独按下这三个键时候

    也不会激发keypress事件。

 

    - 替换事件缺省行为

    事件处理函数返回false即可阻止缺省的处理动作。比如<a href=‘http://www.bing.com‘>,返回false,将不会网页跳转。但是不同元素,不同事件,其

    缺省行为含义定义不一样。

    

    - event bubble

    当事件穿越父子元素时候,按bubble原则处理。举例如下,假设有下列元素

<div><h1>This is a Title</h1>

<p>This is a paragraph.

<a href=”#” id=”link”>This is a link.</a></p>

</div>    

    拥有的父子关系是

          div - 

                - h1

                - p

                        - a

    事件的路径如下图

        

    当将鼠标移动到a上时,将发生mouseover事件。mouseover事件的产生经过两个阶段。首先capture,此阶段,硬件事件将被从上到下一直比较到最末的孩子,所有注册了

    mouseover处理函数的元素都将被着色。第二个阶段浏览器从底部向上浮升,所有被着色的元素将被依次调用mouseover的处理函数(当然是从下到上依次调用)。

    附件

 

    bubble的意义是当注意力转移到子元素(注意不是z轴上面的元素)上时候,虽然焦点已经转移到子元素上,但是父元素仍然能够收到事件通知。附件显示了bubble效果,当点击

    button(用div模拟),它的父div将受到click事件,输出

        button click

        dv click

      

 

    在capture phase与event交互 ?(具体使用场合未知)

    传统的书写方式只能用在bubble phase阶段。ie8及ie老版本不能用于capture phase阶段。ie9及其其它版本可以将addEventListener第三个参数设置为true,

    在capture phase阶段关注事件,比如addEventListener(someDiv, ‘mouseover’, true)。在capture phase阶段关注事件的意义在于它可以截断事件,或者在

    事件发生之前(应该是指事件处理函数被调用之前)做准备工作。

    注意focus, blur, change, scroll, and submit这几个事件没有bubble phase。

    

    阻止bubble phase

    有时当子元素捕获到事件时,并不希望事件bubble到父元素(即不向上传递到父元素,因而父元素的事件处理函数将不会被激发)。在ie老版本中使用

    e.cancelBubble = true, 在ie9及其它浏览器中使用e.stopPropogation()。统一的方式使用下列代码。

if (e.stopPropogation) { // W3C/addEventListener()

e.stopPropogation();

} else { // Older IE.

e.cancelBubble = true;

}

    附件显示了bubble canncel的效果,当在button(用一个div模拟)上点击时候,只显示button click。

      



    event delegation(事件委托)

    因为所有的事件都会bubble到父元素,且事件参数的源属性为最底层的元素,所以可将事件处理函数统一移动到父元素中处理。下列在父元素dv中处理所有的点击事件

      

    

    14) window

    常见的dialog有alert、confirmation、prompt。分别用函数alert、confirm、prompt创建。, 它们没有html和css,不能修改风格,所以将被更好的方法取代。

 

    因为window为顶级元素,所以所有定义的函数自动成为window的属性,可以使用window.yourFunc()形式来调用,当然我们更愿意使用直接的方式yourFunc()。

    对于函数外定义变量也同样适用,可以使用window.yourVariable来访问

      

 

    浏览器版本sniffing

    可以使用window.navigator.userAgent来判断浏览器的种类和版本,但使用object detection的方法更好。

 

    浏览器窗口位置

    使用window的screenX和screenY。它们表示的是浏览器的左上角相对于显示屏幕的绝对位置。但是ie使用的是screenLeft,screenTop。

 

    浏览器窗口大小

    注意,有些浏览器可能不能在高分辨率下工作,比如火狐,虽然os的分辨率设为1600*900, 但它只能在一个小的分辨率下工作,可能是1200*600.

    innerHeight和innerWidth显示了客户区的大小。

    outerHeight和outerWidth显示了整体的大小。

    对于老版本ie(ie8),使用document.body.clientHeight和document.body.clientWidth。

    

    移动浏览器

    使用moveTo()或者moveBy(),但是很少有必要移动浏览器。(实验,这两个方法仿佛无效)

    moveTo,以显示屏幕左上角为坐标点。

 

    获取物理显示屏信息

    使用window.screen对象。

    • window.screen.height 分辨率的高度
    • window.screen.width 分辨率的宽度
    • window.screen.availHeight 可用高度
    • window.screen.colorDepth 颜色的深度

 

    使用javascript打开一个新的窗口

    window.open(‘somefile.html‘),它导致浏览器打开一个新的标签页,显示somefile.html的内容。注意需要将返回值赋给一个变量,否则在某些浏览器中会

    产生问题。

            var popup = window.open(‘somefile.html’);

    open方法通常被用来打广告,所以浏览器常常会屏蔽这一个功能,这时open返回null。

    open的第二个参数可以为新建窗口取一个名字,第三个参数可以控制窗口的外观,注意这些属性之间不能有空格!下面是一个例子

var popup = window.open(‘somepage.html‘, ‘myWindowName‘,

‘height=200,width=200,location=no,resizable=yes,scrollbars=yes‘);    

    但是不同的浏览器对第三个参数的处理方式不同,在Firefox中,上面的语句会弹出一个完全新的窗口,而maxthon仍然是在新标签中打开。

    下面是可以在第三个参数中设置的window属性。

    

    

    open创建窗口的焦点控制

    使用popup.focus()函数激活一个窗口。未实验,不知道实际的含义。

    



    关闭open创建的窗口

    window.close用来关闭open打开的窗口,但实验中关闭了父窗口,不知为何?

    查看使用open打开窗口的状态,使用下列语句。

        if ((popup !== null) && !popup.closed) { // Still open.

    

    标准的打开窗口方式

    使用javascript方法创建新的窗口难于控制外观,应该使用html a 的方式打开,就像下列方式一样。

        <a href="popupB.html" id="link" target="PopUp">B Link</a>

    

    在窗口之前传递数据(未实验)

    

 

    使用history浏览历史(未实验)

    back()

    forward()

    go()

 

    frame

    传统的frameset方式已经过时。现在通常使用的是iframe。

    iframe常用的场景是,判断一个窗口是否是iframe, iframe和父窗口交互,获取窗口所拥有的frame。未实验。

        if (window.parent != window.self) { // This is a child!  In the parent    

        window.frames[0]

    访问iframe的属性和方法

var frame = document.getElementById(‘theFrame’);

var frameWindow = frame.contentWindow || frame.contentDocument;

// Access frameWindow.property and frameWindow.function()

 

    重定向窗口

    直接改变location属性,可以立刻重定向窗口。

       window.location =‘http://www.example.com/otherpage.html‘;     

    同样的效果的另一种书写方式

        window.location.href = ‘http://www.example.com/otherpage.html‘;

    这两种方法的前一个页面均留在history中,可以用后退再次访问。

    使用location.replace()函数,前一个网页不会进入history,因而无法用后退访问。

        window.location.replace(‘http://www.example.com/otherpage.html‘);

    还可以直接进入home中,home()仿佛无效?

        invoking window.home()

    location有两个常用的工具search和hash。search表示?, 用来传递数值,之间通常使用&分开,下面是一个例子。

        http://www.example.com/page.php?s=10&np=7&sort=name

    使用search运算,下面的语句返回?s=10&np=7&sort=name

        var search = window.location.search;

    hash的一个作用是,它可以通过<a>将页面视线移动到一个元素之中,比如下面语句

    <a href=‘#bb‘>move eye to button that has id bb</a>

        

    hash的另一个用途是记录页面的状态,比如说在有tab的页面中,记录当前是在那个tab之上,这种技术也称为deep linking。同时这种视线的改变也会加入history之中,

    因而可以back后退。

    当search和hash组合在一起的时候,正常的顺序应该是?...#,并且#后只有一个值。

 

    打印页面

    使用window.print(), 当然在某些设备上可能不支持该功能。

 

    window的document属性

    document属性代表加载了的html。document关键的属性有

    • getElementById(), 获取html中的元素
    • document.getElementsByTagName()
    • write()和writeln(),向html中写入内容,但是它们应该抛弃,主要是因为它们破坏了DOM结构。但是第三方软件和ads常常使用这个功能将代码加入到page中。
    • compatMode属性,表明浏览器的工作模式,是在Quirks 或者Standard下。值为BackCompat表示Quirk模式,CSS1Compat表示standard模式。

 

    15) DOM(Document Object Model)

    

    HTML为root element,它有唯一的父节点document, document也只有一个孩子,即HTML.

    DOM节点的关系。以附件的文档为例子

    • parentNode表示父节点,只有一个。
    • childNodes表示孩子节点,如果使用console.log(rootDiv.childNodes+‘‘),观察rootDiv语法含义,得到[object NodeList]。

                    如果使用console.log(rootDiv.childNodes)观察运行值,得到下面输出。文本和div都被平行当做了rootDiv的孩子,共7个。

NodeList[<TextNode textContent="\n parent\n ">, div#childQuestDiv, <TextNode textContent="\n ">, div#childHuQuanDiv, <TextNode textContent=" \n ">, div#childLiuJC, <TextNode textContent="\n\n">]

    • firstChild, 表示childNotes中第一个孩子
    • lastChild,与firstChild相对
    • previousSibling 表示前一个兄弟,console.log(childHuQuanDiv.previousSibling)是一个换行符,将输出

                             <TextNode textContent="\n ">

    • nextSibling
    • children,只显示html元素,不包括文本。console.log(rootDiv.children)输出如下,只有三个成员

                             HTMLCollection[div#childQuestDiv, div#childHuQuanDiv, div#childLiuJC]

    •  

    

    观察node信息

    • nodeName,比如输出DIV
    • nodeValue,  仿佛不存在?
    • nodeType, 是一个数字,含义如下表

                    

    寻找节点  

    方法一,从根节点开始,document.documentElement将返回HTML根元素,从html开始,便能遍历到所有的元素。

    方法二,使用快捷方式访问DOM元素

    • document.body 指向body
    • document.forms 包含所有的form
    • document.images 包含所有的图片
    • document.links 包含所有的连接

    方法三,任意访问节点

    • document.getElementById(),如果没有,将返回null。从ie6起,即firefox等均支持,是一个基本的函数。
    • getElementsByTagName(),查找html元素。该函数可以用于任何对象上(不仅仅是document),它返回的是元素的子孙中(不包括本身)tag符合条件的元素。

                    var rootDiv = U.$(‘rootDiv‘);

                    console.log(rootDiv.getElementsByTagName(‘DIV‘));

                    上面两条语句输出

                    HTMLCollection[div#childQuestDiv, div#childHuQuanDiv, div#duduDiv, div#childLiuJC]

    • 将两个函数和并,因为getElementsByTagName()函数可用于任何对象上,所以可以将它们合并起来,比

                         document.getElementById(‘header‘). getElementsByTagName(‘a‘);

                        

    • getElementsByClassName() ,ie8支持,在ie7,ie6老版本中不支持。

    方法四, 使用css selector

                参数是css选择子,比如像 p>a,或则#rootDIV

    • querySelector(),  返回遇到的第一个元素。即可在document上调用,也可在任何object上调用。ie老版本不支持
    • querySelectorAll() ,返回所有的元素。即可在document上调用,也可在任何object上调用。ie老版本不支持

 

    修改元素

    元素可以修改的属性通常和html元素的属性对应(?)。

    - class、for

        class 、for是javascript的关键字,所以要访问html element的class、for属性使用className和htmlFor。

            childLiuJC.className=‘hightschool‘;

    - innerText ,textContent

        将元素内容用纯文本替换,文本内容没有意义。需要做object detection

        

    - innerHTML

        将元素内容用html元素替换

        

    

    创建元素

    - document.createElement() 创建一个元素

        创建一个html 元素 <arg></arg>, arg可以使任何字符串,document.createElement(‘myNewTag‘)将创建<myNewTag></myNewTag>元素。

        var p = document.createElement(‘p‘);

        p.innerText = ‘This is some text‘;

        p.className = ‘enhanced‘;

    - 将新建元素插入html中。insertBefore(), appendChild(), or replaceChild()

        

       rootDiv.appendChild(p) 将把p(This is some text)插入到rootDiv的尾部

        

 

        rootDiv.insertBefore(p, childHuQuanDiv);

        将把p(This is some text)插入到childHuQuanDiv之前

        

      

      rootDiv.replaceChild(p, childHuQuanDiv);

    将替换掉childHuQuanDiv

    

 

    如果仅仅添加文本,使用document.createTextNode()        

        var p = document.createTextNode(‘hello world‘);

        rootDiv.appendChild(p);

 

    克隆元素

    - document.cloneNode()

        这个函数不会拷贝内容和事件,但是会拷贝风格

        var p = duduDiv.cloneNode();

        rootDiv.appendChild(p);

        输出

        

        

    -removeChild删除元素

    运用在父元素之上

        rootDiv.removeChild(childHuQuanDiv);

    寻找父元素的方法是使用parentNode属性。

 

    16) javascrip和css

    元素的css风格均放在style成员之中,style的属性均用骆驼法命名。style的值均被转换为inline style。反过来,从style属性中读出的值均是inline style。使用

        console.log(duduDiv.style);

    将会看到下列输出

    

    蓝色数字是什么意思呢?猜想可能是枚举变量的对应值。

 

    - 获取元素所有的style(可能还包括inline style风格以外)

    需做跨平台检测,ie用currentStyle.yourSpecificStyle, 其它使用window.getComputedStyle(yourElem)。注意只能有用读,不能写。

 

    - 隐藏和显示元素

        duduDiv.style.visibility = ‘hidden‘;

        duduDiv.style.visibility = ‘visible‘;

 

    - 查看外部css的style

       document.styleSheets,书上说是列出page用到的所有style,但实验结果为空,不知为何? P356

       如果外部css文件拥有id,还可以使用getElementById取得它的引用

<!-- HTML -->

<link rel=‘stylesheet‘ id=‘mainStyleSheet‘ href=‘style.css‘>

// JavaScript:

var mainCSS = document.getElementById(‘mainStyleSheet‘);

mainCSS的成员只能,但是能失效整个css文件,如同下面语句。

mainCSS.disabled = ‘disabled‘;

使用insertRule()函数可以插入一条规则,但是下面语句实验失败,不知为何?50表示规则索引号

mainCSS.insertRule(‘.child: {visibility: none;}‘, 50);

mainCSS.deleteRule(5)表示删除索引号为5的规则,也是实验不能通过。

 

    - 创建一个内置的style

    可以使用createElement创建一个内置的style风格。比如下列代码

   var s = document.createElement(‘style‘);

   s.textContent = ‘div {border:2px solid green;}‘;

   document.body.appendChild(s);

    将会把div便为绿框

    

 

 

    17) 文法摘要,运行值观察,typeof类型观察(理论创建)

    

    console.log(), object.toString(),typeof(),比较运算中,javascript自动转换object,为用户输出有意义的值。对象包括number, boolean, string, array,object。

    javascript的转换方式影响object detection。

    

    - number

 var nbr = 93;

 console.log(‘run value: ‘+nbr);

 console.log(‘tostring: ‘+nbr.toString());

 console.log(‘typeof: ‘+typeof(nbr));

 if(93 === nbr)

 console.log(‘=== true‘);

            这段代码将输出 

run value: 93

tostring: 93

typeof: number

=== true

    

    - string

 var str = ‘abc‘;

 console.log(‘run value: ‘+str);

 console.log(‘tostring: ‘+str.toString());

 console.log(‘typeof: ‘+typeof(str));

 if(‘abc‘ === str)

 console.log(‘=== true‘);            

            这段代码输出

run value: abc

tostring: abc

typeof: string

=== true        

 

    - boolean

 var bl = true;

 console.log(‘run value: ‘+bl);

 console.log(‘tostring: ‘+bl.toString());

 console.log(‘typeof: ‘+typeof(bl));

 if(true === bl)

 console.log(‘=== true‘);    

            这段代码输出

run value: true

tostring: true

typeof: boolean

=== true

 

    - array

 var ary = [12,56,910];

 console.log(‘run value: ‘+ary); 

 console.log(‘tostring: ‘+ary.toString()+ ‘ the of toString: ‘+ ary.toString().length);

 console.log(‘typeof: ‘+typeof(ary));

 if(‘12,56,910‘ == ary)

 console.log(‘== true‘);

 else

 console.log(‘== false‘);

           这段代码输出如下,在比较运算中,javascript将ary转换成了字符串‘12,56,910‘

run value: 12,56,910

tostring: 12,56,910 the of toString: 9

typeof: object

== true        

如果将比较运算改为

 if(‘12,56,910‘ === ary)

  console.log(‘=== true‘);

 else

  console.log(‘=== false‘);

将输出

                === false

           因为等式两边虽然值等,但是类型并不相等。

          同时将console.log(‘run value: ‘+ary)改为console.log(ary), 将得到下面输出

                [12,56,910]

 

    - obj

          比如页面上有一个div元素,id号为rootDiv ,页面布局如附件

   var rootDiv = U.$(‘rootDiv‘);

   console.log(‘div element run value: ‘+rootDiv);

   console.log(‘div element tostring: ‘+rootDiv.toString() + ‘ length: ‘+rootDiv.toString().length);

   console.log(typeof(rootDiv));

   if( ‘[object HTMLDivElement]‘ == rootDiv)

    console.log(‘== true‘);

   else

    console.log(‘== false‘);    

            将输出

div element run value: [object HTMLDivElement]

div element tostring: [object HTMLDivElement] length: 23

object

== true        

            toString表示的是rootDiv的语法摘要。在比较运算中javascript转换为了语法意义。    

            将‘div element run value: ‘+rootDiv进行加法运算时候,javascript会隐含调用rootDiv的toString, 所以要观察rootDiv的运行值,应该

            这样写

                    console.log(rootDiv);

            它将输出如下运行值,让我们观察到rootDiv元素的内容

                <div id="rootDiv" style="border:1px solid gray;width:300px;height:300px;margin:10px;">

            所以如果想观察对象的文法意义,使用下面方式更加快捷

                console.log(rootDiv+‘‘);

 

    - 观察对象的文法含义

        对于高级对象,如果想要观察对象的文法摘要,使用

            console.log(obj.toString());

        更加快捷的书写方式是

            console.log(obj+‘‘);       

 

    18)  定时器

    javascript定时器精度为1毫秒。同时javascript是单线程,所以无法保证精确的时间间隔。

 

    设置一次性定时器

        setTimeout(function(){   alert(‘3 seconds passed‘);},  3000); 

        3秒钟后,将弹出对话框‘3 seconds passed‘

    设置重复定时器

        setInterval(function(){alert(‘5 s‘);},5000)

        每隔5秒,均会弹出对话框,显示‘5 s‘

    终止重复定时器的执行   

        使用clearInterval函数,参数为setInterval返回的定时器标识符号。可以从外部终止重复定时器,也可以从定时器内部终止定时器。从内部终止定时器即是

        在定时器处理函数中写入终止条件,这样的好处是什么?可能是提高可读性,在创建时候,就明确指明退出条件,避免终止命令分散在工程各处,难以寻找。

    

            

    19) 函数内变量、匿名函数变量作用域研究                 

        -  全局域中定义的函数自动成为window的属性



        -  全局域中定义的变量自动成为window的属性



        -  函数体中定义变量为局部变量,当函数退出时,它们的值不会被保存,当再次进入时候,它们的值被恢复为初始值



        - 创建自定义对象



           函数本身也是对象。就像普通的对象一样,如果使用标号方式(即object.property) 向对象赋值,即是property不存在,但是经过赋值操作后property自动加入

           object的属性。所以如果在函数内使用this.property=value的方式,将自动为函数对象加入一个属性property。下面的代码运行将输出‘swan‘。

function drawStar()

{

 this.startName= ‘swan‘;

 this.stopDraw = function(){};

}

var doIt = new drawStar();

console.log(doIt.startName);

            因为javascript是基于prototype-type的oo编程语言,默认声明的都是对象。可以使用function 来加入新的自定义类,使得它像String, Number, Boolean,

            Array, Object一样使用。

    



    20) 类的构建(javascript称为自定义对象)

 

    - 使用function构建自定义对象

 

    javascript是prototype-type型的oo语言,不能创建类。使用函数,可以创建类系统,或者说为javascript加入自定义类,而不仅仅是系统的

    定义的String,Number, Boolean, Array。

    使用function的new特性,这时函数体的内容应该只放构造内容,加入成员函数,而不要放入其它东西。下面代码创建了新类Rectangle,可以向String一样

    用new操作符创建Rectangle对象。

var Rectangle = function(x,y,size){

 this.xis = x;

 this.yis = y;

 this.size = size;

 this.draw = function(){

  console.log(‘rectangle drawed: (x,y)size:‘+x+ ‘ ‘+y+‘ ‘+size);

 }

};

var myRec = new Rectangle(100,100,30);

myRec.draw();    

    输出

          rectangle drawed: (x,y)size:100 100 30

    通常还可以加入自定义toString()和valueOf。toString反映语义摘要,valueOf反映值。

 

    - 原型链(prototype chain)

 

    myRec是基于Rectangle原型,而Rectangle又是基于Object,这成为原型链。为了区分一个方法是原型链中的还是对象自定义的,使用hasOwnProperty方法。它返回

    boolean值。

    

    - 向原型添加方法

 

    如果向系统已有原型如String、Array等添加要谨慎。向自定义原型添加属性是很常见的。注意直接向函数对象赋值并不能加入原型之中,原因暂时将其理解为是因为它仅仅是

    加入到函数对象之中。比如

Rectangle.disable = function(){console.log(‘disabled‘);}

Rectangle.disable();

    将输出

          disabled

    下列代码试图从Rectangle的对象myRec中调用disable, 将出错,因为上面的方法不能将disable方法加入原型Rectangle之中。

Rectangle.disable = function(){console.log(‘disabled‘);}

myRec.disable();          

     想要修改Rectangle原型,应该使用prototype属性

Rectangle.prototype.disable = function(){console.log(‘disabled added into prototype‘);}

var myRec = new Rectangle(100,100,30);

myRec.disable();               

    上面代码将输出

          disabled added into prototype

 

 



    21) 高级话题

        - 危险代码

        eval(commandstring)

        eval将commandstring当做命令来执行,会为黑客开放大门,应该尽量少用。eval("alert(‘hello‘)");会执行javascript代码alert(‘hello‘)

        

        - 命名空间,快捷方式

        使用对象实现。

        经常使用的技巧是使用$快速引用命名空间。

            window.$=mynamespace;

            $.mymember;

 

        - 文件操作

        为了防范黑客,在javascript不能进行文件操作。FileSystemObject是ie提供的ActiveX控件,只能运行于ie浏览器下。

 

    22) DOCTYPE

    指明page使用的HTML版本。过去的HTML 2.0不支持table,HTML 3.2仅仅支持基本的css功能。

    近来HTML最常用的版本是HTML 4.01和XHTML 1.0。HTML4.01和XHTML1.0均包括三种标签

    Strict、Transitional、Frameset。Strict最严格,是最小集合。transitional是strict加上一些过时

    的元素。frameset是transitional加上frame支持。几个常用的格式

    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

    如果html page指明了正确的DOCTYPE,则browser的工作模式成为standards-compliant。如果没有指明版本或者DOCTYPE有错,则浏览器进入

    Quirks mode, 浏览器将老版本的浏览器行为来绘制page。比如ie8在Quirks mode下,使用ie5.5的方式绘制page。

    

    火狐浏览器显示了browser的工作模式。被称为Render Mode。tool->page info

    

 

    不幸的是,在有些浏览器中,甚至是有效的DOCTYPE或者无效的元素也会激发浏览器进入Quirk mode。

    所以对于跨浏览器,DOCTYPE和render mode很重要。

 

    简洁方法是使用<!DOCTYPE html>, 浏览器将自动选择standard mode。但html5好像不支持这种书写方式。

 

    23) 启动(启用)javascript(downloads and load web page)

    

    浏览器从服务端下载html page内容和执行javascript代码应该是异步进行。所以需要保证整个html page下载完后才能启动javascript。

    标准的方法是将window onload做为javascript的入口点。

        window.onload = init;  //init是入口函数

 

    24) javascript strict 模式

 

    使用strict模式告诉javascript进行更加严格的语法检查。比如检查潜在错误的代码,提出错误报告。提高安全和性能。警告用户未来不再

    支持的代码。

 

    ‘use strict‘;

 

    可以在脚本顶部书写一次,也可在需要的函数体中开始处书写。比如

    function init() {

    ‘use strict‘;

    alert(‘hello‘);

    }

 

 

  .9 jQuery

    

    0) 代码入口

$(document).ready(function(){

 alert(‘put code here‘);

});                                                                   //ie6 support

更加简洁方式

$(function(){

 alert(‘put code here‘);

});                                                                   //ie6 support

 

    1) 定位DOM

    无论id还是class或是tag,jquery返回的总是array-like对象。对于复杂的selector,jquery执行的顺序是从右向左。

    

    选择子功能至少支持到ie6。

    $("#maincontent");            //id

    $(".column");                      //class

    $("div");                              //tag

    $("p").length;                     //元素个数

    $("p").addClass("paragraph");            //addClass将在set上操作,自动loop,为set上所有元素执行addClass操作。

    $("div.main p>li a");   //复杂的selector

      

    2) jQury对ie支持

    jqury支持ie8的最后系列为1.X.X, 从jquery 2.0.0,不再支持ie旧版本。在html中使用宏注释包含正确的版本。

<!--[if lt IE 9]>

    <script src="jquery-1.9.0.js"></script>

<![endif]-->

<!--[if gte IE 9]><!-->

    <script src="jquery-2.0.0.js"><</script>

<!--<![endif]-->    

                                

    3) evet support

        

 

    4) 修改元素风格

    $(‘selector‘)返回的是一个array-like对象。

    使用css()函数可以取值和设置值。

        - 取值,只获得array-like中第一个对象的值。

            alert($(‘div‘).css(‘width‘));        //ie6

        - 设置,array-like中所有的对象都将被设置

  $(‘div‘).css(‘background-color‘,‘blue‘)    //至少支持ie6

  ,可以使用这种更加可是化效果

  $(‘div‘).css({

        "background-color":"red",

        "color":"black"

  })              //至少支持ie6

        

    5) 修改元素属性

 

    6) 替换元素文本

    使用$(‘selector‘).text(),和css()有相同的语义。当取数据时候,只能得到第一个元素的值,当设置值时候,所有对象的值都将被设置。

    text()操作的是元素中的文本属性,如果要操作html内容,使用

            $(‘Div‘).text(‘me‘)   //至少支持ie6

 

    7) 替换div中html内容

            $(‘div‘).html(‘<div style="border:1px solid green">me</div>‘)   //至少支持ie6

 

    8) 事件处理

    jquery中有两种方式支持事件注册,这两种方式均支持ie6。在jquery1.7+版本中使用的是on方式,之前老版本使用的是click()方式。

    on方式更新。和css()函数一样,它们均作用在arry-like中的所有object之上。

    $("div").on(‘click‘,function(){

        alert(‘new event mode on‘)

    });        //on,更新的方式jquery 1.7+支持方式。

    $("div").click(function(){

        alert(‘handler click()‘)

    });        //,老的事件处理方式。

    

    元素的hover经常使用,使用下列方法。

    $("div").on("mouseenter", function() { 

  alert("hovered over");

  }).on("mouseleave", function() {

  alert("hovered out")

    });           //ie6支持

    如果相同的处理代码,更快捷的方式是

    $("#commandButton").on("mouseenter mouseleave", function() {

        alert("hovered on or out");

    });    //ie6支持

 

    取消掉注册的事件处理函数,使用off()。

        $("div").off();     //取消掉div上所有的事件处理函数。ie6支持。

        $("div").off(‘click‘);    //仅仅取消掉click事件处理函数。ie6支持。

        

 

    9) 事件函数处理细节

    - 在事件处理函数中获取事件源元素信息。this

        在事件处理函数有预留变量this,它是javascript对象,但是在ie不同版本中,它有不同含义。

        $(this),将把this转变为jquery对象。

        在ie6中也支持的方法是从事件处理函数中的传入参数中读取event信息。在

 $("div").on("click",function(myevent){

  alert(myevent.target.id);

 });        //  ie6支持

 

javascript_tutorial 【转】

标签:

原文地址:http://www.cnblogs.com/wenhuan/p/4304731.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!