javascript_tutorial 【转】

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支持

    时间: 2024-10-28 12:44:38

    javascript_tutorial 【转】的相关文章

    Web学习路线

    第一步:学好HTML 学习HTML5 HTML Dog (http://htmldog.com/) HTML入门指南 (http://www.w3.org/MarkUp/Guide/) W3C HTML学习教程 (http://www.w3schools.com/html/) 第二步:学好CSS HTML Dog  (http://htmldog.com/) CSS禅意花园 (http://www.csszengarden.com/)已有中文版图书. 第三步:学好JavaScript 先学习Ja