javascript 高级程序设计 学习笔记

时间:2023-08-28 10:12:08

<!--
<script>
// 异步请求封装 IE6即以上浏览器
// ajax(url,fnSucc,selectID,fnFaild)
//url 请求地址
//fnSucc 异步请求后的内容处理函数
//fnFaild 请求失败处理函数

function ajax(url,fnSucc,fnFaild)
{
//1.创建Ajax对象
//非IE6
var oAjax;
if(window.XMLHttpRequest)//不会报错,只会是undefined
{oAjax=new XMLHttpRequest();}
else
//iE6 IE5
{oAjax=new ActiveXObject("Microsoft.XMLHTTP");}
//alert(oAjax);
//2.连接服务器
//open(方法,文件名,异步传输)
oAjax.open("get",url,true);//制止缓存
//3.发送请求
oAjax.send();
//4.接收返回值 和服务器通讯的时候此事件发生
oAjax.onreadystatechange=function()
{
//oAjax.readyState //浏览器和服务器,进行到哪一步了 异步握手过程
if(oAjax.readyState==4)//读取完成(可能文件不存在)
{
if(oAjax.status==200 || oAjax.status==304)//请求成功 304即使浏览器缓存了也返回数据
{
fnSucc(oAjax.responseText);
//alert("成功"+oAjax.responseText);
}
else
{
if(fnFaild)//fnFaild传进来时
{
fnFaild(oAjax.status);
}
//alert("失败:"+oAjax.status);//status为404
}
}
}

}

window.onload=function(){
var oBtn=document.getElementById("left");
oBtn.onclick=function()
{
ajax("http://28967904.jsp.jspee.cn/ext/singlePage/list/json-1-1-20",function(str){
var da= JSON.parse(str); //JSON数据解析
alert(da.totalRow)
},function(erorr){
console.log('请求出错:'+erorr);
})
}
}

</script>

<script>
//javascript Object: ajax Object
//Created By RexLee
function Ajax(url,data){
this.url=url;
this.data=data;
this.browser=(function(){
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE";//IE浏览器
}else{
return "other";//其他
}})();
};
Ajax.prototype={
get:function(){
var result;
var xmlhttp;
if(this.browser=='MSIE'){
try{
xmlhttp=new ActiveXObject('microsoft.xmlhttp');
}catch(e){
xmlhttp=new ActiveXObject('msxml2.xmlhttp');
}
}else{
xmlhttp=new XMLHttpRequest();
};
xmlhttp.onreadystatechange=function(){
result = xmlhttp.responseText;//闭包,不能采用this.属性
};
xmlhttp.open('GET',this.url+'?'+this.data,false);//true无法抓取数据,why?
xmlhttp.send(null);
return result;
},
post:function(){
var result;
var xmlhttp;
if(this.browser=='MSIE'){
xmlhttp=new ActiveXObject('microsoft.xmlhttp');
}else{
xmlhttp=new XMLHttpRequest();
};
xmlhttp.onreadystatechange=function(){
result = xmlhttp.responseText;//闭包,不能采用this.属性
};
xmlhttp.open('POST',this.url,false);//需设为false,否则无法抓取responseText
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//POST中,这句必须
xmlhttp.send(this.data);
return result;
}
};

//var a=new ajax('opp2.js','');
//alert('by GET\\n'+a.get())
//alert('by POST\\n'+a.post());
///////////////////////////////

window.onload=function(){
document.getElementById("btn").onclick=function(){
var p=document.getElementById("t").value;
var a=new Ajax("phpOOP/getPage.php","page="+p);
document.getElementById("box").innerHTML=a.get();
};
}
</script>

<script>
function Ajax() {
var xmlHttpReq = null;
if (window.XMLHttpRequest) {
xmlHttpReq = new XMLHttpRequest();
} else {
if (window.ActiveXObject) {
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
}
var handler = null;
this.invoke = function (url, mode, synchro, _handler) {
handler = _handler;
xmlHttpReq.open(mode, url, synchro);
xmlHttpReq.onreadystatechange = this.callback;
xmlHttpReq.send(null);
};
this.callback = function () {
if (xmlHttpReq.readyState == 4) {
if (xmlHttpReq.status == 200) {
handler(xmlHttpReq.responseText);
} else {
alert("There was a problem retrieving the XML data:\n" + xmlHttpReq.statusText);
}
}
};
}

window.onload=function(){
document.getElementById("btn").onclick = function(){
var ajax = new Ajax();
ajax.invoke("json/data1.js","GET",true,function(response){
var json = eval("(" + response + ")");
json = json.newList[1].bar_data;
alert(json);//传到服务器测试成功
},function(error){
//alert("报错");
});
}
}
</script>

<script>
var Factory = {
create: function() {
return function() {this.init.apply(this, arguments); }
}
}

var Ajax = Factory.create();

Ajax.prototype = {
init: function (successCallback, failureCallback) {
this.xhr = this.createXMLHttpRequest();
var xhrTemp = this.xhr;
var successFunc = null;
var failFunc = null;

if (successCallback != null && typeof successCallback == "function") {
successFunc = successCallback;
}

if (failureCallback != null && typeof failureCallback == "function") {
failFunc = failureCallback;
}

//this.get.apply(this, arguments);
//this.post.apply(this, arguments);

this.xhr.onreadystatechange = function () {
if (xhrTemp.readyState == 4) {
if (xhrTemp.status == 200) {
if (successFunc != null) {
successFunc(xhrTemp.responseText, xhrTemp.responseXML);
}
}
else {
if (failFunc != null) {
failFunc(xhrTemp.status);
}
}
}
}
},
get: function (url, async) {
this.xhr.open("GET", url, async);
this.xhr.send();
},
createXMLHttpRequest: function () {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else {
return new ActiveXObject("Microsoft.XMLHTTP");
}

throw new Error("Ajax is not supported by the browser!");
},
post: function (url, data, async) {
this.xhr.open("POST", url, async);
this.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
this.xhr.send(data);
},
random: function (length) {
var array = new Array("0", "1", "2", "3", "5", "6", "7", "8", "9");
var len = parseInt(length);
var key = "";

for (var i = 0; i < len; i++) {
key += Math.floor(Math.random() * 10);
}

return key;
}
}

window.onload = function(){
document.getElementById("btn").onclick = function (){
var ajax = new Ajax(function(data,xml){
var data = eval("(" + data + ")");
data = data.newList[1].bar_data;
alert(data);//测试通过
},function(status){
alert(status);
});
ajax.get("json/data1.js", true);

}
}
</script>
-->

<script>
function user(name,job,salay){
this.name = name;
this.job = job;
this.salay = salay;
}
var emply = new user('bill','web','20000');
//用prototype增加一个属性
user.prototype.born = null;
emply.born = '1985';
document.writeln(emply.born);
</script>

<script>/*
// prototype http://www.cnblogs.com/mindsbook/archive/2009/09/19/javascriptYouMustKnowPrototype.html
function Person(name, gender)
{
this.name = name;
this.gender = gender;
this.whoAreYou = function(){//这个也是所谓的closure, 内部函数可以访问外部函数的变量
var res = "I'm " + this.name + " and I'm a " + this.gender +".";
return res;
};
}
// 那么在由Person创建的对象便具有了下面的几个属性
Person.prototype.age = 24;
Person.prototype.getAge = function(){
return this.age;
};
flag = true;
if (flag)
{
var fun = new Person("Tower", "male");
alert(fun.name);
alert(fun.gender);
alert(fun.whoAreYou());
alert(fun.getAge());
//alert(123);
}
Person.prototype.salary = 10000;
Person.prototype.getSalary = function(){
return this.name + " can earn about " + this.salary + "RMB each month." ;
};
// 下面就是最神奇的地方, 我们改变了Person的prototype,而这个改变是在创建fun之后
// 而这个改变使得fun也具有了相同的属性和方法
// 继承的意味即此
if (flag)
{
alert(fun.getSalary());
alert(fun.constructor.prototype.age);//而这个相当于你直接调用 Person.prototype.age
alert(Person.prototype.age);
}
Person.prototype.born = "1985";
Person.prototype.getBorn = function(){
return this.born;
}
if(flag){
alert(fun.getBorn());
}

// 多重prototype链的例子
function Employee(name)
{
this.name = "";
this.dept = "general";
this.gender = "unknown";
}
function WorkerBee()
{
this.projects = [];
this.hasCar = false;
}
WorkerBee.prototype = new Employee; // 第一层prototype链
function Engineer()
{
this.dept = "engineer11"; //覆盖了 "父对象"
this.language = "javascript";
}
Engineer.prototype = new WorkerBee; // 第二层prototype链
var jay = new Engineer("Jay");
var flag = true;
if (flag)
{
alert(jay.dept); //engineer, 找到的是自己的属性
alert(jay.hasCar); // false, 搜索到的是自己上一层的属性
alert(jay.gender); // unknown, 搜索到的是自己上二层的属性
} */
</script>

<!-- 自己做的两个简单的封装小例子
<script>
function calc(a,b){
this.a = a;
this.b = b;
}
calc.prototype.c = 5;
calc.prototype.sum = function(){
var sum = this.a + this.b + this.c;
return sum;
}
var result = new calc(3,4);
alert(result.sum());
</script>

<script>
function hi(){
var add = 0;
for(var i=0;i<arguments.length;i++){
add += arguments[i];
}
return add;
}
alert(hi(5,6,7,8,9));
</script>
-->

<!-- 面向对象开发案例 -->

<!-- 基础篇
<script>
//作为值的函数
function callSomeFunction(someFunction, someArgument){
return someFunction(someArgument);
}
function add10(num){
return num + 10;
}
var result1 = callSomeFunction(add10, 10);
alert(result1); //20

//每个函数都有两个非继承来的方法apply和call,他们的第一个参数都是一个样的是this,不同的只是接收第二个参数方式不同,apply的第二个参数可以是数组,也可以是对象,call的第二个参数要一一列举出来传给函数,
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments); // 传入 arguments 对象
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]); // 传入数组
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20

function sum(num1, num2){
return num1 + num2;
}
function callSum(num1, num2){
return sum.call(this, num1, num2);
}
alert(callSum(10,10)); //20

