chapter1 javascript基础
1.1 变量类型和声明
javascript
里常用基本类型有:boolean,string 和
number,常用的类分别是:Boolean,String和Number,Array,Object.
声明变量用var,不能用关键字和保留字作变量名(关键字和保留字见附录A1).命名的最佳实践是使用匈牙利命名法.
基本类型的变量声明如下:
var iValue=”5” ; //声明并定义数值变量.
var sValue=”test”; //声明并定义字符变量.
var oText; //声明变量.
var bValue=true; //声明并定义布尔变量.
可以用typeof 函数检查变量的类型:
alert("iValue's type is:"+typeof(iValue));
alert("sValue's type is:"+typeof(sValue));
alert("oText's type is:"+typeof(oText));
alert("bValue's type is:"+typeof(bValue));
可以看到第三个语句中typeof(oText)的计算结果是undefined. 如果对象没有声明,或仅声明而没有初始化,那么它的值就是undefined.
用类声明变量的例子如下:
var oNumber=new Number(5);
var oNumber=new Number(5);
var oString=new String("test");
var oObject=new Object();
var oBoolean=new Boolean(true);
alert("oNumber's value is:"+oNumber.valueOf());
alert("oString's value is:"+oString.valueOf());
alert("oObject's value is:"+oObject.valueOf());
alert("oBoolean's value is:"+oBoolean.valueOf());
alert("oNumber's type is:"+typeof(oNumber));
alert("oString's type is:"+typeof(oString));
alert("oObject's type is:"+typeof(oObject));
alert("oBoolean's type is:"+typeof(oBoolean));
可以看到上例中,用类的声明方式来定义变量,调用类的valueOf函数后得到和例子1.1相同的变量值(除了声明为Object的变量).还可以发现上述例子中所有typeof函数运算的结果都是object.
在这种情况下你并不能检查出变量的具体类型,所以你必须使用instanceof 函数去判断变量类型:
alert("oNumber's class is Number?:"+(oNumber instanceof Number));
虽然用类声明变量能得到同样正确的结果,但在声明变量的时候,能够使用基本类型就尽量使用基本类型.
1.2 函数声明和调用
函数的声明和调用如下:
function doAdd(iNum1,iNum2){
//带返回值的函数.
return iNum1+iNum2;
}
function sayHi(sName){
//无返回值的函数.
alert("Hello,"+sName+" !");
}
alert(doAdd(1,2));
sayHi("Diego");
1.3 Array和Object
Array类似java的List,其长度是自动增长的,使用很方便.基本用法如下所示:
var aSample = new Array(); //声明方式一
aSample = []; //声明方式二
//对数组元素赋值
aSample[0]= 1;
aSample[1]="test";
//输出值
alert(aSample[0]);
alert(aSample[1]);
使用Object,你能够定义自己的类(以后会进一步讨论).在目前你只需要知道,它相当于java里的Map类型和VB里的Dictionary类型而供你使用:
var oSample =new Object(); //声明方式一
oSample = {}; //声明方式二
//将其作为Map对象使用.
oSample["name"]="Diego";
oSample["gendar"]="male";
//更方便的声明属性的方式.
oSample.city="Shenzhen";
//输出值
alert(oSample.name);
alert(oSample.gendar);
alert(oSample.city);
1.4 语句
流程控制语句,if-else 和 switch-case :
function getMax(iNum1,iNum2){
//顺带展示?的用法.
return iNum1>iNum2?iNum1:iNum2;
}
function getColor(sColor){
var sValue="";
switch (sColor){
case "FF0000":
sValue="Red";
break;
case "FFFFFF":
sValue="Black";
break;
default:
sValue="unknown";
}
return sValue;
}
常用的迭代语句有: for.. while , do-while ,有一个方便应用于Object类的语句 for ..in.. ,还有用于退出流程语句的continue 和break:
//for 语句用法.
var aSample = new Array(); //声明方式一
aSample = []; //声明方式二
//对数组元素赋值
aSample[0]= 1;
aSample[1]="test";
//输出值
for(var i=0;i<aSample.length;i++){
alert(aSample[i]);
}
//for in 语句用法.
var oSample =new Object(); //声明方式一
oSample = {}; //声明方式二
//将其作为Map对象使用.
oSample["name"]="Diego";
oSample["gendar"]="male";
//更方便的声明属性的方式.
oSample.city="Shenzhen";
//遍历对象属性
for (prop in oSample){
alert("prop's name is:"+prop);
}
//while 语句用法
var i=0;
while(i<5){
alert(aSample[i]);
i++;
}
//do-while,continue 和 break:
var k=0;
do{
alert(aSample[k]);
k++;
if(k<3){
alert("Loop continue:");
continue;
}else{
alert("Loop end:");
break;
}
}while(true)
Chapter2 浏览器的事件模型
2.1 事件机制
事件(event)表示浏览器或用户的行为.例如浏览器装载页面后的onload事件,用户单击鼠标的onclick事件或敲击键盘的onkeydown
事件.事件处理程序(event handler,也称为event
listener)表示与该事件相联系的处理函数.事件发生之后可以被多个事件处理程序所处理,这称为事件流(event
flow).不同的浏览器实现事件流的模型不一定相同,IE采用冒泡型机制,而DOM标准既采用捕获型也采用冒泡型机制.
所谓冒泡型机制,指事件在特定目标发生之后,依次沿着父元素外传.如下程序所示:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Sample2.1.1</title>
<style style="text/css">
.parent{width:350px;height:300px;background-color:red;}
.child{width:150px;height:100px;background-color:blue;}
</style>
<script>
//
function parentAlert(){
alert('This is parent div!');
}
function childAlert(){
alert('This is child div!');
}
function bodyAlert(){
alert('This is body div!');
}
</script>
</head>
<body onclick="bodyAlert();">
<div id="parentDiv" class="parent" onclick="parentAlert();">
<div id="childDiv" class="child" onclick="childAlert();">
</div>
</div>
</body>
</html>
你可以看到,事件从最内层的div发生之后,沿着层级依次上升,父div和顶层元素body都能捕获该事件并进行处理.
所谓捕获型机制和冒泡型正好相反,事件从最外层的元素发生,依次传到最内层元素,然后再传回最外层元素.由于各浏览器默认支持冒泡型机制,所以在这里不过多讨论捕获型事件流.
2.2 事件处理程序(event handler)
如下,可以在html元素指定事件处理程序,也可以用javascript代码指定:
<html>
<head>
<style type="text/css">
.divCls {width:150px;height:100px;background-color:#0000CC}
</style>
</head>
<script>
function clickListener1(){
alert("method1");
}
function clickListener2(){
alert("method2");
}
function attachAnotherFunc1(){
oEle=document.getElementById("oDiv");
oEle.onclick=clickListener2;
}
function attachAnotherFunc2(){
oEle=document.getElementById("oDiv");
oEle.onclick=function(){
alert("method3");
}
}
</script>
<body>
<div id="oDiv" class="divCls" onclick="clickListener1();"/><br><br><br><br><br><br><br><br><br><br>
<input type="button" value="Change listener to 2" onClick="attachAnotherFunc1();"/>
<input type="button" value="Change listener to 3" onClick="attachAnotherFunc2();"/>
</body>
</html>
还可以添加多个事件处理程序,但在IE和DOM中的处理不同:
IE:
[Object].attachEvent(“name_of_event_handler”,fnEventHandler);
[Object].detachEvent(“name_of_event_handler”,fnEventHandler);
DOM:
[Object].addEventListener(“name_of_event_handler”,fnEventHandler,bIsInCaptureTime); //bIsInCaptureTime表示捕获阶段.一般用false
[Object].removeEventListener(“name_of_event_handler”,fnEventHandler,bIsInCaptureTime);
例如:
oDiv.addEventListener(“click”,fnClick,false);
oDiv.removeEventListener(“click”,fnClick,false);
如此则可以将多个事件处理程序附加给对象.
2.3 事件对象
在事件发生的时候,事件对象(Event)会被创建.在IE,可以用如下方法取得事件对象:
var oEvent = window.event;
而在DOM中,你可以在调用函数时传入event关键字,或者在函数内取第一个参数:
var oEvent = arguments[0];
取得事件对象的目的是完成如下任务:
1) 检测事件发生时键盘鼠标的按键
2) 事件发生时对象的坐标(可以创建绚丽的动画效果)
事件对象有许多属性方法帮助你达到上述目标.可是IE和DOM的实现并不完全相同.
IE和DOM相似的属性有:
var sType=oEvent.type;//事件类型
var iKeyCode=oEvent.keyCode;//keydown或keyup事件中获得按键数值代码.
var bShift=oEvent.shiftKey;
var bAlt=oEvent.altKey;
var bCtrl=oEvent.ctrlKey; //是否按下shift,alt或ctrl键.
var iClientX=oEvent.clientX;
var iClientY=oEvent.clientY;//鼠标指针在客户端区域的位置.
var iScreenX=oEvent.screenX;
var iScreenY=oEvent.screenY;//鼠标指针在屏幕区域的位置.
IE和DOM不相似的属性方法有:
获取发生事件的对象:
var oTarget=oEvent.srcElement;//IE
var oTarget=oEvent.target; //DOM
阻止事件的默认行为(例如禁止鼠标右键)
oEvent.returnValue=false; //IE
oEvent.preventDefault(); //DOM
阻止事件冒泡
oEvent.cancelBubble=true;//IE
oEvent.stopPropagation();//DOM
Chater 3 Document和浏览器
3.1 访问文档节点的常用函数
最常用访问文档对象的函数有:document.getElementById 和 document.getElementsByName , 如下例子:
function testSelect(){
var aOpts = document.getElementsByName("chkBox");
for(var i=0;i<aOpts.length;i++){
if(aOpts[i].checked){
alert("Checkbox checked and it's value is:"+aOpts[i].value);
}
}
}
function testInput(){
var oInput = document.getElementById("inpText");
if(oInput.value==""){
alert("Please input something.");
}else{
alert("You input "+oInput.value);
}
}
<table>
<tr><td>First checkbox</td><td><input type="checkbox" name="chkBox" value="1"/></td></tr>
<tr><td>Second checkbox</td><td><input type="checkbox" name="chkBox" value="2"/></td></tr>
</table>
<br>
<input type="text" id="inpText" />
<br>
<input type="button" value="testSelect" onClick="testSelect();"/>
<input type="button" value="testInput" onClick="testInput();"/>
3.2 操作页面元素
添加元素: document.createElement(tagName);
替换元素: document.replaceChild(oNew,oOld);
添加文本节点:document.createTextNode(text);
添加子节点:appendChild(oElement);
添加HTML: oElement.innerHTML=””;
添加文本:对于IE,用oElement.innerText=”” ,对基于DOM的浏览器,用oElement.textContext=””
元素是否有子元素:oElement.hasChildNode
元素的第n个子元素:oElement.childNodes[n-1]
在以下程序你可以看到这些方法的实际应用:
<script type="text/javascript">
function addButton() {
var oDiv = document.getElementById("btnDiv");
if(oDiv.hasChildNodes()){
return;
}
var oInput = document.createElement("input");
oInput.type="button";
oInput.value="NewButton";
oDiv.appendChild(oInput);
oDiv = document.getElementById("txtDiv");
var oText = document.createTextNode("add button1");
oDiv.appendChild(oText);
alert("Added button1");
}
function addButton2(){
var oDiv = document.getElementById("btnDiv");
if(oDiv.hasChildNodes()){
return;
}
oDiv.innerHTML="<input type='button' value='NewButton2'/>";
oDiv = document.getElementById("txtDiv");
if(window.event){
oDiv.innerText="add button2";
}else{
oDiv.textContent="add button2";
}
alert("Added button2");
}
function replaceButton(){
var oDiv = document.getElementById("btnDiv");
if(!oDiv.hasChildNodes()){
return;
}
var oInput = document.createElement("input");
oInput.type="button";
oInput.value="Replaced button";
oDiv.replaceChild(oInput,oDiv.childNodes[0]);
alert("I replaced button!");
}
function removeButton(){
var oDiv = document.getElementById("btnDiv");
if(!oDiv.hasChildNodes()){
return;
}
oDiv.innerHTML="";
oDiv = document.getElementById("txtDiv");
oDiv.removeChild(oDiv.childNodes[0]);
alert("Removed button");
}
</script>
<body>
<div id="btnDiv"></div><div id="txtDiv"></div>
<input type="button" value="addButton" onclick="addButton();"/>
<input type="button" value="addButton2" onclick="addButton2();"/>
<input type="button" value="replaceButton" onclick="replaceButton();"/>
<input type="button" value="removeButton" onclick="removeButton();"/>
</body>
3.3 创建表格
可以用上述DOM方法来创建表格,也可以用特定的表格方法来进行创建.这些方法包括:
<table/>元素中的方法:
rows:表格中所有行的集合.
deleteRow(position):删除某行.
insertRow(position):插入新行.
<tbody/>中的方法:
rows:表格中所有行的集合.
deleteRow(position):删除某行.
insertRow(position):插入新行.
<tr/>中的方法:
cells:<tr/>元素中所有单元格的集合.
deleteCell(position):删除单元格.
insertCell(position):插入单元格.
演示代码如下:
function createTable(){
var oTable=document.createElement("table");
oTable.border="1";
oTable.width="500px";
var oTbody=document.createElement("tbody");
oTable.appendChild(oTbody);
oTbody.insertRow(0);
oTbody.rows[0].insertCell(0);
oTbody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1.1"));
oTbody.rows[0].insertCell(1);
oTbody.rows[0].cells[1].appendChild(document.createTextNode("Cell 1.2"));
oTbody.insertRow(1);
oTbody.rows[1].insertCell(0);
oTbody.rows[1].cells[0].appendChild(document.createTextNode("Cell 2.1"));
oTbody.rows[1].insertCell(1);
oTbody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2.2"));
document.body.appendChild(oTable);
}
3.4 性能和文档碎片
当元素添加到document.body或其子元素之后,页面就会自动刷新.如果有大量的添加/删除操作,就有可能引起性能问题.此时就要用到
createDocumentFragment方法,先在文档碎片上进行添加操作,然后一次性添加到document,这样,文档仅刷新一次.
var arrText = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth"];
var oFragment = document.createDocumentFragment();
for (var i=0; i < arrText.length; i++) {
var oP = document.createElement("p");
var oText = document.createTextNode(arrText[i]);
oP.appendChild(oText);
oFragment.appendChild(oP);
}
document.body.appendChild(oFragment);
3.5 浏览器对象(待续)
Chapter : OO 和模式
类的定义
定义类的属性方法很简单,但要注意,这种方式定义的属性其实是公开的:
<script>
var Employee=function(name,title){
this._name=name;
this._title=title;
};
Employee.prototype.getName=function(){
return this._name;
};
Employee.prototype.setName=function(n){
this._name=n;
};
var oH = new Employee("test");
alert(oH.getName());
oH.setName("A man");
alert(oH.getName());
</script>
类的继承
<script>
var Employee=function(name,title){
this._name=name;
this._title=title;
};
Employee.prototype.getName=function(){
return this._name;
};
Employee.prototype.getTitle=function(){
return this._title;
};
var Engineer = function(name,title,major){
Employee.call(this,name,title);
this._major=major;
};
Engineer.prototype=new Employee();
Engineer.prototype.getMajor=function(){
return this._major;
};
var emp1 = new Employee("Chen","Tester");
alert("emp1.name:"+emp1.getName());
alert("emp1.title:"+emp1.getTitle());
var emp2 = new Engineer("Diego","Engineer","CS");
alert("emp2.name:"+emp2.getName());
alert("emp2.title:"+emp2.getTitle());
alert("emp2.major:"+emp2.getMajor());
</script>