javascript权威指南第22章高级技巧
HTML
<!DOCTYPE html>
<html>
<head> </head>
<body> <div style="position: fixed;background:red;width:300px;height: 200px;">
<button id="my-btn">确定</button>
<div id='myDiv' style="background: blue;width:50px;height:50px"> </div>
</div> <div class="draggable" style="position: fixed;background:red;width:300px;height: 200px;">
<div id='status' style="width: 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();
javascript权威指南第22章高级技巧的更多相关文章
- javascript权威指南第11章 DOM扩展
//javascript 权威指南 第三版 第11章 DOM扩展 //取得body元素 var body = document.querySelector("body"); //取 ...
- 【笔记】javascript权威指南-第六章-对象
对象 //本书是指:javascript权威指南 //以下内容摘记时间为:2013.7.28 对象的定义: 1.对象是一种复合值:将很多值(原始值或者对象)聚合在一起,可以通过名字访问这些值. ...
- 【笔记】javascript权威指南-第三章-类型,值和变量
javascript中的原始类型和对象类型(基本类型和引用类型) //本书是指:javascript权威指南 //以下内容摘记时间为:2013.7.27 计算机程序运行时需要对值(value ...
- javascript权威指南第16章 HTML5脚本编程
<!DOCTYPE html> <html> <head> <script type="text/javascript" src=&quo ...
- JavaScript权威指南--第3章 类型、值和变量
在编程语言中,能够表示并操作的值(value)的类型称作数据类型(type).使用变量来储存值.JavaScript中数据类型有两种:原始类型(primitive type/基本数据类型)和对象类型( ...
- JavaScript权威指南第02章 词法结构
词法结构 2.1字符集 JavaScript 是Unicode字符集编写,差点儿支持地球上全部的语言. 2.1.1区分大写和小写 javascript是区分大写和小写的语言. 2.1.2 空格.换行符 ...
- JavaScript权威指南第01章 JavaScript 概述
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/huangbin10025/article/details/27951767 JavaScript 概 ...
- JavaScript权威指南第03章 类型、值和变量(1)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/huangbin10025/article/details/27953481 类型.值和变量 数据类型 ...
- javascript权威指南第20章 JSON
//20.1 语法 //JAVASCRIPT 是对JSON数据支持的. //JSON 可以申明三种类型的值 简单值("hello world") 对象({"name&qu ...
随机推荐
- pip install 遇到的问题
执行pip命令时遇到 Fatal error in launcher: Unable to create process using '"' 电脑同时安装了python-2.7.13跟p ...
- Django框架学习易错和易忘点
一.get在几处的用法 1.获取前端数据 request.POST.get('xxx') #当存在多个值时,默认取列表最后一个元素:所以当存在多个值时,使用getlist 2.获取数据库数据 mode ...
- idea for mac 快捷键整理
⌘O 查找类文件 ⌘⌥O 前往指定的变量 / 方法 ⌘⇧O 查找所有类型文件.打开文件.打开目录,打开目录需要在输入的内容前面或后面加一个反斜杠/ ⌘⌥← / ⌘⌥→ 退回 / 前进到上一个操作的地方 ...
- VS.NET(C#)--2.8HTML服务器控件
HTML服务器控件 服务器不处理HTML控件,例如:<h1>.<a>超链接.<input>,直接送到客户端,由浏览器呈现. 把HTML控件转换成HTML服务器控件, ...
- string类型的解释与方法
基本概念 string(严格来说应该是System.String) 类型是我们日常coding中用的最多的类型之一.那什么是String呢?^ ~ ^ String是一个不可变的连续16位的Unico ...
- MVC自定定义扩展点之ActionNameSelectorAttribute+ActionFilterAttribute 在浏览器中打开pdf文档
仅仅演示 了ASP.MVC 5 下为了在在浏览器中打开pdf文档的实现方式之一,借此理解下自定义ActionNameSelectorAttribute+ActionFilterAttribute 类的 ...
- linux的scp命令可以在linux服务器之间复制文件和目录
scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...
- POJ3255(Roadblocks)--次短路径
点这里看题目 3228K 485MS G++ 2453B 根据题意和测试用例知道这是一个求次短路径的题目.次短路径,就是比最短路径长那么一丢丢的路径,而题中又是要求从一点到指定点的次短路径,果断Dij ...
- 基于socket.io客户端与服务端的相互通讯
socket.io是对websocket的封装,用于客户端与服务端的相互通讯.官网:https://socket.io/. 下面是socket.io的用法: 1.由于使用express开的本地服务,先 ...
- Java 之 Junit 单元测试
Junit 单元测试 测试分类: 1.黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2.白盒测试:需要写代码.关注程序具体的执行流程. Junit 测试:(属于白盒测试) 步骤: 1 ...