//函数内部的另一个特殊对象是 this,换句话说,this引用的是函数据以执行的环境对象——或者也可以说是 this 值(当在网页的全局作用域中调用函数时,this 对象引用的就是 window)。
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue"

//判断是否Boolean值,有值为true,空为false;
var message = "hi";
if(message){
alert(true);
}

//for in 列举出window对象的所有属性
for(var propName in window){
document.write(propName + " ");
}

//传递参数 证明对象是按值传递,而不是按引用传递的,
function setname(obj){
obj.name = "TOM";
}
var person = new Object();
setname(person);
alert(person.name);

//查找元数所在索引位置
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(1,4)); //8 从第四个索引往后查找1这个元素

function outer(){
inner();
}
function inner(){
alert(inner.caller);
}
outer();

//取数组里的最大值
var values = [1, 2, 3, 4, 5, 6, 7, 8];
var max = Math.max.apply(Math, values);
alert(max);

//随机输出2-10之间的任何一个数,
var num = Math.floor(Math.random() * 9 + 2);
alert(num); //随机选出2-10
</script>
-->

<!-- 面向对象之对象篇
<script>
//工厂模式
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");
person1.sayName();

//构造函数模式
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
//原型
//Person.prototype.sayName = function(){
//alert(this.name);
//}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.sayName();

// 在另一个对象的作用域中调用
var o = new Object();
Person.call(o, "Kristen", 25, "Nurse");
o.sayName(); //"Kristen"

//原型模式
function Personp(){};
Personp.prototype.name = "TOM";
Personp.prototype.age = 30;
Personp.prototype.job = "Doctor";
Personp.prototype.sayName = function(){
alert(this.name);
}
var person1 = new Personp();
person1.sayName();

//当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性;添加这个属性只会阻止我们访问原型中的那个属性,但不会修改那个属性。即使将这个属性设置为 null,也不会恢复其指向原型的连接。不过,使用 delete 操作符则可以完全删除实例属性,从而让我们能够重新访问原型中的属性
function Person_del(){}
Person_del.prototype.name = "Nicholas";
Person_del.prototype.age = 29;
Person_del.prototype.job = "Software Engineer";
Person_del.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person_del();
var person2 = new Person_del();
person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例
alert(person2.name); //"Nicholas"——来自原型
//person1.name = null; //改为null也没有办法恢复他访问原型里面的属性,只能用delete删除
delete person1.name;
alert(person1.name); //"Nicholas"——来自原型

//要取得对象上所有可枚举的实例属性,可以使用 ECMAScript 5 的 Object.keys()方法。这个方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组
function Person_in(){
}
Person_in.prototype.name = "Nicholas";
Person_in.prototype.age = 29;
Person_in.prototype.job = "Software Engineer";
Person_in.prototype.sayName = function(){
alert(this.name);
};
var keys = Object.keys(Person_in.prototype);
alert(keys); //"name,age,job,sayName"
var p1 = new Person_in();
p1.name = "Rob";
p1.age = 31;
var p1keys = Object.keys(p1);
alert(p1keys); //"name,age"

//精简原型
function person_simple(){};
person_simple.prototype = {
name:"TOM1111",
age:29,
job:"Doctor",
sayName:function(){
alert(this.name);
}
}
var person_simple = new person_simple();
person_simple.sayName();

//原型的动态性
function Person_fnd(){};
var friend = new Person_fnd();
Person_fnd.prototype.sayHi = function(){
alert("hi111");
}
//下面这段代码重写了其原型对象,运行结果会出错,重写原型对象切断了现在有原型与任何之前已经存在的对象实例之间的联系,它们引用的仍然是最初的原型,
/*Person_fnd.prototype = {
//constructor:Person_fnd,
sayHi: function(){
alert("hi222");
}
}*/
friend.sayHi();

//原生对象原型 字符串对象原型 不推荐用这个方法,因为有可能会改写了原生对象
String.prototype.startsWith = function(text){
return this.indexOf(text) == 0;
};
var msg = "hello world";
alert(msg.startsWith("hello")); //true

//组合使用构造函数模式和原型模式

//创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存。另外,这种混成模式还支持向构造函数传递参数;可谓是集两种模式之长
function Person_all(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby", "Court"];
}
Person_all.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
}
var person1 = new Person_all("Nicholas", 29, "Software Engineer");
var person2 = new Person_all("Greg", 27, "Doctor");
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van"
alert(person2.friends); //"Shelby,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true

//动态原型模式(不能使用对象字面量重写原型,这样会切断实例与新原型的联系)

//有其他 OO 语言经验的开发人员在看到独立的构造函数和原型时,很可能会感到非常困惑。动态原型模式正是致力于解决这个问题的一个方案,它把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了同时使用构造函数和原型的优点。换句话说,可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型
function Person_fz(name,age,job){
this.name = name;
this.age = age;
this.job = job;
//判断这个方法,如果不存在,就添加到原型中去
if(typeof this.sayName != "function"){
Person_fz.prototype.sayName = function(){
alert(this.name);
}
}
}
var friend = new Person_fz("Jim",50,"Teacher");
friend.sayName();

//寄生构造函数模式(不推荐使用)
function SpecialArray(){
//创建数组
var values = new Array();
//添加值
values.push.apply(values, arguments);
//添加方法
values.toPipedString = function(){
return this.join("|");
};
//返回数组
return values;
}
var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString()); //"red|blue|green"
</script>
-->

<!-- 面向对象之继承篇
<script>
//原型链
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
//继承了 SuperType 实现的方法就是指向另一个对象的原型,产生一个新类型的实例
SubType.prototype = new SuperType();
//SubType的constructor被重写了
SubType.prototype.getSubValue = function (){
return this.subproperty;
};
//改写超类型中的方法一定要放在下面
//SubType.prototype.getSuperValue = function(){
//return false;
//}
var instance = new SubType();
alert(instance.getSuperValue()); //true 继承了SuperType的方法,
alert(instance.getSubValue()); //false 也保留了对自己方法的引用

//借用构造函数
function SuperType1(name){
this.name = name;
}
function SubType1(){
//继承了 SuperType,同时还传递了参数
SuperType1.call(this, "Nicholas");
//实例属性
this.age = 29;
}
var instance = new SubType1();
alert(instance.name); //"Nicholas";
alert(instance.age); //29

//组合继承(组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为 JavaScript 中最常用的继承模式。而且,instanceof 和 isPrototypeOf()也能够用于识别基于组合继承创建的对象)
function SuperType2(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType2.prototype.sayName = function(){
alert(this.name);
};
function SubType2(name, age){
//继承属性
SuperType2.call(this, name);
this.age = age;
}
//继承方法
SubType2.prototype = new SuperType2();
SubType2.prototype.constructor = SubType2;
SubType2.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType2("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType2("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27

//寄生式继承

//在 object()函数内部,先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例。从本质上讲,object()对传入其中的对象执行了一次浅复制
function object(o){
function F(){}
F.prototype = o;
return new F();
}
function createAnother(original){
var clone = object(original); //通过调用函数创建一个新对象
clone.sayHi = function(){ //以某种方式来增强这个对象
alert("hi1212");
};
return clone; //返回这个对象
}
var person_org = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
//这个例子中的代码基于 person 返回了一个新对象——anotherPerson。新对象不仅具有 person的所有属性和方法,而且还有自己的 sayHi()方法
var anotherPerson = createAnother(person_org);
anotherPerson.sayHi(); //"hi"
//alert(anotherPerson.name);

//寄生组合继承 (开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式)

//原来的写法(是有问题的)
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name); //第二次调用 SuperType()
this.age = age;
}
SubType.prototype = new SuperType(); //第一次调用 SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
};

//用寄生组合重构
function inheritPrototype(subType, superType){
var prototype = object(superType.prototype); //创建对象
prototype.constructor = subType;//增强对象
subType.prototype = prototype;//指定对象
}

function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
alert(this.age);
};
//这个例子的高效率体现在它只调用了一次 SuperType 构造函数,并且因此避免了在 SubType.prototype上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够正常使用instanceof 和 isPrototypeOf,开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式
</script>
-->

<!-- 面向对象之函数表达式篇
<script>
//创建函数
//var compareNames = createComparisonFunction("name");
//调用函数
//var result = compareNames({ name: "Nicholas" }, { name: "Greg" });
//解除对匿名函数的引用(以便释放内存)
//compareNames = null;

//闭包与变量
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){
return i;
};
//result[i] = function(num){
//return function(){
//return num;
//}
//}(i) //可以通过创建另一个匿名函数强制让闭包的行为符合预期,返回各自的索引值
}
return result;
}
alert(createFunctions()); //返回函数数组
var a = createFunctions();
alert(a[3]()); //即闭包只能取得包含函数中任何变量的最后一个值,返回都是10

//关于this对象(this 对象是在运行时基于函数的执行环境绑定的:在全局函数中,this 等于 window,而当函数被作为某个对象的方法调用时,this 等于那个对象。不过,匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window①。但有时候由于编写闭包的方式不同,这一点可能不会那么明显)
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
//把外部作用域中的 this 对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了
//var that = this; //这个时候的this是指向My Object的,接着把他赋给了that
return function(){
return this.name;
//return that.name; //所以这里输出的是My Object
};
}
};
alert(object.getNameFunc()()); //"The Window"(在非严格模式下)

//内存泄漏
function assignHandler(){
//这个变量无法销毁,那样会导致下面的匿名函数无法运行
var element = document.getElementById("someElement");
//var id = element.id; //解决办法,通过创建一个副本,这样就可以销毁HTML元素element了,
element.onclick = function(){
alert(element.id);
//alert(id);
};
//element = null;
}

//模仿块级作用域
function outputNumbers(count){
(function(){
for (var i=0;i<count;i++){
alert(i);
}
})();
//alert(i); //error 因为上面的匿名函数是一个私有作用域,这个地方的i是访问不到的
}
outputNumbers(2);

//私有变量
function MyObject(){
//私有变量和私有函数
var privateVariable = 10;
function privateFunction(){
return false;
}
//特权方法
this.publicMethod = function (){
privateVariable++;
return privateFunction();
//return privateVariable;
};
}
var aa = new MyObject();
alert(aa.publicMethod()); //利用特权方法把MyObject里的变量和方法取出来,

