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();
 
                    
                 
                
            
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号