Differences between revisions 4 and 9 (spanning 5 versions)
Revision 4 as of 2006-10-02 13:07:47
Size: 11517
Editor: zuroc
Comment:
Revision 9 as of 2006-10-13 15:27:16
Size: 39712
Editor: zuroc
Comment:
Deletions are marked like this. Additions are marked like this.
Line 4: Line 4:
Javascript 绝对简明手册 Javascript 绝对简明手册(写作中!!!!!!!)
Line 10: Line 10:
Javascript绝对简明手册,初学必备!
     --For Ajax
Javascript和C++,Java,Python一样是一种博大精深的编程语言.
      --For Ajax
Line 17: Line 17:
参考:Ajax基础教程 Javascript权威指南
参考:
Ajax基础教程
Javascript权威指南(中文第4版)
JavaScript.The.Definitive.Guide.5th.Edition
Line 25: Line 27:
 -- 欢迎转载,但请保留引用网址以获得更新
= 序言 =
无论是Ajax,还是XUL(firefox的界面就是用它写的),还是Google桌面,Javascript无处不在
Line 29: Line 34:
js_0001.png js_0000.png
Line 39: Line 44:

= 语言 =

=
= 如何嵌入网页? ==
=== 写在网页中 ===
强烈建议学习时便学边调试
= 如何嵌入网页? =
== 写在网页中 ==
Line 45: Line 48:
<script language="JavaScript"> <script type="text/javaScript">
Line 50: Line 53:
=== 在链接上使用伪协议 === == 在链接上使用伪协议 ==
Line 53: Line 56:
=== 使用独立的js脚本 === == 使用独立的js脚本 ==
Line 59: Line 62:

= 语言核心 =
Line 124: Line 129:
 * NaN 或 Number.NaN 非数字的值  * NaN 或 Number.NaN 非的值
Line 132: Line 137:
=== 对象 ===
创建
=== 基于对象 ===
==== 创建 ====
Line 164: Line 169:

==== 构造函数 ====
{{{
function Rectangle(w,h)//构造函数.不要返回值,因为返回值会使this失效
{
 this.width=w;
 this.height=h;
}
var rect1=new Rectangle(2,4);//创建对象

}}}

==== 成员函数 ====
{{{
function Rectangle_area(){return this.width * this.height;}//声明函数

function Rectangle(w,h)
{
this.width=w;this.height=h;

this.area = Rectangle_area;//关联函数为成员函数
}

var r=new Rectangle(3,2);
r.area();//返回6
}}}

==== 继承 ====
 * Javascript的类都自动继承了原型对象 Object.prototype
 * 继承的属性为只读的,既子类不可以给继承的属性赋值
 * 子类的同名属性/函数将覆盖父类的同名属性/函数
 * String和Date等内部类也有原型对象

{{{
//定义一个父类
function Complex(real , imaginary){
 this.x=real;
 this.y=imaginary;
}

//为父类添加一个方法,通过定义父类原型prototype的函数
//该方法同时覆盖了Object.prototype中的同名函数
Complex.prototype.toString=function(){
 return this.x+"+"+this.y+"j";
}

//定义一个Complex函数,该函数不会被继承(这时不要加this了)
Complex.magnitude=function()
{
 return Math.sqrt(x*x+y*y);
}

//定义一个子类
function MoreComplex(real , imaginary){
 this.x=real;
 this.y=imaginary;
}

//继承父类,注意这时MoreComplex的构造函数被父类的构造函数覆盖
MoreComplex.prototype=new Complex(0,0);

//明确指定,使MoreComplex使用自己的构造函数
MoreComplex.prototype.constructor=MoreComplex;

//定义子类自己的函数
MoreComplex.prototype.swap=function(){
 var tmp=this.x;
 this.x=this.y;
 this.y=tmp;
}

a=new MoreComplex(11,33);

alert(a);//自动调用Complex.toString()
a.swap();
alert(a);
}}}

==== 公共基类的属性 ====
Object.prototype是所有类的公共基类
 * constructor属性 构造器,由于构造函数确定了一个对象的类型,可以用如下代码确定一个对象的类型
 {{{
if((typeof o=="object" )&& o.constructor == Date)//...........
 }}}
但不能保证constructor属性总是存在,类的创建者可以指定一个对象来取代原型的构造器,而指定的对象可以没有 constructor
(PS:此句抄书,我看不懂)

 * toString() 返回一个字串,内容为对象的值或类型.
 
 默认的toString对于对象返回
{{{
[object class]
//class为类名,如自定义对象为Object
//类似的还有Array,Function,Date,Math,Error,Window,Document,Form
}}}
由于可以重载toString.所以,如果你想明确的调用默认的toString来获得类型信息,你可以这样
{{{
Object.prototype.toString.apply(x);
}}}

 * toLocaleString() Object默认的toLocaleString返回值和toString相等;Array,Date,Number都绑定了自己的toLocaleString

 * valueof() Object默认定valueof不执行任何转换,Number和Boolean等有自定义的valueof().
 
 当你自定义了valueof时需要注意的是:valueOf()优先级比toString()高,所以,你常不得不明确的调用toString()

 * hasOwnProperty()
 {{{
var o = new Object();
o.hasOwnProperty("undef"); //false:没有定义该属性
o.hasOwnProperty("toString"); //false:该属性是继承的

Math.hasOwnProperty("cos");//true:Math有cos属性
 }}}

* propertylsEnumerable()
一个属性如果可以由for...in循环枚举出来就返回true,否则,返回false
{{{
var o = {x:1};
o.propertylsEnumerable("x");//true
o.propertylsEnumerable("y");//false,无该属性
o.propertylsEnumerable("valueOF");//false,该属性不可枚举
}}}

 * isPrototypeOf()
 调用该函数的对象如果是参数的原型,就返回true
 {{{
 var o=new Object();
 Object.prototype.isPrototypeOf(o);
 //true,o.constructor == Object

 Object.isPrototypeOf(o);//false
 o.isPrototypeOf(Object.prototype);//false

 Function.prototype.isPrototypeOF(Object);
 //true:Object.constructor == Function
}}}
Line 167: Line 306:
创建 ==== 创建 ====
Line 192: Line 331:

==== 数组的函数 ====
* join() 把所有的元素转换为字串,参数作为分隔符(默认分隔符是 ,)
{{{
var a=[1,2,3];
a.join();//1,2,3
a.join(" : ");//1 : 2 : 3
}}}
* reverse() 对数组反向排序
* sort() 默认按照UTF-8码的顺序排序,可以传一个参数,如果返回一个小于等于0的数,第1个参数出现在第2个参数前面,反之同理.
{{{
 function randOrd(){
return (Math.round(Math.random())-0.5);
}

anyArray = new Array('3','a','5','F','x','47');
anyArray.sort( randOrd ); //把数组乱序排列
}}}

* concat() 返回一个数组,包含了原数组和参数
{{{
anyArray = new Array(47,33);

anyArray.concat(8,99,88 );
//[47,33,8,99,88]

anyArray.concat([8,99],[88,53] );
//[47,33,8,99,88,53],会自动把参数中数组拆包一层

anyArray.concat(2,[3,[4,5]]);
//[47,33,2,3,[4,5]],拆包只拆一层
}}}

* slice() 返回一个数组的切片,返回规则如下
{{{
var a = [1,2,3,4,5]
a.slice(0,3); //返回a[0]至a[2],即[1,2,3]
a.slice(3); //返回a[3]至结尾,即[4,5]
a.slice(1,-1);//返回a[1]至最后一个元素[2,3,4]
a.slice(-3,-2);//返回[3]
}}}

* splice() 可以删除/添加原数组元素,同时返回删除的值
{{{
var a = [1,2,3,4,5,6,7];
a.splice(4);
//删除a[4]至结尾,同时返回删除的值,即a=[1,2,3,4],返回[5,6,7]

var a = [1,2,3,4,5,6,7];
a.splice(3,3,"a","b");
//从a[3]开始,删除3个元素(包括a[3]),同时在从a[3]开始插入"a","b"作为新的元素,返回删除的值
//即a=[1,2,3,"a","b",7],返回[4,5,6]

var a = [1,2,3,4,5,6,7];
a.splice(3,0,["a",2],"k");
//返回[],a=[1,2,3,["a",2],"k",4,5,6,7] ,splice()不会对添加的数组拆包
}}}

* push()和pop()
{{{
var stack=[];

stack.push(1,2);//stack=[1,2],return 2(2表示数组长度)

stack.pop();//stack=[1],return 2

stack.push(3);//stack=[1,3],return 2(2表示数组长度)

stack.pop();//stack=[1],return 3

stack.push([4,5]);//stack=[1,[4,5]],return 2

stack.pop();//stack=[1],return [4,5]

stack.pop();//stack=[],return 1
}}}