//静态私有变量
(function(){
//私有变量和私有函数
var privateVariable = 10;
function privateFunction(){
return 100;
}
//构造函数
MyObject = function(){};
//公有/特权方法
MyObject.prototype.publicMethod = function(){
privateVariable++;
return privateFunction();
};
})();
var b = new MyObject();
alert(b.publicMethod());

//构建特权方法实例
function apple(){
//私有变量和函数
var name = "orage";
function color(){
return name;
}
//构建特权方法
//apple.prototype.method = function(){
this.method = function(){
return color();
}
}
var app = new apple();
alert(app.method());

(function(){
var name = ""; //这是公有的变量,所有实例都共享这个变量
//var name = "" //注释这个,方便下面实现实例有自己的私有变量
Person = function(value){
name = value;
//this.name = value; //这样每个实例都有自己的私有变量
};
Person.prototype.getName = function(){
return name;
//return this.name;
};
Person.prototype.setName = function (value){
name = value;
//this.name = value;
};
})();
var person1 = new Person("Nicholas");
//alert(person1.getName()); //"Nicholas"
//person1.setName("Greg");
//alert(person1.getName()); //"Greg"
var person2 = new Person("Michael");
alert(person1.getName()); //"Michael"
alert(person2.getName()); //"Michael"

//模块模式
</script>
-->

<!-- 面向对象之window对象篇
<script>
//
location.replace("http://www.wrox.com/"); //url跳转到这个地址之后,浏览器后退功能被禁止
location.reload(); //重新加载(有可能从缓存中加载)
location.reload(true); //重新加载(从服务器重新加载)
</script>
-->

<!-- 面向对象之客户端检测篇

<script>
//以下是完整的用户代理字符串检测脚本,包括检测呈现引擎、平台、Windows操作系统、移动设备和游戏系统。
var client = function(){
//呈现引擎
var engine = {
ie: 0,
gecko: 0,
webkit: 0,
khtml: 0,
opera: 0,
//完整的版本号
ver: null
};
//浏览器
var browser = {
//主要浏览器
ie: 0,
firefox: 0,
safari: 0,
konq: 0,
opera: 0,
chrome: 0,
//具体的版本号
ver: null
};
//平台、设备和操作系统
var system = {
win: false,
mac: false,
x11: false,
//移动设备
iphone: false,
ipod: false,
ipad: false,
ios: false,
android: false,
nokiaN: false,
winMobile: false,
//游戏系统
wii: false,
ps: false
};
//检测呈现引擎和浏览器
var ua = navigator.userAgent;
if (window.opera){
engine.ver = browser.ver = window.opera.version();
engine.opera = browser.opera = parseFloat(engine.ver);
} else if (/AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
//确定是 Chrome 还是 Safari
if (/Chrome\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.chrome = parseFloat(browser.ver);
} else if (/Version\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.safari = parseFloat(browser.ver);
} else {
//近似地确定版本号
var safariVersion = 1;
if (engine.webkit < 100){
safariVersion = 1;
} else if (engine.webkit < 312){
safariVersion = 1.2;
} else if (engine.webkit < 412){
safariVersion = 1.3;
} else {
safariVersion = 2;
}
browser.safari = browser.ver = safariVersion;
} else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
engine.ver = browser.ver = RegExp["$1"];
engine.khtml = browser.konq = parseFloat(engine.ver);
} else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
engine.ver = RegExp["$1"];
engine.gecko = parseFloat(engine.ver);
//确定是不是 Firefox
if (/Firefox\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.firefox = parseFloat(browser.ver);
}
} else if (/MSIE ([^;]+)/.test(ua)){
engine.ver = browser.ver = RegExp["$1"];
engine.ie = browser.ie = parseFloat(engine.ver);
}
//检测浏览器
browser.ie = engine.ie;
browser.opera = engine.opera;
//检测平台
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
system.mac = p.indexOf("Mac") == 0;
system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
//检测 Windows 操作系统
if (system.win){
if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)){
if (RegExp["$1"] == "NT"){
switch(RegExp["$2"]){
case "5.0":
system.win = "2000";
break;
case "5.1":
system.win = "XP";
break;
case "6.0":
system.win = "Vista";
break;
case "6.1":
system.win = "7";
break;
default:
system.win = "NT";
break;
}
} else if (RegExp["$1"] == "9x"){
system.win = "ME";
} else {
system.win = RegExp["$1"];
}
}
}
//移动设备
system.iphone = ua.indexOf("iPhone") > -1;
system.ipod = ua.indexOf("iPod") > -1;
system.ipad = ua.indexOf("iPad") > -1;
system.nokiaN = ua.indexOf("NokiaN") > -1;
//windows mobile
if (system.win == "CE"){
system.winMobile = system.win;
} else if (system.win == "Ph"){
if(/Windows Phone OS (\d+.\d+)/.test(ua)){;
system.win = "Phone";
system.winMobile = parseFloat(RegExp["$1"]);
}
}
//检测 iOS 版本
if (system.mac && ua.indexOf("Mobile") > -1){
if (/CPU (?:iPhone )?OS (\d+_\d+)/.test(ua)){
system.ios = parseFloat(RegExp.$1.replace("_", "."));
} else {
system.ios = 2; //不能真正检测出来,所以只能猜测
}
}
//检测 Android 版本
if (/Android (\d+\.\d+)/.test(ua)){
system.android = parseFloat(RegExp.$1);
}
//游戏系统
system.wii = ua.indexOf("Wii") > -1;
system.ps = /playstation/i.test(ua);
//返回这些对象
return {
engine: engine,
browser: browser,
system: system
};
}();
</script>
-->

<!-- 面向对象之DOM篇
<div id="myDiv"><!-A comment -></div>
<ul id="myList"></ul>
<script>
var element = document.createElement("div");
element.className = "message";
element.id = "msg";
element.title = "message11";
element.lang = "en";
element.dir = "dir";
var textNode = document.createTextNode("Hello world, ");
element.appendChild(textNode);
var anotherTextNode = document.createTextNode("EverBody!");
element.appendChild(anotherTextNode);
document.body.appendChild(element);
alert(element.childNodes.length);
element.normalize();//合并文本节点
alert(element.childNodes.length);
alert(element.firstChild.nodeValue);

var newNode = element.firstChild.splitText(5);//分割文本节点
alert(element.firstChild.nodeValue);
alert(newNode.nodeValue);
alert(element.childNodes.length);

//comment
var myDiv = document.getElementById("myDiv");
var comment = myDiv.firstChild;
//alert(comment.data);
alert(comment.nodeValue);

//创建文档片段
var fragment = document.createDocumentFragment();
var ul = document.getElementById("myList");
for(var i=0;i<3;i++){
li = document.createElement("li");
li.appendChild(document.createTextNode("Item" + (i+1)));
fragment.appendChild(li);
}
ul.appendChild(fragment);

//引用外部JS文件
function loadScript(url){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
//script.appendChild(document.createTextNode("111")); //给标签添加内容
script.text = "function sayHi(){alert('hi');}" //检测脚本是否加载完成
document.head.appendChild(script);
}
loadScript("client.js");

//引用外部CSS文件
function loadStyle(url){
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = url;
//var head = document.getElementsByTagName("head")[0]; //getElementsByTagName返回的是nodeList对象列表,索引值从0开始
//head.appendChild(link);
document.head.appendChild(link);
}
loadStyle("style.css");

</script>
-->

<!-- 面向对象之DOM扩展篇
<div style="padding: 20px; overflow:hiddle; position: absolute; left: 200px;">
<div id="offleft" style="width: 100px; height: 100px; margin: 25px; padding: 20px;">saafds</div>
</div>

<div id="div1">
<p><b>Hello</b> world!</p>
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
</div>

<script>
//取得元素的左和上偏移量
function getElementLeft(element){
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while (current != null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
var offid = document.getElementById("offleft");
var offleft = getElementLeft(offid);
alert(offleft);

function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current != null){
actualTop += current.offsetTop;
current = current.offsetParent;
}
return actualTop;
}
var offtop = getElementTop(offid);
alert(offtop);

//封
function getElementOffSet(element){
var actualLeft = element.offsetLeft;
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current != null){
actualLeft += current.offsetLeft;
actualTop += current.offsetTop;
current = current.offsetParent;
}
return {
offsetLeft:actualLeft,
offsetTop:actualTop
}
}
var offset = getElementOffSet(offid);
alert(offset.offsetLeft+" + "+offset.offsetTop);

//取得元素的客户区大小(封)
function getViewport(element){
if(document.compatMode == "BackCompat"){
return {
width:element.clientWidth,
height:element.clientHeight
};
}else{
return{
width:element.clientWidth,
height:element.clientHeight
}
}
}
var getViewport = getViewport(offid);
alert(getViewport.width + "+" + getViewport.height);

//取得滚动条的位置
function scrollToTop(element){
if(element.scrollTop != 0){
element.scrollTop = 0;
}
}
var scrolltop = scrollToTop(offid);

//遍历所有元素的标签
var div = document.getElementById("div1");
/* 用来过滤,只遍历出li标签
var filter = function(node){
return node.tagName.toLowerCase() == "li" ?NodeFilter.FILTER_ACCEPT :NodeFilter.FILTER_SKIP;
};
var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT,filter, false);
*/
var iterator = document.createNodeIterator(div,NodeFilter.SHOW_ELEMENT,null,false);
var node = iterator.nextNode();
while(node != null){
alert(node.tagName);
node = iterator.nextNode();
}
</script>
-->

<!-- 面向对象之事件篇
<div id="myBtn">button</div>
<a href="http://www.baidu.com" id="link">baidu</a>
<ul id="nav">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
<div style="width: 150px; height: 150px; background: #ccc;" id="parentid">
<div style="width: 100px; height: 100px; background: #ff5200;" id="childrenid">stopPropagation</div>
</div>
<div id="eventPhase">eventPhase</div>
<div id="div_position" style="width:150px; background: #ccc; height: 150px; margin:50px;">客户区位置</div>
<div id="divedit">divedit</div>
<div id="myrelate" style="background-color:red;height:100px;width:100px;">relatedTarget</div>
<br/><br/>
<input id="myText" name="text" type="text">
<br/><br/>
<ul id="myList">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>

