HTML
<!DOCTYPE html> <html> <head> </head> <body> <div style="position: fixed;background:red;300px;height: 200px;"> <button id="my-btn">确定</button> <div id='myDiv' style="background: blue;50px;height:50px"> </div> </div> <div class="draggable" style="position: fixed;background:red;300px;height: 200px;"> <div id='status' style=" 100px;height:100px;"></div> </div> <script type="text/javascript" src="Expression.js"></script> </body> </html>
JS
//22.1 //22.1.1 安全的类型检测 var value = new Array(); var isArray = value instanceof Array; var isArray = typeof value; //比如正则表达式操作符会返回function //由于所有类型都是派生于Object 对象 function isArray(value) { return Object.prototype.toString.call(value) == '[object Array]'; } function isFunction(value) { return Object.prototype.toString.call(value) == '[object Function]'; } function isRegExp(value) { return Object.prototype.toString.call(value) == '[object RegExp]'; } // 21.1.2 作用域安全的构造函数 function Person(name, age, job) { this.name = name; this.age = age; this.job = job; } //正确构造 var person = new Person('Nicholas', 29, 'Software Engineer'); //构造一个对象 //意外的构造 person = Person('Nicholas', 29, 'Software Engineer'); //这样被当函数执行,this指向window //安全的构造对象 function Polygon(sides) { if (this instanceof Polygon) { this.sides = sides; this.getArea = function () { return 0; } } else { return new Polygon(sides); } } //窃取模式继承存在的问题 function Rectangle(width, height) { Polygon.call(this, 2); this.width = width; this.height = height; this.getArea = function () { return this.width * this.height; }; } var rect = new Rectangle(5, 10); alert(rect.sides); //undefined 因为基类 Polygon 是作用域安全的 // 当new Rectangle() 构造函数已经锁定this =Rectangle // 通过 Polygon.call(this,2);构造函数时候 this!=Polygon // 此时 Rectangle this 与 Polygon this 不同域因此不会被继承属性 //利用原型继承方式可以解决这个问题 Rectangle.prototype = new Polygon(0); //22.1.3 懒性载入函数 //假如页面js脚本会重复多次执行 //因为浏览器是在当下一旦确定就不会变 //因此这里只要第一次判断出支持的请求方式后 //就直接覆盖新的声明函数给当前函数。 //从而实现简化逻辑if语句 function CreateXMLHttpRequest() { if (typeof XMLHttpRequest != undefined) { return function () { return new XMLHttpRequest(); } } else if (typeof ActiveXObject != undefined) { return function () { return new ActiveXObject(''); } } } //22.1.4 函数绑定 var handler = { message: 'Event handled', handleClick: function (event) { alert(this.message); } }; var btn = document.getElementById('my-btn'); btn.addEventListener('click', function (event) { handler.handleClick(event); }, false); //创建一个闭包(闭包是隔断作用域) function bind(fn, context) { return function () { return fn.apply(context, arguments); } } btn.addEventListener('click', bind(handler.handleClick, handler), false); //22.1.5 函数柯里化 //柯里化通用方式 function curry(fn, context) { var args = Array.prototype.slice.call(arguments, 2); //取从数组下表2开始后的参数(外部参数) //前2参数是fn context return function () { var innerArgs = Array.prototype.slice.call(arguments); //闭包函数参数,即当前闭包函数 var finalArgs = args.concat(innerArgs); //外部函数参数和闭包函数链接起来 return fn.apply(context, finalArgs); }; } //22.2 防篡改对象 // 22.2.1 不可拓展对象 Object.preventExtensions(person); //设置该对象不可拓展 if (Object.isExtensible(person)) { } //22.2.2 密封的对象 Object.seal(person); if (Object.isSealed(person)) { } //22.2.3 冻结的对象 Object.freeze(person); //22.3.1 重复的定时器 var interval = 250; setTimeout(function () { //处理逻辑 var div = document.getElementById('myDiv'); var left = parseInt(div.style.left) + 5; div.style.left = left + "px"; if (left < 200) { setTimeout(arguments.callee, interval); } }, interval); //22.3.2 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]; function printValue(item) { var div = document.getElementById('myDiv'); div.innerHTML += item + "<br>"; } chunk(data, printValue); //22.3.3 函数节流 var processor = { timeoutId: null, //实际进行处理的方法 performProcessing: function () { //实际执行的代码 }, process: function () { clearTimeout(this.timeoutId); //清除当前定时器,执行代码逻辑后再设置定时器 var that = this; //引用this指针 this.timeoutId = setTimeout(function () { that.performProcessing(); }, 100); } }; //尝试开始执行 processor.process(); //简化模式 function throttle(method, context) { clearTimeout(method.tId); method.tId = setTimeout(function () { method.call(context); }, 100); }; //22.4 自定义事件 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 (!event.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); } } } //事件使用 function handleMessage(event) { alert('Message received' + event.message); } //创建一个新对象 var target = new EventTarget(); //添加事件处理程序 target.addHandler('message', handleMessage); //触发事件 target.fire({ type: 'message', message: 'Hello world!' }); //删除事件 target.removeHandler('message', handleMessage); //再次触发,应该没有处理程序 target.fire({ type: 'message', message: 'Hello world!' }); //22.5 拖放 // var DragDrop = function () { // var dragging = null; // var diffx = 0; // var diffY = 0; // function handleEvent(event) { // //获取事件和目标 // event = event ? event : window.event; // var target = event.target || event.srcElement; // //确定事件类型 // switch (event.type) { // case "mousedown": // if (target.className.indexOf("draggable") > -1) { // dragging = target; // diffx = event.clientX - target.offsetLeft; // diffY = event.clientY - target.offsetTop; // target.style.cursor = 'move'; // } // break; // case "mousemove": // if (dragging !== null) { // dragging.style.left = (event.clientX - diffx) + "px"; // dragging.style.top = (event.clientY - diffY) + "px"; // } // break; // case "mouseup": // dragging = null; // target.style.cursor = 'default'; // break; // } // }; // //公共接口 // return { // enable: function () { // document.addEventListener('mousedown', function (event) { // handleEvent(event); // }, false); // document.addEventListener('mousemove', function (event) { // handleEvent(event); // }, false); // document.addEventListener('mouseup', function (event) { // handleEvent(event); // }, false); // }, // disable: function () { // document.removeEventListener('mousedown', function (event) { // handleEvent(event); // }, false); // document.removeEventListener('mousemove', function (event) { // handleEvent(event); // }, false); // document.removeEventListener('mouseup', function (event) { // handleEvent(event); // }, false); // } // } // }(); //DragDrop.enable(); //添加自定义事件 var _DragDrop = function () { var dragdrop = new EventTarget(), dragging = null, diffX, diffY; function handleEvent(event) { //获取事件和目标 event = event ? event : window.event; var target = event.target || event.srcElement; //确定事件类型 switch (event.type) { case "mousedown": if (target.className.indexOf("draggable") > -1) { dragging = target; diffx = event.clientX - target.offsetLeft; diffY = event.clientY - target.offsetTop; target.style.cursor = 'move'; 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; target.style.cursor = 'default'; break; } }; //公共接口 dragdrop.enable =function(){ document.addEventListener('mousedown', function (event) { handleEvent(event); }, false); document.addEventListener('mousemove', function (event) { handleEvent(event); }, false); document.addEventListener('mouseup', function (event) { handleEvent(event); }, false); }; dragdrop.disable =function(){ document.removeEventListener('mousedown', function (event) { handleEvent(event); }, false); document.removeEventListener('mousemove', function (event) { handleEvent(event); }, false); document.removeEventListener('mouseup', function (event) { handleEvent(event); }, false); } return dragdrop; }(); //表示实例化当前对象 _DragDrop.addHandler('dragstart',function(event){ var status =document.getElementById('status'); status.innerHTML ="Started dragging"+event.target.id; }); _DragDrop.addHandler('drag',function(event){ var status =document.getElementById('status'); status.innerHTML +="<br/>Dragged "+event.target.id+"to("+event.x+","+event.y+")"; }); _DragDrop.addHandler('dragend',function(event){ var status =document.getElementById('status'); status.innerHTML +="<br/>Dropped "+event.target.id+"at"+event.x+","+event.y+")"; }); _DragDrop.enable();