* unshift()和shift()
和push()和pop()类似,不过是在数组的头进行操作
{{{
var a=[2];
a.unshift(1);
//a=[1,2]
//IE(包括IE7)和标准的规定返回值却不同,Gecko/Opera 中返回值为新数组的长度,而 IE 中没有返回值,也就是返回值是 undefined。因此,编程时不要依赖这个返回值。

a.unshift(3,[4,5]);//a=[3,[4,5],1,2]

a.shift();
//返回3
}}}

* toString()
toString等价于不加参数的join
Line 272: Line 504:
//TODO p133 返回函数声明中的参数的个数,通过arguments.callee.length访问
{{{
//一个检查参数是否相符的函数
function check(args){
 var actual=args.length;
 var expected=args.callee.length;
 if(actual!=expected){
  throw new Error("Wrong number of arguments");
 }
}

function f(x,y)
{
 check(arguments);
 return x+y;
}
}}}
Line 283: Line 531:
=== 函数的静态变量 ===
类似在C++函数中声明一个static变量
{{{
uniqueInteger.counter=0;//静态变量
function uniqueInteger(){//每个返回一个不同的数
 return uniqueInteger.counter++;
}
}}}
Line 446: Line 701:
//用于数组
Line 449: Line 705:
//用于对象,比"."运算符的优势是其要取的属性名可以动态生成
Line 507: Line 764:


== throw / try...catch...finally ==
throw用来抛出异常,异常对象通常是一个Error对象或其子类型
{{{
function factorial(x){
if(x<0)throw new Error("x must not be negative");//x是负数就抛出异常
return x;
}
}}}

try...catch...finally捕捉异常
{{{
try{
//代码
}
catch(e)
{
//仅当try块抛出异常,才会执行,e为异常实例
//这个块可以处理异常,也可以什么都不做
}
finally{
//无论是否有异常,这个块中的语句都将被执行
}
}}}

== 正值表达式 ==
//todo

= 浏览器中的Javascript概览 =

 * window对象代表显示浏览器的窗口,document对象代表文档中窗口.

 * 事件触发器:html元素对事件进行响应(不要放在<script>块中)
 
<input type="checkbox" name="opts" value="ignore-case" onclick="ignore-case=this.checked;">

其中onclick就是事件触发器,常用的还有onmousedown,onmouseup,onmouseover,onmouseout,onchange,onsubmit,onreset

 * 定义函数的js文件一般放在head区
 
 * <body>和<frameset>的onload在文档被完全加载完成时触发,onunload在文档被卸载时触发


== window对象 ==

window是全局对象,它的函数/属性一般可以不加前缀直接调用。有时为了避免名字冲突,可以加window前缀

=== 简单的对话框 ===
注意:对话框中显示的是纯文本.
* alert() 见图js_0001.png

* confirm() 见图js_0002.png

{{{
if(confirm("看我的非技术Blog吗?\n\n我写了不少诗哦 :)")) location.replace("http://www.cnweblog.com/zuroc/");
}}}

* prompt() 见图js_0003.png

{{{
n=prompt("你叫什么名字呢?","");//第二个参数是输入的默认值

document.write("<h1>你好, "+n+"!<br/>我叫张沈鹏.</h1>");
}}}



=== 状态栏 ===
* status 浏览器状态栏的显示文本
* defaultStatus 浏览器状态栏显示文本的默认值
该属性在firefox默认关闭,不介绍了

=== 定时器 ===
* setTimeout() 安排一个JavaScript代码在指定的时间后执行
* clearTimerout() 取消setTimeout的执行
* setInterval() 每隔指定的时间调用指定的函数
* clearInterval() 取消Interval的执行
{{{
function hi(){alert("hi!");}
setInterval("hi()",2000);//2000ms=2s
}}}

=== 错误处理onerror ===
只要给这个属性赋了一个函数,那么这个窗口只要发生了javascript错误,该函数就会被调用.传给错误处理函数的参数有三个,第一个是错误类型,第二个是引发错误的js脚本的Url,第三是发生错误的行号.

如果onerror返回true,它将屏蔽系统的错误处理程序
{{{
//如果你不想错误消息打搅用户,无论你的代码有多Bug
window.onerror = function(){return true;}
//不过,不建议你这样做
}}}

=== 浏览器信息navigator ===
包含了浏览器的信息

* appName Web浏览器的名称
* userAgent 浏览器在USER-AGENT HTTP标题中发送的字符串,通常包含了appName和appVersion
* platform 平台,如Win32
{{{
//一个简单浏览器探测器
var browser = {
    version: parseInt(navigator.appVersion),
    isNetscape: navigator.appName.indexOf("Netscape") != -1,
    isMicrosoft: navigator.appName.indexOf("Microsoft") != -1
};
}}}


=== 屏幕screen ===
* width,height 分辨率的宽和高
* availWidth , availHeight 去除了任务栏这样的特性的宽和高
* colorDepth 屏幕的色深
见例子1_5.html

=== 打开窗口open ===
{{{
//注意,直接弹出窗口容易被浏览器广告拦截了
window.open("http://www.cnweblog.com/zuroc/","窗口名","width=200,height=200,status=yes,resizable=yes");
//具体属性希望那位大哥可以帮我列一下
//被打开的窗口可以用opener引用父窗口,如果是用户自己打开的opener为null
//用open时一般要明确加上window前缀,因为Document也有open属性
}}}
见例子1_5.html

window.close可以关闭你用javascript打开的窗口

=== 移动窗口/改变大小moveTo , moveBy , resizeTo , resizeBy ===
* moveTo 把窗口左上角移到指定的坐标
* moveTo 把窗口相对现在的位置移动指定的象素
* resizeTo 按照绝对大小调整窗口
* resizeBy 按照相对大小调整窗口
见例子1_5.html

=== 焦点控制 focus 和 blur ===
* focus() 将焦点给指定窗口,同时把窗口移动到最前端,使窗口可见,当open()打开窗口,如果第二个参数指定的窗口名已经存在,open不会自动使那个窗口可见,这时就要调用该函数
* blur() 放弃焦点,这时窗口将被至于窗口队列的最后(这就什么sohu背投广告的原理吧)
见例子1_5.html


=== 文档滚动 ===
* scrollBy() 相对当前位置滚动指定的象素
* scrollTo() 将文档滚动到一个绝对位置,文档的左上角的坐标为(0,0)

=== 当前地址栏 location ===
它本身代表当前窗口的URL,它还有各个属性如下
* location.protocol 用的协议,如在本地直接打开网页则是file:
* location.host 用的域名
* location.pathname 域名后的网址路径.如"/F:/Javascript绝对简明教程/example/test.html "
* location.search 查询的内容
* location.reload() 刷新当前线
* location.replace() 跳转到指定的URL,与直接给location赋值不同的是,这样不会在浏览历史中留下记录(也就是后退不会到该页)
{{{
//一个把URL串中查询内容解析为键值对的函数
function getArgs(){
 var args=new Object;
 var query=location.search.substring(1);//或取查询串
 var pairs=query.split(","); //在逗号处分开
 for(var i=0;i<pairs.length;i++){
  var pos=pair[i].indexOf("=");
  var argname=pairs[i].substring(0,pos);
  var value=pairs[i].substring(pos+1);
  args[argname]=decodeURIComponent(value);
 }
 return args;
}
//调用可以这样
var args=getArgs();
if(args.x)x=parseInt(args.x);
}}}

{{{
//检查浏览器是否支持DOM,如果不支持则跳转
if (!document.getElementById) location = "staticpage.html";
}}}

=== 历史History ===
脚本不能真正访问History数组,但是可以调用它的函数
* back() 后退
* forward() 前进
* go() 后退/前进指定的页数

=== 框架 ===
一个窗口可以用frames,parent,top引用其他属性

每个窗口有一个frame[]数组(如果一个窗口没有框架则它的frame[]是空的,frames.length==0),frame[0]表示它的第一个子框架,如此类推

每个窗口还有一个parent属性,为包含这个窗口的window对象,这样一个窗口通过诸如parent.frames[1]的方式,引用他的兄弟窗口

对于顶层窗口,有parent==window

对于框架中的框架,可以用top直接引用最顶层的窗口

见图js_0004.png

框架可以用name指定名字,这个名字可以为链接的target值.当这个链接被激活的时候会在指定的框架中显示内容