<div id="myDiv">Right click or Ctrl+click me to get a custom context menu.
Click anywhere else to get the default context menu.</div>
<ul id="myMenu" style="position:absolute;visibility:hidden;background-color:
silver">
<li><a href="http://www.nczonline.net">Nicholas’ site</a></li>
<li><a href="http://www.wrox.com">Wrox site</a></li>
<li><a href="http://www.yahoo.com">Yahoo!</a></li>
</ul>

<div id="device" style="width: 100px; height: 100px; background: #ccc;">1111</div>

<div id="output" style="width: 100px; height: 100px;">output</div>

<ul id="myLinks">
<li id="goSomewhere">Go somewhere</li>
<li id="doSomething">Do something</li>
<li id="sayHi" title="sayhi" class="sayhi" type="121212">Say hi</li>
</ul>

<div id="myInput">
<input type="button" value="Click Me" id="myInputs">
</div>

<script>
//
var btn = document.getElementById("myBtn");
/*btn.addEventListener("click",function(){
alert(this.id);
},false);
btn.addEventListener("click",function(){
alert("hello world");
},false);

btn.removeEventListener("click",function(){
alert("hello world"); //这种取消绑定事件是无效的,
},false);

var handler = function(){
alert("大家好");
}
btn.addEventListener("click",handler,false);
btn.removeEventListener("click",handler,false); //取消绑定是有效的,
*/
/* //在IE8及以下运行
//IE的两个方法:attachEvent()和 detachEvent(),是在全局作用域下执行,
btn.attachEvent("onclick",function(){
alert(this === window);
});
btn.attachEvent("onclick",handler);
btn.detachEvent("onclick",handler);
*/
//跨浏览器事件处理程序
var EventUtil = {
addHandler : function (element, type, handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
} else if(element.attachEvent){
element.attachEvent("on"+type,handler);
} else{
element["on"+type] = handler;
}
},
removeHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
} else if(element.attachEvent){
element.attachEvent("on"+type,handler);
} else{
element["on"+type] = null;
}
},
//EventUtil 方法之一:getEvent(),它返回对 event对象的引用
getEvent: function(event){
return event ? event : window.event;
},

//EventUtil 方法之二:getTarget(),它返回事件的目标
getTarget: function(event){
return event.target || event.srcElement;
},

//EventUtil 方法之三:preventDefault(),用于取消事件的默认行为
preventDefault: function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},

//EventUtil 方法之四:stopPropagation(),首先尝试使用 DOM 方法阻止事件流,否则就使用 cancelBubble 属性
stopPropagation: function(event){
if(event.stopPropagation){
event.stopPropagation();
} else{
event.cancelBubble = true;
}
}

//EventUtil 方法之五:relatedTarget 属性提供了相关元素的信息
/*getRelatedTarget: function(event){
if (event.relatedTarget){
return event.relatedTarget;
} else if (event.toElement){
return event.toElement;
} else if (event.fromElement){
return event.fromElement;
} else {
return null;
}
}*/
};
//EventUtil.addHandler(btn,"click",handler);
//EventUtil.removeHandler(btn,"click",handler); //移除事件

//事件
btn.onclick = function(event){
alert(event.type);
};
btn.addEventListener("click",function(event){
alert(event.type);
},false);

/* //DOM中的事件对象
document.body.onclick = function(event){
alert(event.currentTarget === document.body);
alert(this === document.body);
alert(event.target === document.getElementById("myBtn"));
}
*/
//阻止事件执行
var link = document.getElementById("link");
link.onclick = function(event){
event.preventDefault(); //阻止事件执行
}

//阻止事件往上冒泡
var parentid = document.getElementById("parentid");
parentid.onclick = function(event){
alert(this.id);
event.stopPropagation();
}
var childrenid = document.getElementById("childrenid");
childrenid.onclick = function(event){
alert(this.id);
event.stopPropagation(); //阻止事件往上冒泡
}
document.body.onclick = function(event){
//alert("body");
}

/* //监测事件处在事件流的哪个阶段
var eventPhase = document.getElementById("eventPhase");
eventPhase.onclick = function(event){
alert(event.eventPhase); //处于目标对象上 2
};
document.body.addEventListener("click",function(event){
alert(event.eventPhase); //处于捕获阶段 1
},true);
document.body.onclick = function(event){
alert(event.eventPhase); //处于冒泡阶段 3
}
*/
//
EventUtil.addHandler(window,"load",function(){
var script = document.createElement("script");
EventUtil.addHandler(script,"load",function(event){
alert("loading");
});
script.src = "example.js";
document.head.appendChild(script);
})
EventUtil.addHandler(window,"resize",function(event){
//alert("resizing");
})

//取得客户区坐标位置
var my_position = document.getElementById("div_position");
EventUtil.addHandler(my_position,"click",function(event){
event = EventUtil.getEvent(event); //这一行代码添加到事件处理程序的开头,就可以确保随时都能使用 event 对象,而不必担心用户使用的是什么浏览器
alert("Client coordinates: " + event.clientX + "," + event.clientY);
event.stopPropagation();
});

//修改键
var divedit = document.getElementById("divedit");
EventUtil.addHandler(divedit,"click",function(event){
event = EventUtil.getEvent(event);
var keys = [];
if(event.shiftKey){
keys.push("shift");
}
if(event.ctrlKey){
keys.push("ctrl");
}
if(event.altKey){
keys.push("alt");
}
if(event.metaKey){
keys.push("meta");
}
console.log("Keys " + keys.join(","));
})

//相关元素
//EventUtil 方法之五(扩展方式):relatedTarget 属性提供了相关元素的信息
EventUtil.getRelatedTarget = function(event){
if (event.relatedTarget){
return event.relatedTarget;
} else if (event.toElement){
return event.toElement;
} else if (event.fromElement){
return event.fromElement;
} else {
return null;
}
}

var myrelate = document.getElementById("myrelate");
EventUtil.addHandler(myrelate,"mouseout",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
var relatedTarget = EventUtil.getRelatedTarget(event);
console.log("Moused out of " + target.tagName + " to " + relatedTarget.tagName);
});

EventUtil.getButton = function(event){
if(document.implementation.hasFeature("MouseEvents","2.0")){
return event.button;
}else{
switch(event.button){
case 0:
case 1:
case 3:
case 5:
case 7:
return 0;
case 2:
case 6:
return 2;
case 4:
return 1;
}
}
};
EventUtil.addHandler(myrelate,"mousedown",function(event){
event = EventUtil.getEvent(event);
console.log(EventUtil.getButton(event));
})

//按下keyup,都会显示keycode的值
var myText = document.getElementById("myText");
EventUtil.addHandler(myText,"keyup",function(event){
event = EventUtil.getEvent(event);
console.log(event.keyCode);
});

//EventUtil 方法之getCharCode 检测charCode属性是否可用,如果不可用,则用keyCode
EventUtil.getCharCode = function(event){
if(typeof event.charCode == "number"){
return event.charCode;
}else{
return event.keyCode;
}
}

EventUtil.addHandler(myText,"keypress",function(event){
event = EventUtil.getEvent(event);
console.log(EventUtil.getCharCode(event));
});

/* //变动事件之删除节点
EventUtil.addHandler(window,"load",function(event){
var myList = document.getElementById("myList");
EventUtil.addHandler(document,"DOMSubtreeModified",function(event){
console.log(event.type);
console.log(event.target);
});
EventUtil.addHandler(document,"DOMNodeRemoved",function(event){
console.log(event.type);
console.log(event.target);
console.log(event.relatedNode);
});
EventUtil.addHandler(myList.firstChild,"DOMNodeRemovedFromDocument",function(event){
console.log(event.type);
console.log(event.target);
});
myList.parentNode.removeChild(myList);
})*/

//H5事件之contextmenu
EventUtil.addHandler(window, "load", function(event){
var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "contextmenu", function(event){
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);
var menu = document.getElementById("myMenu");
menu.style.left = event.clientX + "px";
menu.style.top = event.clientY + "px";
menu.style.visibility = "visible";
});
EventUtil.addHandler(document, "click", function(event){
document.getElementById("myMenu").style.visibility = "hidden";
});
});

//H5事件之beforeunload
EventUtil.addHandler(window,"beforeunload",function(event){
event = EventUtil.getEvent(event);
var message = "I'm really going to miss you if you go.";
//event.returnValue = message;
return message;
});

//H5事件之DOMContentLoaded
EventUtil.addHandler(document,"DOMContentLoaded",function(event){
alert("content loaded");
});

//readystatechange
EventUtil.addHandler(document,"readystatechange",function(event){
if(document.readyState == "interactive"){
console.log("处在交互阶段!"); //判断事件所处的阶段
}
});

//H5事件之pageshow
(function(){
var showCount = 0;
EventUtil.addHandler(window,"load",function(){
console.log("load fired");
});
EventUtil.addHandler(window,"pageshow",function(event){
showCount++;
console.log("show has been fired " + showCount + "times. Persisted? " + event.persisted);
})
})();

//H5事件之hashchange
EventUtil.addHandler(window, "hashchange", function(event){
//alert("old url: " + event.oldURL + "\nNew Url: " + event.newURL);
//alert("Current hash: " + location.hash);
});
EventUtil.addHandler(window,"click",function(){
location.hash = "mao and i shi da niu";
});

//device事件之orientationchange
EventUtil.addHandler(window,"load",function(event){
var device = document.getElementById("device");
//要在手机或者平板上测试
device.innerHTML = "Current orientation is " + window.orientation;
EventUtil.addHandler(window,"orientationchange",function(event){
device.innerHTML = "Current orientation is " + window.orientation;
});
});

function hengshuping(){
alert(window.orientation);
if(window.orientation==0){
alert("竖屏状态!"); //要在手机或者平板上测试
}
if(window.orientation==90||window.orientation==-90){
alert("横屏状态!");
}
}
hengshuping();

//device事件之MozOrientation
EventUtil.addHandler(window,"MozOrientation",function(event){
var output = document.getElementById("output");
//当设备的加速计检测到设备方向改变时,就会触发这个事件
output.innerHTML = "X=" + event.x + ", Y=" + event.y + "Z=" + event.Z + "<br/>";
});

