//对非DOM元素实现自定义事件
function CusEventTarget() {
//存储事件处理程序的属性对象
this.handlers = {};
}
CusEventTarget.prototype = {
//重新将constructor指向EventTarget构造函数
constructor:CusEventTarget,
/**
* 注册给定类型时间的事件处理程序
* @param type 自定义的事件类型
* @param handler 处理该事件类型的函数
*/
addHandler:function (type, handler) {
//如果handlers属性中没有存在一个针对该事件类型的数组
//则创建一个新的。(一个事件类型可以对应多个事件处理函数,因此要用数组保存)
//然后使用push()将该处理程序添加到数组的末尾
if (typeof this.handlers[type] === "undefined") {
this.handlers[type] = [];
}
this.handlers[type].push(handler);
},
/**
* 触发事件
* @param event 一个至少包含type属性的对象
*/
fire:function (event) {
//给event对象设置一个target属性
if (!event.target) {
event.target = this;
}
//如果该事件类型的执行函数存在,
//调用各个函数,并给出event对象
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);
}
}
},
/**
* 注销事件类型的事件处理程序
* @param type 事件类型
* @param handler 执行的函数
*/
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 CusEventTarget();
//存放被拖动的元素
var dragging = null;
var diffX = 0;
var diffY = 0;
/**
* 处理拖放功能中的三个鼠标事件
* @param event
*/
function handleEvent(event) {
//获取事件和目标
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//确定事件类型
switch (event.type) {
case "mousedown":
//检查target的class是否包含"draggable”类
if (target.className.indexOf("draggable") > -1) {
event.preventDefault && event.preventDefault();
target.setCapture && target.setCapture();
//要拖动的元素
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) {
//assign location
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":
if (target.className.indexOf("draggable") > -1) {
dragdrop.fire({
type:"dragend",
target:dragging,
x:event.clientX,
y:event.clientY
});
dragging = null;
EventUtil.stopPropagation(event);
}
break;
}
}
//公公接口
dragdrop.enable = function () {
EventUtil.addHandler(document, "mousedown", handleEvent);
EventUtil.addHandler(document, "mousemove", handleEvent);
EventUtil.addHandler(document, "mouseup", handleEvent);
};
dragdrop.disable = function () {
EventUtil.removeHandler(document, "mousedown", handleEvent);
EventUtil.removeHandler(document, "mousemove", handleEvent);
EventUtil.removeHandler(document, "mouseup", handleEvent);
};
return dragdrop;
}();
DragDrop.enable();
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 + " to (" + event.x + "," + event.y + ")";
});