在javascript也可以通过名字访问框架,如一个框架如下
 {{{
<frame name="table_of_contents" src="top.html">
 }}}
则可以通过parent.table_of_contents方法访问该框架

需要注意的在一个框架定义的函数/变量,在另一个框架中要通过框架名来调用

见例1_6.html

== 文档Documents ==

=== 基本常识 ===

==== 属性 ====
* bgColor , fgColor 文档背景色,前景色(不赞成使用的属性)
* lastModified 文档的最后修改时间
{{{
//可以在文档末加入
  最后更新:<script>document.write(document.lastModified);</script>
}}}
* referrer 如果该属性存在,则返回一个链接,表示用户是由哪个网页链接到该页的
{{{
<script>
//如果你想其他由网站链接到该页的用户先访问你的首页
if (document.referrer == "" || document.referrer.indexOf("mysite.com") == -1)
    window.location = "http://home.mysite.com";
</script>
}}}
==== 数组 ====
* title 文档标题
* URL 等同于window的location.href
* anchors[] 所有有name属性的a标记
* forms[] 所有form标记,每个form还有一个element[]数组
* images[] 所有的<img>标签,可以改变它的src属性来改变图象
* link[] 文档中所有的超链接,和window的location一样有protocol, hostname,pathname等属性


{{{
<form name="f1"><input type="button" value="Push Me" name="zipcode"></form>

//如果一个元素有name还可以这样访问
document.forms.f1
document.forms["f1"]

//对于它的子元素可以这样访问
document.shipping.zipcode

//如果有重名的元素,以上的引用方法将返回一个数组
}}}

==== 事件设置 ====
{{{
<form name="myform" onsubmit="return validateform();">...</form>
//以上事件设置在javascript中的等效代码如下,注意,javascript中的所有事件名都是小写的
document.myform.onsubmit = validateform;
}}}

=== DOM树 ===
见图js_0005.png
对于树上的节点可以用firstChild, lastChild, nextSibling, previousSibling, 和 parentNode属性来历遍

appendChild(), removeChild(), replaceChild(), 和 insertBefore() 可以在文档中动态的添加/删除节点

每个节点都有一个nodeType属性,表明了它的类型
{{{
Interface nodeType constant nodeType value

Element Node.ELEMENT_NODE 1
Text Node.TEXT_NODE 3
Document Node.DOCUMENT_NODE 9
Comment Node.COMMENT_NODE 8
DocumentFragment Node.DOCUMENT_FRAGMENT_NODE 11
Attr Node.ATTRIBUTE_NODE 2
}}}

getAttribute(), setAttribute(), removeAttribute() 可以用来操作属性,标准的Html元素的属性也可以通过这种方式访问
getAttributeNode()可以返回一个Attr对象,它有一个specified属性,可以判断文档是否指定了该属性,或判断它是否是默认值

{{{
//历便一个DOM树
function countTags(n) { // n is a Node
    var numtags = 0; // Initialize the tag counter
    if (n.nodeType == 1 /*Node.ELEMENT_NODE*/) // Check if n is an Element
        numtags++; // Increment the counter if so
    var children = n.childNodes; // Now get all children of n
    for(var i=0; i < children.length; i++) { // Loop through the children
        numtags += countTags(children[i]); // Recurse on each one
    }
    return numtags; // Return the total
}
alert('This document has ' + countTags(document) + ' tags');
}}}

==== 搜索文档的特定元素 ====
* document.getElementsByTagName() 返回指定标签名的数组
{{{
//虽然只有一个body,还是返回一个数组
document.getElementsByTagName("body")[0];

//有多少表格
var tables = document.getElementsByTagName("table");
alert("This document contains " + tables.length + " tables");

}}}

* document.getElementById() 返回id号为指定值元素,因为每个id应该的独一无二的,所以该方法最多返回一个元素
{{{
<p id="specialParagraph">
var myParagraph = document.getElementById("specialParagraph");
}}}

* document.getElementsByName() 返回name属性为指定值的元素的数组
{{{
// Find <a name="top">
var link = document.getElementsByName("top")[0];
// Find all <input type="radio" name="shippingMethod"> elements
var choices = document.getElementsByName("shippingMethod");
}}}

==== 动态改变文档内容 ====
* Document.createElement()
* Document.createTextNode()
* Node.appendChild()
* Node.insertBefore()
* Node.replaceChild()


==== 一个动态改变Document内容的演示 ====
{{{
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>test</title>
<script>
function sortkids(e) {
     // This is the element whose children we are going to sort
     if (typeof e == "string") e = document.getElementById(e);

     // Transfer the element (but not text node) children of e to a real array
     var kids = [];
     for(var x = e.firstChild; x != null; x = x.nextSibling)
         if (x.nodeType == 1 /* Node.ELEMENT_NODE */) kids.push(x);

     // Now sort the array based on the text content of each kid.
     // Assume that each kid has only a single child and it is a Text node
     kids.sort(function(n, m) { // This is the comparator function for sorting
                   var s = n.firstChild.data; // text of node n
                   var t = m.firstChild.data; // text of node m
                   if (s < t) return -1; // n comes before m
                   else if (s > t) return 1; // n comes after m
                   else return 0; // n and m are equal
               });

     // Now append the kids back into the parent in their sorted order.
     // When we insert a node that is already part of the document, it is
     // automatically removed from its current position, so reinserting
     // these nodes automatically moves them from their old position
     // Note that any text nodes we skipped get left behind, however.
     for(var i = 0; i < kids.length; i++) e.appendChild(kids[i]);
}
</script>
</head>

<body>


<ul id="list"> <!-- This is the list we'll sort -->
<li>one<li>two<li>three<li>four <!-- items are not in alphabetical order -->
</ul>
<!-- this is the button that sorts the list -->
<button onclick="sortkids('list')">Sort list</button>
</body>
</html>
}}}

==== 一个把文章中字母都变为大写的演示 ====
{{{
// This function recursively looks at Node n and its descendants,
// converting all Text node data to uppercase
function upcase(n) {
    if (n.nodeType == 3 /*Node.TEXT_NODE*/) {
        // If the node is a Text node, change its text to uppercase.
        n.data = n.data.toUpperCase();
 //你也可以用appendData(), insertData(), deleteData(), replaceData()来更改数据
    }
    else {
        // If the node is not a Text node, loop through its children
        // and recursively call this function on each child.
        var kids = n.childNodes;
        for(var i = 0; i < kids.length; i++) upcase(kids[i]);
    }
}
}}}

==== 把指定标签改为粗体 ====
{{{

<script>
// This function takes a Node n, replaces it in the tree with an Element node
// that represents an HTML <b> tag, and then makes the original node the
// child of the new <b> element.
function embolden(n) {
    if (typeof n == "string") n = document.getElementById(n); // Lookup node
    var b = document.createElement("b"); // Create a new <b> element
    var parent = n.parentNode; // Get the parent of the node
    parent.replaceChild(b, n); // Replace the node with the <b> tag
    b.appendChild(n); // Make the node a child of the <b> element
}
</script>

<!-- A couple of sample paragraphs -->
<p id="p1">This <i>is</i> paragraph #1.</p>
<p id="p2">This <i>is</i> paragraph #2.</p>
<!-- A button that invokes the embolden() function on the element named p1 -->
<button onclick="embolden('p1');">Embolden</button>


}}}

==== 更改属性 ====
{{{
var headline = document.getElementById("headline"); // Find named element
headline.setAttribute("align", "center"); // Set align='center'
}}}

==== 临时容器DocumentFragment ====
 DocumentFragment是一个用来装载DOM对象的临时容器,将他写入文档其实是将它的子元素写入节点
 {{{
// 翻转元素
function reverse(n) {
    // Create an empty DocumentFragment as a temporary container
    var f = document.createDocumentFragment();
    // Now loop backward through the children, moving each one to the fragment.
    // The last child of n becomes the first child of f, and vice-versa.
    // Note that appending a child to f automatically removes it from n.
    while(n.lastChild) f.appendChild(n.lastChild);

    // Finally, move the children of f all at once back to n, all at once.
    n.appendChild(f);
}
}}}
 
 ==== 直接插入Html代码innerHTML ====
 虽然不是W3C的标准,但是事实上的标准,类似的还有outerHTML, innerText, 和outerText
 {{{
var table = document.createElement("table"); // Create the <table> element
table.border = 1; // Set an attribute
// Add a Name|Type|Value header to the table
}}}