//device事件之deviceorientation
EventUtil.addHandler(window,"deviceorientation",function(event){
var output = document.getElementById("output");
output.innerHTML = "Alpha=" + event.alpha + "Beta=" + event.beta + ", Gamma =" + event.gamma + "<br/>";
output.style.webkitTransform = "rotate(" + Math.round(event.alpha) + "deg)";
});

//device事件之devicemotion
EventUtil.addHandler(window,"devicemotion",function(event){
var output = document.getElementById("output");
if(event.rotationRate !== null){
output.innerHTML +="Alpha=" + event.rotationRate.alpha + ", Beta=" + event.rotationRate.beta + ", Gamma=" + event.rotationRate.gamma;
}
});

//device事件之touch

//跟踪用户对屏幕的触摸操作
function handleTouchEvent(event){
//只跟踪一次触摸
if(event.touches.length == 1){
var output = document.getElementById("output");
switch(event.type){
case "touchstart":
output.innerHTML = "Touch started (" + event.touches[0].clientX + "," + event.touches[0].clientY + ")";
break;
case "touchend":
output.innerHTML += "<br>Touch ended (" + event.changedTouches[0].clientX + "," + event.changedTouches[0].clientY + ")";
break;
case "touchmove":
event.preventDefault(); //阻止滚动
output.innerHTML += "<br>Touch moved (" + event.changedTouches[0].clientX + "," + event.changedTouches[0].clientY + ")";
break;
}
}
}
EventUtil.addHandler(document,"touchstart",handleTouchEvent);
EventUtil.addHandler(document,"touchend",handleTouchEvent);
EventUtil.addHandler(document,"touchmove",handleTouchEvent);

//手势事件 iOS 2.0 中的 Safari 还引入了一组手势事件。
function handleGestureEvent(event){
var output = document.getElementById("output");
switch(event.type){
case "gesturestart":
output.innerHTML = "Gesture started (rotation=" + event.rotation +
",scale=" + event.scale + ")";
break;
case "gestureend":
output.innerHTML += "<br>Gesture ended (rotation=" + event.rotation +
",scale=" + event.scale + ")";
break;
case "gesturechange":
output.innerHTML += "<br>Gesture changed (rotation=" + event.rotation +
",scale=" + event.scale + ")";
break;
}
}
document.addEventListener("gesturestart", handleGestureEvent, false);
document.addEventListener("gestureend", handleGestureEvent, false);
document.addEventListener("gesturechange", handleGestureEvent, false);

//事件委托/事件代理
var lists = document.getElementById("myLinks");
EventUtil.addHandler(lists,"click",function(event){ //lists可以用document替代
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//console.dir(target); //查看该事件的详细信息包括属性,方法等

switch (target.id){
case "doSomething":
document.title = "I changed the document's title";
break;

case "goSomewhere":
location.href = "http://www.baidu.com";
break;

case "sayHi":
console.log("hi");
break;
}
});

//移除事件处理程序
var myInputs = document.getElementById("myInputs");
myInputs.onclick = function(event){
//alert(event.target.id);
myInputs.onclick = null //移除事件处理程序
//注意,在事件处理程序中删除按钮也能阻止事件冒泡。目标元素在文档中是事件冒泡的前提。
document.getElementById("myInput").innerHTML = "Processing...";
}

//采用事件委托方式来实现上个例子的功能
var myInput = document.getElementById("myInput");
EventUtil.addHandler(myInput,"click",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if (target.id == "myInputs") {
document.getElementById("myInput").innerHTML = "Processing...";
};
})

//模拟事件
var myInputs = document.getElementById("myInputs");
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,
false, false, false, false, 0, null);
myInputs.dispatchEvent(event); //模拟对鼠标进行点击

/*错误的写法
function element_li(){
var elementArray = [];
var nav = document.getElementById("nav");
var nav_list = nav.getElementsByTagName("li");
for(var i=0;i<nav_list.length;i++){
elementArray.push(i);
}
return elementArray;
}
var i = element_li();
var li = document.getElementsByTagName("li")[i];
li.addEventListener("click",function(){
alert(i);
},false);*/

window.onload = function(){
var nav = document.getElementById("nav");
var nav_list = nav.getElementsByTagName("li");
var len = nav_list.length;
//使用event.target方法
for(var i=0;i<len;i++){
nav_list[i]['data_id'] = i; //给nav_list对象增加一个名字为data_id的属性字段
//nav_list[i].onclick = function(event){
//alert(event.target.data_id);
//console.log(event.currentTarget.tagName)
//}
}
nav.onclick = function(event){
console.log(event.target.data_id);//调用这个对象的属性字段
//console.dir(document); //打印出这个对象的属性和方法
//console.log(event.currentTarget.tagName) //返回绑定的节点
}

/*
for(var i=0;i<len;i++){
//闭包方式
(function(k){
//nav_list[k].addEventListener("click",function(){
nav_list.item(k).addEventListener("click",function(){
alert(k);
},false);
})(i)

//直接引用事件
//nav_list[i]._index = i;
//nav_list[i].onclick = function(){
//alert(this._index + 1);
//}

//绑定事件
//nav_list[i].addEventListener("click",function(){
//alert(this._index + 1);
//console.log(this._index + 1);
//},false);
}*/
}
</script>
-->

<!-- 面向对象之表单脚本篇
<form id="myForm">
<input type="text" autofocus>
<input type="text" name="input" value="111">
<input type="text" name="blurs" value="blur">
<input type="submit" name="submit_btn">
<p><input type="text" size="25" maxlength="50" value="max" name="maxinput"></p>
<input type="text" name="tel1" id="txtTel1" maxlength="3">
<input type="text" name="tel2" id="txtTel2" maxlength="3">
<input type="text" name="tel3" id="txtTel3" maxlength="4">
<select name="location" id="selLocation">
<option value="Sunnyvale, CA">Sunnyvale</option>
<option value="Los Angeles, CA">Los Angeles</option>
<option value="Mountain View, CA">Mountain View</option>
<option value="">China</option>
<option>Australia</option>
</select>
<select name="location1" id="selLocation1">
<option value="1111, CA">1111</option>
</select>
</form>
<div class="editable" onclick='document.execCommand("createlink",false,"http://www.baidu.com");' id="richedit" contenteditable>11212</div>
<div class="editable" onclick='document.execCommand("italic",false,null);' contenteditable>333502</div>
<iframe name="richedit" style="height:100px;width:100px;" src="111.html"></iframe>
<script>
//
var EventUtil = {
addHandler : function (element, type, handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
} else if(element.attachEvent){
element.attachEvent("on"+type,handler);
} else{
element["on"+type] = handler;
}
},
getEvent: function(event){
return event ? event : window.event;
},
getTarget: function(event){
return event.target || event.srcElement;
},
preventDefault: function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
}
}

var form = document.getElementById("myForm");
var field = form.elements[1]; //替代写法form.elements['input'];
field.value = "Another value";
field.focus();
field.disabled = true;
//field.type = "checkbox"; //动态修改type属性

//避免多次提交表单
EventUtil.addHandler(form,"submit",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
var btn = target.elements["submit_btn"];
btn.disabled = true;
});

EventUtil.addHandler(window,"load",function(event){
var element = document.forms[0].elements[0];
//element.focus();
if (element.autofocus !== true) {
element.focus();
console.log("JS focus");
};
})

var blurs = document.forms[0].elements['blurs'];
EventUtil.addHandler(blurs,"focus",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if(target.style.backgroundColor != "red"){
target.style.backgroundColor = "yellow";
}
});
/*EventUtil.addHandler(blurs,"blur",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if(/[^\d]/.test(target.value)){
target.style.backgroundColor = "red";
}else{
target.style.backgroundColor = "";
}
});*/
EventUtil.addHandler(blurs,"change",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if(/[^\d]/.test(target.value)){//返回布尔值,用于匹配取到的值和正则
target.style.backgroundColor = "pink";
}else{
target.style.backgroundColor = "";
}
});

var maxinput = document.forms[0].elements['maxinput'];
//console.log(maxinput.value);
//maxinput.value = "abcde";
//maxinput.select();
EventUtil.addHandler(maxinput,"select",function(event){
console.log("Text selected: " + maxinput.value);
});

//取得选择的文本
var maxinput = document.forms[0].elements['maxinput'];
function getSelectedText(textbox){
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
};
//方法一:封装一个回调函数
function printSelectedText(){
var text = getSelectedText(maxinput);
console.log(text);
}
//EventUtil.addHandler(maxinput,"select",printSelectedText);

//方法二:内部函数调用方式
EventUtil.addHandler(maxinput,"select",function(event){
function getSelectedText(textbox){
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
};
var text = getSelectedText(maxinput);
console.log(text);
});

//方法三:普通调用方式
/*EventUtil.addHandler(maxinput,"select",function(event){
console.log(maxinput.value.substring(maxinput.selectionStart, maxinput.selectionEnd));
});*/

//选择部分文本的方法 setSelectionRange
maxinput.value = "Hello world!";
//var text2 = maxinput.setSelectionRange(0,maxinput.value.length);
//var text2 = maxinput.setSelectionRange(0,3);
var text2 = maxinput.setSelectionRange(3,6);
console.log(text2);

/*//IE8- 选择部分文本的方法 createTextRange
var range = maxinput.createTextRange();
range.collapse(true);
range.moveStart("character",0);
range.moveEnd("character",maxinput.value.length);
range.select();

//跨浏览器
function selectText(textbox,startIndex,stopIndex){
if(textbox.setSelectionRange){
textbox.setSelectionRange(startIndex,stopIndex);
}else if(textbox.createTextRange){
var range = textbox.createTextRange();
range.collapse(true);
range.moveStart("character",startIndex);
range.moveEnd("character",stopIndex-startIndex);
range.select();
}
textbox.focus();
}
textbox.value = "Hello world!";
selectText(textbox,0,textbox.value.length);
selectText(textbox,0,3);
selectText(textbox,3,7);*/

//输入框之屏蔽字符
EventUtil.getCharCode = function(event){
if(typeof event.charCode == "number"){
return event.charCode;
}else{
return event.keyCode;
}
};
EventUtil.addHandler(maxinput,"keypress",function(event){
event = EventUtil.getEvent(event);
//EventUtil.preventDefault(event); //屏蔽了所有按键操作
var target = EventUtil.getTarget(event);
var charCode = EventUtil.getCharCode(event);
//alert(charCode);
if(!/\d/.test(String.fromCharCode(charCode)) && charCode<9 && !event.ctrlKey){
EventUtil.preventDefault(event);
}
});

