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