==== 选中内容 getSelection ====
还不是标准,但还是可用的,参考
http://www.quirksmode.org/js/selected.html
{{{
Hi , everybody . My name is Zsp .
function getSelectedText() {
    if (window.getSelection) {
        // This technique is the most likely to be standardized.
        // getSelection() returns a Selection object, which we do not document.
        return window.getSelection().toString();
    }
    else if (document.selection) {
        // This is the IE-specific technique.
        // We do not document the IE selection property or TextRange objects.
        return document.selection.createRange().text;
    }
    //现在可以省略了
    else if (document.getSelection) {
        // This is an older, simpler technique that returns a string
        return document.getSelection();
    }
}
}}}
{{{
//一个实际使用的演示
<a href="javascript:
    var q;
    if (window.getSelection) q = window.getSelection().toString();
    else if (document.getSelection) q = document.getSelection();
    else if (document.selection) q = document.selection.createRange().text;
    void window.open('http://en.wikipedia.org/wiki/' + q);
">
Look Up Selected Text In Wikipedia
</a>
}}}

=== CSS ===

{{{
//一个用来隐藏广告代码的演示
var imgs = document.getElementsByTagName("img"); // Find all images
for(var i = 0; i < imgs.length; i++) { // Loop through them
    var img=imgs[i];
    if (img.width == 468 && img.height == 60) // If it's a 468x60 banner...
        img.style.visibility = "hidden"; // hide it!
}
}}}

* javascript与css的名字映射,如font-family映射为fontFamily,诸如此类.另外css中的float映射为cssFloat,如此类推
{{{
e.style.position = "absolute";
e.style.fontFamily = "sans-serif";
e.style.backgroundColor = "#ffffff";
e.style.left = "300px";
e.style.margin = topMargin + "px " + rightMargin + "px " +
                 bottomMargin + "px " + leftMargin + "px";
}}}

==== 当前的CSS设置 ====
W3C规定了getComputedStyle()函数来获取CSS元素的经过各种效果复合过后的当前值

但是IE不支持标准,但它有每个元素都有一个currentStyle属性,可以取得同样的效果
{{{
//一段兼容的代码
<p>
Look Up Selected Text In Wikipedia
</p>

<script>
var p = document.getElementsByTagName("p")[0]; // Get first paragraph of doc
var typeface = ""; // We want its typeface
if (p.currentStyle) // Try simple IE API first
    typeface = p.currentStyle.fontFamily;
else if (window.getComputedStyle) // Otherwise use W3C API
    typeface = window.getComputedStyle(p, null).fontFamily;
alert(typeface);
</script>
}}}

==== 指定样式表 ====

{{{
<head>
<!-- Here we define four stylesheets, using <link> and <style> tags. -->
<!-- Two of the <link>ed sheets are alternate and so disabled by default. -->
<!-- All have id attributes so we can refer to them by name. -->
<link rel="stylesheet" type="text/css" href="ss0.css" id="ss0">
<link rel="alternate stylesheet" type="text/css" href="ss1.css"
      id="ss1" title="Large Type">
<link rel="alternate stylesheet" type="text/css" href="ss2.css"
      id="ss2" title="High Contrast">
<style id="ss3" title="Sans Serif">
body { font-family: sans-serif; }
</style>

<script>
// This function enables or disables a stylesheet specified by id.
// It works for <link> and <style> elements.
function enableSS(sheetid, enabled) {
    document.getElementById(sheetid).disabled = !enabled;
}
</script>
</head>
<body>

<!-- This is a simple HTML form for enabling and disabling stylesheets -->
<!-- It is hardcoded to match the sheets in this document but could be -->
<!-- dynamically generated using stylesheet titles instead. -->
<form>
<input type="checkbox" onclick="enableSS('ss0', this.checked)" checked>Basics
<br><input type="checkbox" onclick="enableSS('ss1', this.checked)">Large Type
<br><input type="checkbox" onclick="enableSS('ss2', this.checked)">Contrast
<br><input type="checkbox" onclick="enableSS('ss3', this.checked)" checked>
Sans Serif
</form>


}}}
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

Javascript 绝对简明手册(写作中!!!!!!!) -- [email protected] TableOfContents

Include(CPUGnav)

Javascript和C++,Java,Python一样是一种博大精深的编程语言.

  • --For Ajax

版本:0.1 beta

作者:张沈鹏

参考:
Ajax基础教程
Javascript权威指南(中文第4版)
JavaScript.The.Definitive.Guide.5th.Edition

[http://blog.csdn.net/zuroc 我的技术Blog] [http://www.cppblog.com/zuroc 我的C++Blog] [http://www.cnweblog.com/zuroc/ 我的文学Blog]

1. 序言

无论是Ajax,还是XUL(firefox的界面就是用它写的),还是Google桌面,Javascript无处不在

2. 准备

设置服务器*.xml的MIME为text/xml ,Windows Xp自带的IIS的设置如下图 js_0000.png

Firefox上有许多插件是开发必备的,用法大家Google,我列一下名称

另外建议安装一下DreamWaverEditPlus. EditPlus中可以快速切换IE和Js脚本,快捷键Ctrl+B 强烈建议学习时便学边调试

3. 如何嵌入网页?

3.1. 写在网页中

  • <script type="text/javaScript">
    //代码
    </script>

3.2. 在链接上使用伪协议

<a href="javascript:void window.open();">Open</a>

3.3. 使用独立的js脚本

  • <script language="javascript" src="/js/dialog.js" />

4. 语言核心

4.1. 关于分号

javascript的分号是选加的,如果不加,javacript会在换行处自动加上分号.

但是,建议你不要省略分号,理由如下

  • 加了分号的代码可以用软件压缩,来节省带宽(附带效果是加密你的Js代码:) )(Ajax基础教程 上的理由)
  • 良好的编程习惯(Javascript权威指南 上的理由)

4.2. 输出Html最简单的方式

见例子1_1

  • doucment.write("Hello World");

4.3. alert : 弹出窗口,调试必备

见例子1_2

  • alert("弹出窗口,调试必备");

4.4. 命名规则

区分大小写,开头必须是字母或 $ 或 _

4.5. 基本类型

4.5.1. 字符串

使用Unicode字符,如

"test"

'name="zsp"' //双引号可以放在单引号中,反之亦然

'You\'re right' //转义字符,和C++的转义相同

字符串的属性

str="[email protected]"

str.length
//字符串的长度

str.charAt(str.length-1)
//字符串的最后一个字符(注意,第一个字符的索引是0,和C++数组类似)

str.indexOf("@")
//第一个 @ 字符的位置

str.substring(str.lastIndexOf(".")+1,str.length);
//提取后缀"com",提取规则是左开右闭(就是包括左边参数所代表的元素,而不包括右边的)

str.toUpperCase();
//返回大写形式

4.5.2. 十六进制

0xff //15*16+15=255 , 0x为十六进制前缀

4.5.3. 浮点

-3.14 6.02E-23 //6.02 X 10-23(10的负23次方)

4.5.4. 特殊常量

  • Infinity 无穷大
  • Number.POSITIVE_INFINITY 正无穷大
  • Number.NEGATIVE_INFINITY 负无穷大
  • NaN 或 Number.NaN 非法的值
  • Number.MAX_VALUE 可表示的最大值
  • Number.MIN_VALUE 可表示的最接近0的值

4.5.5. 布尔值

true==1 false==0

4.5.6. 基于对象

4.5.6.1. 创建

方式1:

var o = new Object();
o.x=2.3;
o.y=-1.2;

方式2:

var o={x:2.3 , y:-1.2};

调用 o["x"] //返回2.3

一个复杂点的例子 见例子1_3

var point={x:2.3,y:-1.2};
var side=4;
var square={
        upperLeft : {x:point.x , y:point.y},
        lowerRight : {x:(point.x + side) , y:(point.y+side)}
};

alert(square["upperLeft"]["x"]);//显示2.3

备注:内建类型字串不是Object(),即用typeof得到的是"string",和"object"不等价,但在任何需要的地方他会自动转化为一个String对象

4.5.6.2. 构造函数

function Rectangle(w,h)//构造函数.不要返回值,因为返回值会使this失效
{
        this.width=w;
        this.height=h;
}
var rect1=new Rectangle(2,4);//创建对象

4.5.6.3. 成员函数

function Rectangle_area(){return this.width * this.height;}//声明函数

function Rectangle(w,h)
{
this.width=w;this.height=h;

this.area = Rectangle_area;//关联函数为成员函数
}

var r=new Rectangle(3,2);
r.area();//返回6

4.5.6.4. 继承

  • Javascript的类都自动继承了原型对象 Object.prototype
  • 继承的属性为只读的,既子类不可以给继承的属性赋值
  • 子类的同名属性/函数将覆盖父类的同名属性/函数
  • String和Date等内部类也有原型对象