//自动切换焦点
(function(){
function tabForward(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if(target.value.length == target.maxLength){
var form = target.form;
var len =form.elements.length;
for(var i=0;i<len;i++){
if(form.elements[i] == target){
if(form.elements[i+1]){
form.elements[i+1].focus();
}
return;
}
}
}
}
var textbox1 = document.getElementById("txtTel1");
var textbox2 = document.getElementById("txtTel2");
var textbox3 = document.getElementById("txtTel3");

EventUtil.addHandler(textbox1,"keyup",tabForward);
EventUtil.addHandler(textbox2,"keyup",tabForward);
EventUtil.addHandler(textbox3,"keyup",tabForward);
})();

//select
var selectbox = document.forms[0].elements["location"];
var text = selectbox.options[0].text;
var value = selectbox.options[0].value;
var selectedIndex = selectbox.selectedIndex;
var selectedOption = selectbox.options[selectedIndex];
//alert("Select index: " + selectedIndex + "\nSelected text: " + selectedOption.text + "\nSelected value: " + selectedOption.value);
function getSelectedOptions(selectbox){
var result = [];
var option = null;
var len = selectbox.options.length;
for(var i=0;i<len;i++){
option = selectbox.options[i];
if(option.selected){
result.push(option);
}
}
return result;
}

var selectbox = document.getElementById("selLocation");
var selectedOptions = getSelectedOptions(selectbox);
var len = selectedOptions.length;
var message = "";
for(var i=0;i<len;i++){
message += "Selected index: " + selectedOptions[i].index +
"\nSelected text: " + selectedOptions[i].text +
"\nSelected value: " + selectedOptions[i].value + "\n\n";
}
alert(message);

//动态创建option
//方法一:dom方法,
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("Option text"));
newOption.setAttribute("value","Option value");
selectbox.appendChild(newOption);

//方法二:构造函数 在IE8-中有问题,
var newOption1 = new Option("Option text1","Option value1");
selectbox.appendChild(newOption1);

//方法三:add()方法,最佳方案
var newOption2 = new Option("Option text2","Option value2");
selectbox.add(newOption2,undefined);

//动态移除option
//selectbox.removeChild(selectbox.options[0]); //方法一
//selectbox.remove(0); //方法二
//selectbox.options[0] = null; //方法三
//清除所有选项
function clearSelectbox(selectbox){
for(var i=0,len=selectbox.options.length;i<len;i++){
selectbox.remove(i);
}
}

//动态移动
var selectbox = document.getElementById("selLocation");
var selectbox1 = document.getElementById("selLocation1");
selectbox1.appendChild(selectbox.options[0]);

//移动到任意位置
var optionToMove = selectbox.options[1];
selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index-1]);

//富文本编辑之打开关闭
var editDiv = document.getElementById("richedit");
editDiv.contentEditable = "true";

EventUtil.addHandler(window,"load",function(){
frames["richedit"].document.designMode = "on";
});

//编辑富文本
document.execCommand("bold",false,null);
document.execCommand("italic",false,null);
//frames["richedit"].document.execCommand("italic",false,null);
document.execCommand("createlink",false,"http://www.baidu.com");

</script>
-->

<!-- 面向对象之html5编程篇

<div class="mediaplayer">
<div class="video">
<video id="player" src="movie.mov" poster="mymovie.jpg"
width="300" height="200">
Video player not available.
</video>
</div>
<div class="controls">
<input type="button" value="Play" id="video-btn">
<span id="curtime">0</span>/<span id="duration">0</span>
</div>
</div>

<script>
var player = document.getElementById("player");
var curtime = document.getElementById("video-btn");
var duration = document.getElementById("duration");

duration.innerHTML = player.duration;
EventUtil.addHandler(btn,"click",function(event){
if(player.paused){
player.play();
btn.value = "Pause";
}else{
player.pause();
btn.value = "Play";
}
});

setInterval(function(){
curtime.innerHTML = player.currentTime;
},250);

//检测编解码器的支持情况
var audio = document.getElementById("audio-player");
if(audio.canplayType("audio/mpeg")){
//进一步处理代码
}

if(audio.canplayType("audio/ogg; codecs=\"vorbis\"")){
//进一步处理代码
}

//Audio 自带一个原生的构造函数
var audio = new Audio("sound.mp3");
EventUtil.addHandler(audio,"canplaythrough",function(event){
audio.play();
});

//历史状态管理
//先要用pushState创建一个假的utl,否则单击刷新按钮会导致404错误
history.pushState({name:"Nichilas"},"Nicholas'page","nicholas.html");
EventUtil.addHandler(window,"popstate",function(event){
var state = event.state;
if(state){
processState(state);
}
})
//更新当前状态
history.replaceState({name:"Greg"},"Greg's page");
</script>
-->

<!-- 面向对象之canvas篇
<img src="data:image/sp1.png">
<canvas id="drawing" width=" 200" height="200">A drawing of something.</canvas>
<canvas id="times" width=" 200" height="200">A drawing of something.</canvas>
<canvas id="images" width=" 200" height="200">A drawing of something.</canvas>
<canvas id="filter" width=" 400" height="400">A drawing of something.</canvas>
<script>
var drawing = document.getElementById("drawing");
//导入画布中的图像
/*if(drawing.getContext){
var imgURI = drawing.toDataURL("image/png");
var image = document.createElement("img");
image.src = imgURI;
document.body.appendChild(image);
} */

if(drawing.getContext){
var context = drawing.getContext("2d");
//context.strokeStyle = "red";
context.fillStyle = "#ff0000";
context.fillRect(10,10,50,50);
context.fillStyle = "rgba(0,0,255,0.5)";
context.fillRect(30,30,50,50);
//清除一个小矩形
context.clearRect(40,40,10,10);

context.strokeStyle = "red";
context.strokeRect(100,10,50,50);
context.strokeStyle = "rgba(0,0,255,0.5)";
context.strokeRect(120,30,50,50);

/*//restore
context.fillStyle = "red";
context.save();

context.fillStyle = "#00ff00";
context.translate(100,100);
context.save();

context.fillStyle = "#0000ff";
context.fillRect(10,150,50,50);

context.restore();
context.fillRect(20,170,50,50);

context.restore();
context.fillRect(30,180,50,50);*/

//设置阴影
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
context.shadowBlur = 4;
context.shadowColor = "rgba(0,0,0,0.5)";

context.fillStyle = "#ff0000";
context.fillRect (10,100,50,50);

context.fillStyle = "rgba(0,0,255,1)";
context.fillRect(80,100,50,50);

}

var times = document.getElementById("times");
if(times.getContext){
var context = times.getContext("2d");
//绘制一个不带数字的时钟表盘
context.beginPath();
//绘制外圆
context.arc(100,100,99,0,2*Math.PI,false);
//绘制内圆
context.moveTo(194,100);
context.arc(100,100,94,2*Math.PI,false);
//绘制分针
context.moveTo(100,100);
context.lineTo(100,25);
//绘制时针
context.moveTo(100,100);
context.lineTo(35,100);
//描边路径
context.stroke();

context.font = "bold 14px Arial";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("12",100,20);
context.fillText("3",180,100);
context.fillText("6",100,180);
context.fillText("9",20,100);
}

//绘制图像
var images = document.getElementById("images");
if(images.getContext){
var context = images.getContext("2d");
var image = document.images[0];
context.drawImage(image,10,10);
context.drawImage(image,50,10,20,30);
context.drawImage(image,0,10,50,50,0,100,40,60);
}

//渐变
var filter = document.getElementById("filter");
function createRectLinearGradient(context, x, y, width, height){
return context.createLinearGradient(x, y, x+width, y+height);
}
if(filter.getContext){
var context = filter.getContext("2d");
var gradient = createRectLinearGradient(context,30,30,50,50);
gradient.addColorStop(0,"white");
gradient.addColorStop(1,"black");

context.fillStyle = "#ff0000";
context.fillRect(10,10,50,50);

context.fillStyle = gradient;
context.fillRect(30,30,50,50);

context.fillStyle = gradient;
context.fillRect(50,50,50,50);

//径向渐变
var gradient = context.createRadialGradient(55, 55, 10, 55, 55, 30);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
//绘制红色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
//绘制渐变矩形
context.fillStyle = gradient;
context.fillRect(30, 30, 50, 50);
}

</script>
-->

<!-- 面向对象之错误处理与调试篇
<script>
function CustomError(message){
this.name = "CustomError";
this.message = "message";
}
//CustomError.prototype = new Error();
//throw new CustomError("My message");

function process(values){
values.sort();
for(var i=0,len=values.length;i<len;i++){
if(values[i]>100){
return values[i];
}
}
return -1;
}
//process("message"); //抛出错误
process([1,2,3,4]);

//处理图像错误

var image = new Image();
EventUtil.addHandler(image,"load",function(event){
alert("Image loaded!");
});
EventUtil.addHandler(image,"error",function(event){
alert("Image not loaded");
});
//image.src = "add.png"; //加载成功
image.src = "smilex.gif"; //抛出错误

function getQueryString(url){
if(typeof url == "string"){
var pos = url.indexOf("?");
if(pos > -1){
return url.substring(pos + 1);
}
}
return "";
}
var aa = getQueryString("http://www.baidu.com?abcde");
alert(aa);

function reverseSort(values){
if(values instanceof Array){ //基本类型的值应该使用 typeof 来检测,而对象的值则应该使用 instanceof 来检测
values.sort();
values.reverse();
}
}

//通信错误
function addQueryStringArg(url,name,value){
if(url.indexOf("?") == -1){
url += "?";
}else{
url += "&";
}
url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
return url;
}
var url = "http:www.somedomain.com";
var newUrl = addQueryStringArg(url,"redir","http://www.somedomain.com?a=b&c=d");
alert(newUrl);

//踌浏览器javascript控制台接口
function log(message){
if(typeof console == "object"){
console.log(message);
}else if(typeof opera == "object"){
opera.postError(message);
}else{
java.lang.System.out.println(message);
}
}