//定义一个父类
function Complex(real , imaginary){
        this.x=real;
        this.y=imaginary;
}

//为父类添加一个方法,通过定义父类原型prototype的函数
//该方法同时覆盖了Object.prototype中的同名函数
Complex.prototype.toString=function(){
        return this.x+"+"+this.y+"j";
}

//定义一个Complex函数,该函数不会被继承(这时不要加this了)
Complex.magnitude=function()
{
        return Math.sqrt(x*x+y*y);      
}

//定义一个子类
function MoreComplex(real , imaginary){
        this.x=real;
        this.y=imaginary;
}

//继承父类,注意这时MoreComplex的构造函数被父类的构造函数覆盖
MoreComplex.prototype=new Complex(0,0);

//明确指定,使MoreComplex使用自己的构造函数
MoreComplex.prototype.constructor=MoreComplex;

//定义子类自己的函数
MoreComplex.prototype.swap=function(){
        var tmp=this.x;
        this.x=this.y;
        this.y=tmp;
}

a=new MoreComplex(11,33);

alert(a);//自动调用Complex.toString()
a.swap();
alert(a);

4.5.6.5. 公共基类的属性

Object.prototype是所有类的公共基类

  • constructor属性 构造器,由于构造函数确定了一个对象的类型,可以用如下代码确定一个对象的类型
    if((typeof o=="object" )&& o.constructor == Date)//...........

但不能保证constructor属性总是存在,类的创建者可以指定一个对象来取代原型的构造器,而指定的对象可以没有 constructor (PS:此句抄书,我看不懂)

  • toString() 返回一个字串,内容为对象的值或类型. 默认的toString对于对象返回

[object class]
//class为类名,如自定义对象为Object
//类似的还有Array,Function,Date,Math,Error,Window,Document,Form

由于可以重载toString.所以,如果你想明确的调用默认的toString来获得类型信息,你可以这样

Object.prototype.toString.apply(x);
  • toLocaleString() Object默认的toLocaleString返回值和toString相等;Array,Date,Number都绑定了自己的toLocaleString
  • valueof() Object默认定valueof不执行任何转换,Number和Boolean等有自定义的valueof(). 当你自定义了valueof时需要注意的是:valueOf()优先级比toString()高,所以,你常不得不明确的调用toString()
  • hasOwnProperty()
    var o = new Object();
    o.hasOwnProperty("undef"); //false:没有定义该属性
    o.hasOwnProperty("toString"); //false:该属性是继承的
    
    Math.hasOwnProperty("cos");//true:Math有cos属性

* propertylsEnumerable() 一个属性如果可以由for...in循环枚举出来就返回true,否则,返回false

var o = {x:1};
o.propertylsEnumerable("x");//true
o.propertylsEnumerable("y");//false,无该属性
o.propertylsEnumerable("valueOF");//false,该属性不可枚举
  • isPrototypeOf() 调用该函数的对象如果是参数的原型,就返回true
     var o=new Object();
     Object.prototype.isPrototypeOf(o);
     //true,o.constructor == Object
    
     Object.isPrototypeOf(o);//false
     o.isPrototypeOf(Object.prototype);//false
    
     Function.prototype.isPrototypeOF(Object);
     //true:Object.constructor == Function

4.5.7. 数组

4.5.7.1. 创建

方式1

var a = new Array();
a[0]=2;
a[1]="I'm a earthman ."
a[2]=true;
a[3]={x:1 , y:3}

方式2

var a=new Array(2,"I'm a earthman .",true,{x:1 , y:3});
var a2=new Array(10);//注意,这个10是表示a有10个未定义元素!(因为这时候只传给Array一个参数)

方式3

var a=[2,"I'm a earthman .",true,{x:1 , y:3}];
var a2=[[1,2,3],[1,2,3]];//可以嵌套

var base=11;
var a3[base,base+1,base+2];//可以为变量

var a4=[1,,,,5];//有3个未定义的元素

4.5.7.2. 数组的函数

* join() 把所有的元素转换为字串,参数作为分隔符(默认分隔符是 ,)

var a=[1,2,3];
a.join();//1,2,3
a.join(" : ");//1 : 2 : 3

* reverse() 对数组反向排序 * sort() 默认按照UTF-8码的顺序排序,可以传一个参数,如果返回一个小于等于0的数,第1个参数出现在第2个参数前面,反之同理.

 function randOrd(){
return (Math.round(Math.random())-0.5);
}

anyArray = new Array('3','a','5','F','x','47');
anyArray.sort( randOrd );       //把数组乱序排列

* concat() 返回一个数组,包含了原数组和参数

anyArray = new Array(47,33);

anyArray.concat(8,99,88 );
//[47,33,8,99,88]

anyArray.concat([8,99],[88,53] );       
//[47,33,8,99,88,53],会自动把参数中数组拆包一层

anyArray.concat(2,[3,[4,5]]);   
//[47,33,2,3,[4,5]],拆包只拆一层

* slice() 返回一个数组的切片,返回规则如下

var a = [1,2,3,4,5]
a.slice(0,3); //返回a[0]至a[2],即[1,2,3]
a.slice(3);        //返回a[3]至结尾,即[4,5]
a.slice(1,-1);//返回a[1]至最后一个元素[2,3,4]
a.slice(-3,-2);//返回[3]

* splice() 可以删除/添加原数组元素,同时返回删除的值

var a = [1,2,3,4,5,6,7];
a.splice(4);
//删除a[4]至结尾,同时返回删除的值,即a=[1,2,3,4],返回[5,6,7]

var a = [1,2,3,4,5,6,7];
a.splice(3,3,"a","b");
//从a[3]开始,删除3个元素(包括a[3]),同时在从a[3]开始插入"a","b"作为新的元素,返回删除的值
//即a=[1,2,3,"a","b",7],返回[4,5,6]

var a = [1,2,3,4,5,6,7];
a.splice(3,0,["a",2],"k");
//返回[],a=[1,2,3,["a",2],"k",4,5,6,7] ,splice()不会对添加的数组拆包

* push()和pop()

var stack=[];

stack.push(1,2);//stack=[1,2],return 2(2表示数组长度)

stack.pop();//stack=[1],return 2

stack.push(3);//stack=[1,3],return 2(2表示数组长度)

stack.pop();//stack=[1],return 3

stack.push([4,5]);//stack=[1,[4,5]],return 2

stack.pop();//stack=[1],return [4,5]

stack.pop();//stack=[],return 1

* unshift()和shift() 和push()和pop()类似,不过是在数组的头进行操作

var a=[2];
a.unshift(1);
//a=[1,2]
//IE(包括IE7)和标准的规定返回值却不同,Gecko/Opera 中返回值为新数组的长度,而 IE 中没有返回值,也就是返回值是 undefined。因此,编程时不要依赖这个返回值。

a.unshift(3,[4,5]);//a=[3,[4,5],1,2]

a.shift();
//返回3

* toString() toString等价于不加参数的join

4.5.8. Date对象

var now = new Date();
//默认是当前的时间和日期

var christmas = new Date(2000,11,25);
//月份从0开始计数,所以这是表示2000年12月25日

christmas.toLocaleString();//返回时间的本地表示,如果是中国大陆,这里返回"2000年12月25日 0:00:00 "
//如果不加toLocalString,christmas自动转换为string时会用GMT时间
//GMT时间这里就是"Mon Dec 25 00:00:00 UTC+0800 2000 "

christmas.getDay()
//返回该日期是星期几,比如这里返回1,注意星期天返回的是0

4.5.9. null 和 undefined

  • null : 无值,表示它的不是有效的Javascript类型
  • undefined : 已经声明但是没有定义的变量的值,对象的一个不存在的属性也是该值

==运算符将两者视为相等,

可以用===区别null和undefinedes

4.6. 函数

4.6.1. 定义函数

方式1:

function square(x){
        return x*x;
}

方式2:

var square = function(x){return x*x;}

方式3://比较笨拙

var square = new Funtion("x","return x*x"); 

4.6.2. 一个函数,多个函数名

var square = function(x){return x*x;}
var b=square;
var c=b(5);//c=25

4.6.3. 函数嵌套函数

function hypotenuse(){
        function square(x){
                return x*x;
        }
        return Math.sqrt(square(a)+square(b));
}

4.6.4. 函数参数

尽管函数定义时参数个数是固定的,但调用时可以传递任意多个参数,这些参数可以通过arguments[]访问,即使是无名的.