function sum(num1,num2){
log("Entering sum(),arguments are " + num1 + "," + num2);
log("Before calculation");
log("After calculation");
log("Exiting sum()");
var result = num1 + num2;
return result;
}

//输出调试消息
function log(message){
var console = document.getElementById("debuginfo");
if(console === null){
console.id = "debuginfo";
console.style.background = "#dedede";
console.border = "1px solid silver";
console.style.padding = "5px";
console.style.position = "absolute";
console.style.right = "0px";
document.body.appendChild(console);
}
console.innerHTML += "<p>" + message + "</p>";
}

//检测每个参数是否数值(如果有一个不是数值则返回NAN)
function divide(num1,num2){
if(typeof num1 != "number" || typeof num2 != "number"){
thorw new Error("divide():both argument must be number!");
}
return num1/num2;
}

//对于大型应用程序来说,自定义的错误通常都使用 assert()函数抛出
function assert(condition,message){
if(!condition){
throw new Error(message);
}
}

//assert()函数的应用
function divide(num1,num2){
assert(typeof num1 == "number" && typeof num2 == "number"),
"divide():both argument must be number!";
return num1/num2;
}
</script>
-->

<!-- 面向对象之XML篇

<script>
//同步加载
var xmldom = createDocument();
xmldom.async = false;
xmldom.load("example.xml");
if(xmldom.parseError != 0){
//错误处理
}else{
alert(xmldom.documentElement.tagName);
alert(xmldom.documentElement.firstChild.tagName);
var anotherChild = xmldom.createElement("child");
xmldom.documentElement.appendChild(anotherChild);
var children = xmldom.getElementsByTagName("child");
alert(children.length);
alert(xmldom.xml);
}

//跨浏览器处理XML

function parseXml(){
var xmldom = null;
if(typeof DOMParser != "undefined"){
xmldom = (new DOMparser()).parseFromString(xml,"text/xml");
var errors = xmldom.getElementsByTagName("parsererror");
if(errors.length){
throw new Error("XML parsing error:" + errors[0].textContent);
}
}else if(typeof ActiveXObject != "undefined"){
xmldom = createDocument();
xmldom.loadXML(xml);
if(xmldom.parseError != 0){
throw new Error("XML parsing error: " + xmldom.parseError.reason);
}
}else{
throw new Error("NO XML parser available");
}
return xmldom;
}

//应用到案例
var xmldom = null;
try{
xmldom = parseXml("<root><child/></root>");
}catch(ex){
alert(ex.message);
}
//接下来开始对XML进行处理

//序列化xml的另一种跨浏览器写法
function serializeXml(xmldom){
if(typeof XMLSerializer != "undefined"){
return (new XMLSerializer()).serializeToString(xmldom);
}else if(typeof xmldom.xml != "undefined"){
return xmldom.xml;
}else{
throw new Error("Could not serialize XML DOM");
}
}

//跨浏览器使用Xpath
//命名空间对象的字面量表达形式
{
prefix1:"url1",
prefix2:"url2",
prefix3:"url3"
}

//解析针对特定浏览器的命名空间格式
function selectSingleNode(context, expression, namespaces){
var doc = (context.nodeType != 9 ? context.ownerDocument : context);
if (typeof doc.evaluate != "undefined"){
var nsresolver = null;
if (namespaces instanceof Object){
nsresolver = function(prefix){
return namespaces[prefix];
};
}
var result = doc.evaluate(expression, context, nsresolver,
XPathResult.FIRST_ORDERED_NODE_TYPE, null);
return (result !== null ? result.singleNodeValue : null);
} else if (typeof context.selectSingleNode != "undefined"){
//创建命名空间字符串
if (namespaces instanceof Object){
var ns = "";
for (var prefix in namespaces){
if (namespaces.hasOwnProperty(prefix)){
ns += "xmlns:" + prefix + "='" + namespaces[prefix] + "' ";
}
}
doc.setProperty("SelectionNamespaces", ns);
}
return context.selectSingleNode(expression);
} else {
throw new Error("No XPath engine found.");
}
}

//应用新案例
var result = selectSingleNode(xmldom.documentElement, "wrox:book/wrox:author",
{ wrox: "http://www.wrox.com/" });
alert(serializeXml(result));
</script>
-->

<!-- 面向对象之E4X(XML扩展)篇
<script>
var employees = new XML();
employees =<employees>
<employee position="Software Engineer">
<name>Nicholas C. Zakas</name>
</employee>
<employee position="Salesperson">
<name>Jim Smith</name>
</employee>
</employees>;

var firstEmployee = employees.employee[0];
alert(firstEmployee);
alert(employees.employee.length());
</script>
-->

<!-- 面向对象之JSON篇

<script>
var book = {
title:"TOM",
authors:[
"Nicholas"
],
edition:3,
year:2011
/*toJSON:function(){
return this.title;
}*/
};
var jsonText = JSON.stringify(book);
alert(jsonText);

var bookcopy = JSON.parse(jsonText);
//console.log(bookcopy);

//带数组参数的序列化
var jsonText1 = JSON.stringify(book,["title","edition"]);
alert(jsonText1);

//带函数参数的序列化
var jsonText2 = JSON.stringify(book,function(key,value){
switch(key){
case "authors":
return value.join(",");

case "year":
return 5000;

case "edition":
return undefined;

default:
return value;
}
});
alert(jsonText2);

//缩进 同时也会换行
//var jsonText3 = JSON.stringify(book,null,4);
var jsonText3 = JSON.stringify(book,null,"--");
alert(jsonText3);

//parse()方法解析选项
var book1 = {
title:"TOM",
authors:[
"Nicholas"
],
edition:3,
year:2011,
releaseDate:new Date(2011,11,1)
};

var jsondata = JSON.stringify(book1);
var book1copy = JSON.parse(jsondata,function(key,value){
if(key == "releaseDate"){
return new Date(value);
}else{
return value;
}
});

//console.log(book1copy);
alert(book1copy.releaseDate.getFullYear());

</script>
-->

<!-- 面向对象之AJAX与Comet篇

<script>
//创建适用IE各版本的XHR对象的函数
function createXHR(){
if(typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
}else if(typeof ActiveXObject != "undefined"){
if(typeof argument.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len;
for(i=0,len=versions.length;i<len;i++){
try{
new ActiveXObject(versions[i]);
argument.callee.activeXString = versions[i];
break;
}catch(ex){
//跳过
}
}
}
return new ActiveXObject(argument.callee.activeXString);
}else{
throw new Error("No XHR object available");
}
}

//XHR的用法
var xhr = createXHR();
xhr.open("get","example.php",false);
xhr.send(null);
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
}else{
alert("Request was unsuccessful: " + xhr.status);
}

/*
XHR对象的属性简介
1、responseText:作为响应主体被返回的文本。
 2、responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保
存包含着响应数据的 XML DOM 文档。
 3、status:响应的 HTTP 状态。
 4、statusText:HTTP 状态的说明。
*/

/*
XHR对象的readyState属性,表示请求/响应过程的当前活动阶段
0:未初始化。尚未调用 open()方法。
 1:启动。已经调用 open()方法,但尚未调用 send()方法。
 2:发送。已经调用 send()方法,但尚未接收到响应。
 3:接收。已经接收到部分响应数据。
 4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
*/

//跨浏览器兼容性
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
}else{
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("get","example.txt",true);
xhr.setRequestHeader("MyHeader","MyValue"); //成功发送头部信息要在open之后,send之前
xhr.send(null);

//xhr.abort() //取消异步请求

//XHRHttpRequest2(FormData、超时设定、OverrideMimeType()方法)
//进度事件(load事件、progress事件)

//跨源资源共享(CORS)

//跨浏览器CORS请求(通用)
function createCORSRequest(method,url){
var xhr = new XMLHttpRequest();
if("withCredentiais" in xhr){
xhr.open(method,url,true);
}else if(typeof XDomainRequest != "undefined"){
var xhr = new XDomainRequest();
xhr.open(method,url);
}else{
xhr = null;
}
return xhr;
}

//绝对路径是跨源请求,相对路径是同源请求
var request = createCORSRequest("get","http://www.somewhere-else.com/page/");
if(request){
request.onload = function(){
//对request.responeText进行处理
}
request.send();
}

//XMLHttpRequest和XDomainRequest(IE)两个对象被广泛使用,他们共的方法和属性有
//1、abort():用于停止正在进行的请求,
//2、onerror():用于替代onreadystatechange检测错误,
//3、onload:用于替代onreadystatechange检测成功,
//4、responseText:用于取得响应内容,
//5、send():用于发送请求,
//以上成员都包含在createCORSRequest()函数返回的对象中,在所有浏览器中都能正常使用

//图片Ping 通过侦听事件实现跨域通信
var img = new Image();
img.onload = img.onerror = function(){
alert("Done");
}
img.src = "http://www.example.com/test?name=tom";

//JSONP(有两个选项,回调函数和数据,他的优点是可以直接响应和访问数据,缺点是因为访问别的域,所有存在安全性问题,请求失败也无法跟踪)
function handleResponse(response){
alert("You're at IP address " + response.ip + ", which is in " + response.city + "," + response.region_name);
}
var script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script,document.body.firstChild);

//Comet(长轮询和HTTP流)

//1、HTTp流的案例
function createStreamingCilent(url,progress,finished){
var xhr = new XMLHttpRequest(),
received = 0;

xhr.open("get",url,true);
xhr.onreadystatechange = function(){
var result;
if(xhr.readyState == 3){
//只取得最新数据并调整计数器
result = xhr.responseText.substring(received);
received += result.length;

//调用progress回调函数
progress(result);
}else if(xhr.readyState == 4){
finished(xhr.responseText);
}
}
xhr.send(null);
return xhr;
}
var client = createStreamingCilent("streaming.php",function(data){
alert("Received: " + data);
},function(data){
alert("Done!");
})

//Comet的两个新接口

//接口一服务器发送事件(SSE)
var source = new EventSource("myevents.php");
/*EventSource实例有一个readystate属性:
0表示正在接到服务器,
1表示打开链接,
2表示关闭连接,

EventSource实例三个事件:
1、open:在建立连接时触发,
2、message:在从服务器接收到新事件时触发,
3、error:在无法建立链接时触发,
*/
source.onmessage = function(event){
var data = event.data;
}
source.closed //关闭链接