arguments.length可以说明它所含的元素个数

注意:arguments不是数组(不可以用for...in循环),它是一个Aguments对象

arguments可以用于参数个数检查,或接受任意数目参数...

function max()
{
var m=Number.NEGATIVE_INFINITY;
for(var i=0;i< arguments.length;i++)
        if(arguments[i]>m)m=arguments[i];
        
return m;
}

4.6.5. 函数自身的length

返回函数声明中的参数的个数,通过arguments.callee.length访问

//一个检查参数是否相符的函数
function check(args){
        var actual=args.length;
        var expected=args.callee.length;
        if(actual!=expected){
                throw new Error("Wrong number of arguments");
        }
}

function f(x,y)
{
        check(arguments);
        return x+y;
}

4.6.6. arguments.callee : 递归无名函数

callee可以引用当前正在执行的函数

function(x)
{
if(x<1)return 1;
return x*arguments.callee(x-1);
}

=== 函数的静态变量 ===
类似在C++函数中声明一个static变量
{{{
uniqueInteger.counter=0;//静态变量
function uniqueInteger(){//每个返回一个不同的数 
        return uniqueInteger.counter++;
}

4.7. 作用域

没有块级作用域,其他类似于Java和C++.

即函数中无论在那里声明的变量,在整个函数体中都是有定义的.如:

(见例1_4)

var i="global";

function test(o){

document.write(i);//i为undefined,即函数中i已被声明,但没定义
var i="local";

if(typeof o == "object")
        {
                var j=0;        //j在整个函数中都有定义,不限于这个循环
                for(var k=0;k<10;k++){//k在整个函数中都有定义,不限于这个循环
                        document.write(k);
                }
                document.write("out loop k=",k);//k仍然有定义,值为10
        }

document.write("out loop j=",j);//仍然有定义,如果o不是object(),则j没有被初始化,值为undefined,否则为9

}

备注:把所有的变量集中在函数开头声明(不一定要定义)可以避免许多诡异的错误.

4.8. 引用

对与 数组 , 对象 , 函数 的拷贝只是拷贝了引用(相当于是个快捷方式),对任何一个副本的改动都会改动所有的副本

var a = [1 , 2 , 3];
var b = a;
a[0] = 99;
alert(b); //为99,2,3

a={x:1}
b=a;
a.x=2;
alert(b.x);//为2

4.9. ==(等于)和===(全等)

4.9.1. 等于

等于可以进行类型自动转换,如

"2"==2
true==1

一个对象和字串或数字比较,会尝试valueOf()和toString()转换

null == undinfined

4.9.2. 全等 (否定为!==)

  • 如果类型不同,则不相同
  • NaN永远不与任何值全等,包括它本身(可以用IsNaN()测试一个值是否是NaN)
  • 按字符原有编码进行比较(等于操作在比较前先统一了编码)
  • null != undinfined

对于数组,对象,函数等引用类型只有当他们是指向同一个实体时才相等,如

var a = [1,2,3];
var b = [1,2,3];
alert(a==b);//false

4.10. +加

加法是从左到右的 a=1+2+" blind mine" // a="3 blind mine" b="blind mine "+1+2 // a="blind mine 12"

4.11. 比较大小

符号> , < , >= , <=

  • 任何和NaN的比较都返回false
  • 字串和数字比较,会把字串转换为数字(如果转换不成功,则其值为NaN),再比较
  • 如果对象可以被转换为数字和字串,将执行数字转换来比较

4.12. in

in运算符左边是一个字串,右边是一个对象,如果字串是对象的一个属性名则返回true

var point = {x:1};
var has_x = "x" in point ; //true
var has_y = "y" in point; //false
var ts = "toString" in point; //true,继承属性

4.13. instanceof

instanceof运算符要求左边是一个对象的实例,右边是对象名,如果两者相符返回true

var d=new Date();
d instanceof Date;//true
d instanceof Object;//true,所有的对象都是Object的实例
d instanceof Number;//false

4.14. typeof

返回对象的类型

typeof 1; //number
typeof "1";//string
typeof true;//boolean

typeof [1,2];//object
typeof {x:1};//object

typeof function(x){};//function

typeof xxx;//未定义的对象返回undefined

4.15. new

创建一个新的对象

o=new Date;

4.16. delete

删除对象的属性

var o={x:1,y:2};

delete o.x; //返回true
typeof o.x;//返回undefined

delete o.x;//删除不存在的属性,返回true

delete o;//不能删除var声明的对象,返回true

x=1;//不用var关键字,隐式声明一个变量
delete x;//返回true
x;//一个运行时错误,IE6显示为 " 'x'未定义 "

注意:delete只能删除属性值,不能删除引用对象

var my = new Object;

my.hire = new Date;
my.fire = my.hire;

delete my.hire;

alert(my.fire);//显示当前的时间

4.17. void

可以出现在任何操作数前,它作用是舍弃运算的结果,返回undefined.

常用于javascript : URL中.可以计算一个计算一个表达式的值,又不让浏览器显示它.如

<a href="javascript:void window.open();">Open</a><!-- 不加void,点击后链接会消失,变为一个"[object]"字串 -->

4.18. []

//用于数组
var a=[21,3];
a[0];//21

//用于对象,比"."运算符的优势是其要取的属性名可以动态生成
var b={x1:1,x2:"zsp"};
b['x1'];//1
b['x'+2];//zsp

for(f in o){
        alert('o.'+f+'='+o[f]);//由于f是动态生成的,所有不能用" . "运算符
}

== if/else/while/do...while/for== 和C++类似

== for...in === 可循环对象的所有用户定义属性,包括继承的(但是不包括内建属性)

var o={x:1,y:2};
var a=[];
var i=0;

for(a[i++] in o);//把o的属性名复制到一个数字中(注意,顺序不固定)

for (i in a)
{
alert(a[i]);//循环一个数组
}

4.19. switch

function convert(x){
        switch(typeof x){
                case 'number':  //case后可以接任意表达式,不限于常量
                        return x.toString(16);//转换为16进制
                case 'string':
                        return '"'+x+'"';
                case 'boolean':
                        return x.toSting().toUpperCase();
                default:
                        return x.toString();
        }
}

4.20. label(标签)/break/continue

break,continue的基本用法和C++中类似,不过他们可以和label配合使用(有的像Java中的label,功能限制版的goto)

outerloop:
        for(var i=0;i!=10;i++)
        {
                for (var j=0;j<10;j++){
                        if(j>3)break;
                        if(i==2)break outerloop;//跳出外层循环
                        alert("j = "+j);
                }
                alert("i = "+i);
        }

4.21. throw / try...catch...finally

throw用来抛出异常,异常对象通常是一个Error对象或其子类型

function factorial(x){
if(x<0)throw new Error("x must not be negative");//x是负数就抛出异常
return x;
}

try...catch...finally捕捉异常

try{
//代码
}
catch(e)
{
//仅当try块抛出异常,才会执行,e为异常实例
//这个块可以处理异常,也可以什么都不做
}
finally{
//无论是否有异常,这个块中的语句都将被执行
}

4.22. 正值表达式

//todo

5. 浏览器中的Javascript概览

  • window对象代表显示浏览器的窗口,document对象代表文档中窗口.
  • 事件触发器:html元素对事件进行响应(不要放在<script>块中)

<input type="checkbox" name="opts" value="ignore-case" onclick="ignore-case=this.checked;">

其中onclick就是事件触发器,常用的还有onmousedown,onmouseup,onmouseover,onmouseout,onchange,onsubmit,onreset

  • 定义函数的js文件一般放在head区
  • <body>和<frameset>的onload在文档被完全加载完成时触发,onunload在文档被卸载时触发

5.1. window对象

window是全局对象,它的函数/属性一般可以不加前缀直接调用。有时为了避免名字冲突,可以加window前缀

5.1.1. 简单的对话框

注意:对话框中显示的是纯文本. * alert() 见图js_0001.png

* confirm() 见图js_0002.png

if(confirm("看我的非技术Blog吗?\n\n我写了不少诗哦 :)"))       location.replace("http://www.cnweblog.com/zuroc/");

* prompt() 见图js_0003.png

n=prompt("你叫什么名字呢?","");//第二个参数是输入的默认值

document.write("<h1>你好, "+n+"!<br/>我叫张沈鹏.</h1>");

5.1.2. 状态栏

* status 浏览器状态栏的显示文本 * defaultStatus 浏览器状态栏显示文本的默认值 该属性在firefox默认关闭,不介绍了

5.1.3. 定时器

* setTimeout() 安排一个JavaScript代码在指定的时间后执行 * clearTimerout() 取消setTimeout的执行 * setInterval() 每隔指定的时间调用指定的函数 * clearInterval() 取消Interval的执行

function hi(){alert("hi!");}
setInterval("hi()",2000);//2000ms=2s

5.1.4. 错误处理onerror

只要给这个属性赋了一个函数,那么这个窗口只要发生了javascript错误,该函数就会被调用.传给错误处理函数的参数有三个,第一个是错误类型,第二个是引发错误的js脚本的Url,第三是发生错误的行号.

如果onerror返回true,它将屏蔽系统的错误处理程序

//如果你不想错误消息打搅用户,无论你的代码有多Bug
window.onerror = function(){return true;}
//不过,不建议你这样做

5.1.5. 浏览器信息navigator

包含了浏览器的信息

* appName Web浏览器的名称 * userAgent 浏览器在USER-AGENT HTTP标题中发送的字符串,通常包含了appName和appVersion * platform 平台,如Win32

//一个简单浏览器探测器
var browser = {
    version: parseInt(navigator.appVersion),
    isNetscape: navigator.appName.indexOf("Netscape") != -1,
    isMicrosoft: navigator.appName.indexOf("Microsoft") != -1
};

5.1.6. 屏幕screen

* width,height 分辨率的宽和高 * availWidth , availHeight 去除了任务栏这样的特性的宽和高 * colorDepth 屏幕的色深 见例子1_5.html

5.1.7. 打开窗口open

//注意,直接弹出窗口容易被浏览器广告拦截了
window.open("http://www.cnweblog.com/zuroc/","窗口名","width=200,height=200,status=yes,resizable=yes");
//具体属性希望那位大哥可以帮我列一下
//被打开的窗口可以用opener引用父窗口,如果是用户自己打开的opener为null
//用open时一般要明确加上window前缀,因为Document也有open属性

见例子1_5.html

window.close可以关闭你用javascript打开的窗口

5.1.8. 移动窗口/改变大小moveTo , moveBy , resizeTo , resizeBy

* moveTo 把窗口左上角移到指定的坐标 * moveTo 把窗口相对现在的位置移动指定的象素 * resizeTo 按照绝对大小调整窗口 * resizeBy 按照相对大小调整窗口 见例子1_5.html

5.1.9. 焦点控制 focus 和 blur

* focus() 将焦点给指定窗口,同时把窗口移动到最前端,使窗口可见,当open()打开窗口,如果第二个参数指定的窗口名已经存在,open不会自动使那个窗口可见,这时就要调用该函数 * blur() 放弃焦点,这时窗口将被至于窗口队列的最后(这就什么sohu背投广告的原理吧) 见例子1_5.html

5.1.10. 文档滚动

* scrollBy() 相对当前位置滚动指定的象素 * scrollTo() 将文档滚动到一个绝对位置,文档的左上角的坐标为(0,0)

5.1.11. 当前地址栏 location

它本身代表当前窗口的URL,它还有各个属性如下 * location.protocol 用的协议,如在本地直接打开网页则是file: * location.host 用的域名 * location.pathname 域名后的网址路径.如"/F:/Javascript绝对简明教程/example/test.html " * location.search 查询的内容 * location.reload() 刷新当前线 * location.replace() 跳转到指定的URL,与直接给location赋值不同的是,这样不会在浏览历史中留下记录(也就是后退不会到该页)

//一个把URL串中查询内容解析为键值对的函数
function getArgs(){
        var args=new Object;
        var query=location.search.substring(1);//或取查询串
        var pairs=query.split(",");     //在逗号处分开
        for(var i=0;i<pairs.length;i++){
                var pos=pair[i].indexOf("=");
                var argname=pairs[i].substring(0,pos);
                var value=pairs[i].substring(pos+1);
                args[argname]=decodeURIComponent(value);
        }
        return args;
}
//调用可以这样
var args=getArgs();
if(args.x)x=parseInt(args.x);

//检查浏览器是否支持DOM,如果不支持则跳转
if (!document.getElementById) location = "staticpage.html";

5.1.12. 历史History

脚本不能真正访问History数组,但是可以调用它的函数 * back() 后退 * forward() 前进 * go() 后退/前进指定的页数

5.1.13. 框架

一个窗口可以用frames,parent,top引用其他属性

每个窗口有一个frame[]数组(如果一个窗口没有框架则它的frame[]是空的,frames.length==0),frame[0]表示它的第一个子框架,如此类推

每个窗口还有一个parent属性,为包含这个窗口的window对象,这样一个窗口通过诸如parent.frames[1]的方式,引用他的兄弟窗口

对于顶层窗口,有parent==window

对于框架中的框架,可以用top直接引用最顶层的窗口

见图js_0004.png

框架可以用name指定名字,这个名字可以为链接的target值.当这个链接被激活的时候会在指定的框架中显示内容

在javascript也可以通过名字访问框架,如一个框架如下

  • <frame name="table_of_contents" src="top.html">

则可以通过parent.table_of_contents方法访问该框架

需要注意的在一个框架定义的函数/变量,在另一个框架中要通过框架名来调用

见例1_6.html

5.2. 文档Documents

5.2.1. 基本常识

5.2.1.1. 属性

* bgColor , fgColor 文档背景色,前景色(不赞成使用的属性) * lastModified 文档的最后修改时间

//可以在文档末加入
  最后更新:<script>document.write(document.lastModified);</script>

* referrer 如果该属性存在,则返回一个链接,表示用户是由哪个网页链接到该页的

<script>
//如果你想其他由网站链接到该页的用户先访问你的首页
if (document.referrer == "" || document.referrer.indexOf("mysite.com") == -1)
    window.location = "http://home.mysite.com";
</script>

5.2.1.2. 数组

* title 文档标题 * URL 等同于window的location.href * anchors[] 所有有name属性的a标记 * forms[] 所有form标记,每个form还有一个element[]数组 * images[] 所有的<img>标签,可以改变它的src属性来改变图象 * link[] 文档中所有的超链接,和window的location一样有protocol, hostname,pathname等属性

<form name="f1"><input type="button" value="Push Me" name="zipcode"></form>

//如果一个元素有name还可以这样访问
document.forms.f1    
document.forms["f1"]  

//对于它的子元素可以这样访问
document.shipping.zipcode

//如果有重名的元素,以上的引用方法将返回一个数组

5.2.1.3. 事件设置

<form name="myform" onsubmit="return validateform();">...</form>
//以上事件设置在javascript中的等效代码如下,注意,javascript中的所有事件名都是小写的
document.myform.onsubmit = validateform;

5.2.2. DOM树

见图js_0005.png 对于树上的节点可以用firstChild, lastChild, nextSibling, previousSibling, 和 parentNode属性来历遍

appendChild(), removeChild(), replaceChild(), 和 insertBefore() 可以在文档中动态的添加/删除节点

每个节点都有一个nodeType属性,表明了它的类型

Interface                       nodeType constant                       nodeType value

Element                 Node.ELEMENT_NODE                        1
Text                            Node.TEXT_NODE                           3 
Document                        Node.DOCUMENT_NODE                       9
Comment                 Node.COMMENT_NODE                        8
DocumentFragment  Node.DOCUMENT_FRAGMENT_NODE 11
Attr                            Node.ATTRIBUTE_NODE                      2

getAttribute(), setAttribute(), removeAttribute() 可以用来操作属性,标准的Html元素的属性也可以通过这种方式访问 getAttributeNode()可以返回一个Attr对象,它有一个specified属性,可以判断文档是否指定了该属性,或判断它是否是默认值

//历便一个DOM树
function countTags(n) {                         // n is a Node
    var numtags = 0;                            // Initialize the tag counter
    if (n.nodeType == 1 /*Node.ELEMENT_NODE*/)  // Check if n is an Element
        numtags++;                              // Increment the counter if so
    var children = n.childNodes;                // Now get all children of n
    for(var i=0; i < children.length; i++) {    // Loop through the children
        numtags += countTags(children[i]);      // Recurse on each one
    }
    return numtags;                             // Return the total
}
alert('This document has ' + countTags(document) + ' tags');

5.2.2.1. 搜索文档的特定元素

* document.getElementsByTagName() 返回指定标签名的数组

//虽然只有一个body,还是返回一个数组
document.getElementsByTagName("body")[0];

//有多少表格
var tables = document.getElementsByTagName("table");
alert("This document contains " + tables.length + " tables");

* document.getElementById() 返回id号为指定值元素,因为每个id应该的独一无二的,所以该方法最多返回一个元素

<p id="specialParagraph">
var myParagraph = document.getElementById("specialParagraph");

* document.getElementsByName() 返回name属性为指定值的元素的数组

// Find <a name="top">
var link = document.getElementsByName("top")[0];
// Find all <input type="radio" name="shippingMethod"> elements
var choices = document.getElementsByName("shippingMethod");

5.2.2.2. 动态改变文档内容

* Document.createElement() * Document.createTextNode() * Node.appendChild() * Node.insertBefore() * Node.replaceChild()

5.2.2.3. 一个动态改变Document内容的演示

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>test</title>
<script>
function sortkids(e) {
     // This is the element whose children we are going to sort
     if (typeof e == "string") e = document.getElementById(e);

     // Transfer the element (but not text node) children of e to a real array
     var kids = [];
     for(var x = e.firstChild; x != null; x = x.nextSibling)
         if (x.nodeType == 1 /* Node.ELEMENT_NODE */) kids.push(x);

     // Now sort the array based on the text content of each kid.
     // Assume that each kid has only a single child and it is a Text node
     kids.sort(function(n, m) { // This is the comparator function for sorting
                   var s = n.firstChild.data; // text of node n
                   var t = m.firstChild.data; // text of node m
                   if (s < t) return -1;      // n comes before m
                   else if (s > t) return 1;  // n comes after m
                   else return 0;             // n and m are equal
               });

     // Now append the kids back into the parent in their sorted order.
     // When we insert a node that is already part of the document, it is
     // automatically removed from its current position, so reinserting
     // these nodes automatically moves them from their old position
     // Note that any text nodes we skipped get left behind, however.
     for(var i = 0; i < kids.length; i++) e.appendChild(kids[i]);
}
</script>
</head>

<body>


<ul id="list"> <!-- This is the list we'll sort -->
<li>one<li>two<li>three<li>four <!-- items are not in alphabetical order -->
</ul>
<!-- this is the button that sorts the list -->
<button onclick="sortkids('list')">Sort list</button>
</body>
</html>

5.2.2.4. 一个把文章中字母都变为大写的演示

// This function recursively looks at Node n and its descendants,
// converting all Text node data to uppercase
function upcase(n) {
    if (n.nodeType == 3 /*Node.TEXT_NODE*/) {
        // If the node is a Text node, change its text to uppercase.
        n.data = n.data.toUpperCase();
        //你也可以用appendData(), insertData(), deleteData(), replaceData()来更改数据
    }
    else {
        // If the node is not a Text node, loop through its children
        // and recursively call this function on each child.
        var kids = n.childNodes;
        for(var i = 0; i < kids.length; i++) upcase(kids[i]);
    }
}

5.2.2.5. 把指定标签改为粗体

<script>
// This function takes a Node n, replaces it in the tree with an Element node
// that represents an HTML <b> tag, and then makes the original node the
// child of the new <b> element.
function embolden(n) {
    if (typeof n == "string") n = document.getElementById(n); // Lookup node
    var b = document.createElement("b"); // Create a new <b> element
    var parent = n.parentNode;           // Get the parent of the node
    parent.replaceChild(b, n);           // Replace the node with the <b> tag
    b.appendChild(n);                    // Make the node a child of the <b> element
}
</script>

<!-- A couple of sample paragraphs -->
<p id="p1">This <i>is</i> paragraph #1.</p>
<p id="p2">This <i>is</i> paragraph #2.</p>
<!-- A button that invokes the embolden() function on the element named p1 -->
<button onclick="embolden('p1');">Embolden</button>

5.2.2.6. 更改属性

var headline = document.getElementById("headline");  // Find named element
headline.setAttribute("align", "center");            // Set align='center'

5.2.2.7. 临时容器DocumentFragment

  • DocumentFragment是一个用来装载DOM对象的临时容器,将他写入文档其实是将它的子元素写入节点

    // 翻转元素
    function reverse(n) {
        // Create an empty DocumentFragment as a temporary container
        var f = document.createDocumentFragment();
        // Now loop backward through the children, moving each one to the fragment.
        // The last child of n becomes the first child of f, and vice-versa.
        // Note that appending a child to f automatically removes it from n.
        while(n.lastChild) f.appendChild(n.lastChild);
    
        // Finally, move the children of f all at once back to n, all at once.
        n.appendChild(f);
    }
    ==== 直接插入Html代码innerHTML ==== 虽然不是W3C的标准,但是事实上的标准,类似的还有outerHTML, innerText, 和outerText
    var table = document.createElement("table");  // Create the <table> element
    table.border = 1;                             // Set an attribute
    // Add a Name|Type|Value header to the table

5.2.2.8. 选中内容 getSelection

还不是标准,但还是可用的,参考 http://www.quirksmode.org/js/selected.html

Hi , everybody . My name is Zsp .
function getSelectedText() {
    if (window.getSelection) {
        // This technique is the most likely to be standardized.
        // getSelection() returns a Selection object, which we do not document.
        return window.getSelection().toString();
    }
    else if (document.selection) {
        // This is the IE-specific technique.
        // We do not document the IE selection property or TextRange objects.
        return document.selection.createRange().text;
    }
    //现在可以省略了
    else if (document.getSelection) {
        // This is an older, simpler technique that returns a string
        return document.getSelection();
    }
}

//一个实际使用的演示
<a href="javascript:
    var q;
    if (window.getSelection) q = window.getSelection().toString();
    else if (document.getSelection) q = document.getSelection();
    else if (document.selection) q = document.selection.createRange().text;
    void window.open('http://en.wikipedia.org/wiki/' + q);
">
Look Up Selected Text In Wikipedia
</a>

5.2.3. CSS

//一个用来隐藏广告代码的演示
var imgs = document.getElementsByTagName("img");  // Find all images
for(var i = 0; i < imgs.length; i++) {            // Loop through them
    var img=imgs[i];
    if (img.width == 468 && img.height == 60)     // If it's a 468x60 banner...
        img.style.visibility = "hidden";          // hide it!
}

* javascript与css的名字映射,如font-family映射为fontFamily,诸如此类.另外css中的float映射为cssFloat,如此类推

e.style.position = "absolute";
e.style.fontFamily = "sans-serif";
e.style.backgroundColor = "#ffffff";
e.style.left = "300px";
e.style.margin = topMargin + "px " + rightMargin + "px " +
                 bottomMargin + "px " + leftMargin + "px";

5.2.3.1. 当前的CSS设置

W3C规定了getComputedStyle()函数来获取CSS元素的经过各种效果复合过后的当前值

但是IE不支持标准,但它有每个元素都有一个currentStyle属性,可以取得同样的效果

//一段兼容的代码
<p>
Look Up Selected Text In Wikipedia
</p>

<script>
var p = document.getElementsByTagName("p")[0]; // Get first paragraph of doc
var typeface = "";                             // We want its typeface
if (p.currentStyle)                            // Try simple IE API first
    typeface = p.currentStyle.fontFamily;
else if (window.getComputedStyle)              // Otherwise use W3C API
    typeface = window.getComputedStyle(p, null).fontFamily;
alert(typeface);
</script>

5.2.3.2. 指定样式表

<head>
<!-- Here we define four stylesheets, using <link> and <style> tags. -->
<!-- Two of the <link>ed sheets are alternate and so disabled by default. -->
<!-- All have id attributes so we can refer to them by name. -->
<link rel="stylesheet" type="text/css" href="ss0.css" id="ss0">
<link rel="alternate stylesheet" type="text/css" href="ss1.css"
      id="ss1" title="Large Type">
<link rel="alternate stylesheet" type="text/css" href="ss2.css"
      id="ss2" title="High Contrast">
<style id="ss3" title="Sans Serif">
body { font-family: sans-serif; }
</style>

<script>
// This function enables or disables a stylesheet specified by id.
// It works for <link> and <style> elements.
function enableSS(sheetid, enabled) {
    document.getElementById(sheetid).disabled = !enabled;
}
</script>
</head>
<body>

<!-- This is a simple HTML form for enabling and disabling stylesheets -->
<!-- It is hardcoded to match the sheets in this document but could be -->
<!-- dynamically generated using stylesheet titles instead. -->
<form>
<input type="checkbox" onclick="enableSS('ss0', this.checked)" checked>Basics
<br><input type="checkbox" onclick="enableSS('ss1', this.checked)">Large Type
<br><input type="checkbox" onclick="enableSS('ss2', this.checked)">Contrast
<br><input type="checkbox" onclick="enableSS('ss3', this.checked)" checked>
Sans Serif
</form>

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

jsInAWord (last edited 2009-12-25 07:13:05 by localhost)