data:foo //数据行后面有空行时,才会触发message事件,因此在服务器上生成事件流时添加这一行,
id:1 //让服务器知道下次该触发哪一个事件,确保浏览器以正确的顺序收到连接的数据段

//web socket
var socket = new WebSocket("ws://www.example.com/server.php");
socket.send("Hello world"); //建立好链接之后,就可以向服务器发送任意字符串了,

//数据序列化
var message = {
time:new Date(),
text:"Hello world",
clientId:"asdfp8734rew"
}
socket.send(JSON.stringify(message));
socket.onmessage = function(event){
var data = event.data;
//处理数据
}

//websocket 还有其他三个事件,三连接生命周期的不同阶段触发
//1、open:在成功建立连接时触发,
//2、error:在发生错误时触发,连接不能持续,
//3、close:在连接关闭时触发,

//这三个事件案例的应用
var socket = new WebSocket("ws://www.example.com/server.php");
socket.onopen = function(){
alert("Connection established.");
};
socket.onerror = function(){
alert("Connection error.");
};
socket.onclose = function(){
alert("Connection closed.");
};

//这三个事件中只有close事件有三个额外属性
socket.onclose = function(event){
console.log("Was clean? " + event.wasClean + "Code=" + event.code + "Reason=" + event.reason);
};
</script>
-->

<!-- 面向对象之高级技巧篇
<div id="my_btn">button</div>
<div class="draggable" style="position:absolute; background:red; height:50px; width: 50px;"> </div>
<script>
//函数绑定
var handler = {
message:"Event handled",
handleClick:function(event){
alert(this.message);
}
};

var btn = document.getElementById("my_btn");
//undefined 没有保存环境的原因,
EventUtil.addHandler(btn,"click",handler.handleClick);
//用匿名函数解决
EventUtil.addHandler(btn,"click",function(event){
handler.handleClick();
});
//用bind方法解决
function bind(fn,context){
return function(){
return fn.apply(context,arguments);
};
}

var handler1 = {
message:"Event handled",
handleClick:function(event){
alert(this.message + ":" + event.type);
}
};
EventUtil.addHandler(btn,"click",bind(handler1.handleClick,handler1));
//ECMAScript5为所有函数定义了一个bind()方法,
EventUtil.addHandler(btn,"click",handler1.handleClick.bind(handler1));

//不可扩展对象(preventExtensions)
var person = {name:"TOM"};
//person.age = 29; //添加属性
Object.preventExtensions(person); //不能再给对象添加属性和方法
person.age = 30;
alert(person.age); //undefined

//密封的对象(seal)
Object.seal(person);
person.age = 31;
alert(person.age);

//已有的成员属性也不可以修改或者删除
delete person.name;
alert(person.name);

//冻结的对象(freeze)
Object.freeze(person);
person.age = 23;
alert(person.age);//undefined
delete person.name;
alert(person.name);//TOM
person.name = "still";
alert(person.name);//TOM

//高级定时器
//定时器对队列的工作方式是,当特定时间过去后将代码插入。注意,给队列添加代码并不意味着对它立刻执行,而只能表示它会尽快执行。设定一个 150ms 后执行的定时器不代表到了 150ms代码就立刻执行,它表示代码会在 150ms 后被加入到队列中。如果在这个时间点上,队列中没有其他东西,那么这段代码就会被执行,表面上看上去好像代码就在精确指定的时间点上执行了

var btn = document.getElementById("my_btn");
btn.onclick = function(){
setTimeout(function(){
document.getElementById("message").style.visibility = "visible";
},250);
//其他代码
}

//Yielding Processes(数组分块)
function chunk(array,process,context){
setTimeout(function(){
var item = array.shift();
process.call(context,item);

if(array.length > 0){
setTimeout(arguments.callee,100);
}
},100);
}

var data = [12,123,1234,453,436,23,23,5,4123,45,346,5634,2234,345,342];
function printValue(item){
var div = document.getElementById("my_btn");
div.innerHTML += item + "<br/>";
}
//chunk(data,printValue);

//函数节流
function throttle(method,context){
clearTimeout(method,tId);
method.tId = setTimeout(function(){
method.call(context);
},100);
}
//这段非常简单的例子有两个问题可能会造成浏览器运行缓慢。首先,要计算 offsetWidth 属性,如果该元素或者页面上其他元素有非常复杂的 CSS 样式,那么这个过程将会很复杂。其次,设置某个元素的高度需要对页面进行回流来令改动生效。如果页面有很多元素同时应用了相当数量的 CSS 的话,这又需要很多计算
window.onresize = function(){
var div = document.getElementById("my_btn");
div.style.height = div.offsetWidth + "px";
}

//用throttle()函数来解决(节省浏览器计算)
function resizeDiv(){
var div = document.getElementById("my_btn");
div.style.height = div.offsetWidth + "px";
}
window.onresize = function(){
throttle(resizeDiv);
}

//自定义事件
function EventTarget(){
this.handlers = {};
}
EventTarget.prototype = {
constructor:EventTarget,
addHandler:function(type,handler){
if(typeof this.handlers[type] == "undefined"){
this.handlers[type] = [];
}
this.handlers[type].push(handler);
},

fire:function(event){
if(!evnt.target){
event.target = this;
}
if(this.handlers[event.type] instanceof Array){
var handlers = this.handlers[event.type];
for(var i=0,len=handlers.length;i<len;i++){
handlers[i](event);
}
}
},

removeHandler:function(type,handler){
if(this.handlers[type] instanceof Array){
var handlers = this.handlers[type];
for(var i =0, len=handlers.length;i<len;i++){
if(handlers[i] === handler){
break;
}
}
handlers.splice(i,1);
}
}
};

//拖放
var DragDrop = function(){
var dragdrop = new EventTarget(),
dragging = null,
diffX = 0,
diffY = 0;

function handleEvent(event){
//获取事件和目标
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);

//确定事件类型
switch (event.type){
case "mousedown":
if(target.className.indexOf("draggable") > -1){
dragging = target;
diffX = event.clientX - target.offsetLeft;
diffY = event.clientY - target.offsetTop;
dragdrop.fire({type:"dragstart",target:dragging,x:event.clientX,y:event.clientY});
}
break;
case "mousemove":
if(dragging!==null){
//指定位置
dragging.style.left = (event.clientX - diffX) + "px";
dragging.style.top = (event.clientY - diffY) + "px";
DragDrop.fire({type:"drag",target:dragging,x:event.clientX,y:event.clientY});
}
break;
case "mouseup":
dragdrop.fire({type:"dragend",target:dragging,x:event.clientX,y:event.clientY});
dragging = null;
break;
}
};
//公共接口
dragdrop.enable = function(){
EventUtil.addHandler(document,"mousedown",handleEvent);
EventUtil.addHandler(document,"mousemove",handleEvent);
EventUtil.addHandler(document,"mouseup",handleEvent);
};

dragdrop.disable = function(){
EventUtil.addHandler(document,"mousedown",handleEvent);
EventUtil.addHandler(document,"mousemove",handleEvent);
EventUtil.addHandler(document,"mouseup",handleEvent);
};
return dragdrop;
/*return {
enable:function(){
EventUtil.addHandler(document,"mousedown",handleEvent);
EventUtil.addHandler(document,"mousemove",handleEvent);
EventUtil.addHandler(document,"mouseup",handleEvent);
},
disable:function(){
EventUtil.removeHandler(document,"mousedown",handleEvent);
EventUtil.removeHandler(document,"mousemove",handleEvent);
EventUtil.removeHandler(document,"mouseup",handleEvent);
}
}*/
}();
</script>
-->

<!-- 面向对象之离线应用与客户端存储篇 -->
<script>
//离线检测
if(navigator.onLine){
//正常工作
}else{
//执行离线状态时的任务
}
EventUtil.addHandler(window,"online",function(){
alert("Online");
});
EventUtil.addHandler(window,"Offline",function(){
alert("Offline");
});

//应用缓存
EventUtil.addHandler(applicationCache,"updateready",function(){
applicationCache.swapCache();
});

//数据存储
var CookieUtil = {
get: function (name){
var cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if (cookieStart > -1){
var cookieEnd = document.cookie.indexOf(";", cookieStart);
if (cookieEnd == -1){
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart
+ cookieName.length, cookieEnd));
}
return cookieValue;
},
set: function (name, value, expires, path, domain, secure) {
var cookieText = encodeURIComponent(name) + "=" +
encodeURIComponent(value);
if (expires instanceof Date) {
cookieText += "; expires=" + expires.toGMTString();
}
if (path) {
cookieText += "; path=" + path;
}
if (domain) {
cookieText += "; domain=" + domain;
}
if (secure) {
cookieText += "; secure";
}
document.cookie = cookieText;
},
unset: function (name, path, domain, secure){
this.set(name, "", new Date(0), path, domain, secure);
}
};

//设置cookie
CookieUtil.set("name","Nicholas");
CookieUtil.set("book",professional JavaScript);

//读取cookie的值
alert(CookieUtil.get("name"));
alert(CookieUtil.get("book"));

//删除cookie
CookieUtil.unset("name");
CookieUtil.unset("book");

//设置cookie,包括它的路径,域,失败日期
CookieUtil.set("name","Nicholas","/books/projs/","www.qq.com",new Date("January 1,2010"));

//删除刚刚设置的cookie
CookieUtil.unset("name","/books/projs/","www.qq.com");

//设置安全的cookie
CookieUtil.set("name","Nicholas",null,null,true);
</script>

<script>
/*
for(var i=0;i<3;i++){
setTimeout(function(){
alert(i); //3,3,3,这里有两个问题,一个作用域,二是执行时间顺序,因为JS是单线程,for循环执行完了,才开始执行setTimeout匿名函数
},0)
}
*/

//js实现类似于add(1)(2)(3)调用方式的方法
function add(x){
var sum = x;
var tmp = function(y){
sum = sum + y;
return tmp;
};
tmp.toString = function(){
return sum;
};
return tmp;
}
console.log(add(1)(2)(3)); //6
console.log(add(1)(2)(3)(4)); //10
</script>