📄 dragdrop.js
字号:
* @type Object
* @private
*/
this.clickTimeout = null;
/**
* The X position of the mousedown event stored for later use when a
* drag threshold is met.
* @type int
* @private
*/
this.startX = 0;
/**
* The Y position of the mousedown event stored for later use when a
* drag threshold is met.
* @type int
* @private
*/
this.startY = 0;
/**
* Each DragDrop instance must be registered with the DragDropMgr.
* This is executed in DragDrop.init()
*
* @param {DragDrop} oDD the DragDrop object to register
* @param {String} sGroup the name of the group this element belongs to
*/
this.regDragDrop = function(oDD, sGroup) {
if (!this.initialized) { this.init(); }
if (!this.ids[sGroup]) {
this.ids[sGroup] = {};
}
this.ids[sGroup][oDD.id] = oDD;
};
/**
* Removes the supplied dd instance from the supplied group. Executed
* by DragDrop.removeFromGroup.
* @private
*/
this.removeDDFromGroup = function(oDD, sGroup) {
if (!this.ids[sGroup]) {
this.ids[sGroup] = {};
}
var obj = this.ids[sGroup];
if (obj && obj[oDD.id]) {
delete obj[oDD.id];
}
};
/**
* Unregisters a drag and drop item. This is executed in
* DragDrop.unreg, use that method instead of calling this directly.
* @private
*/
this._remove = function(oDD) {
for (var g in oDD.groups) {
if (g && this.ids[g][oDD.id]) {
delete this.ids[g][oDD.id];
}
}
delete this.handleIds[oDD.id];
};
/**
* Each DragDrop handle element must be registered. This is done
* automatically when executing DragDrop.setHandleElId()
*
* @param {String} sDDId the DragDrop id this element is a handle for
* @param {String} sHandleId the id of the element that is the drag
* handle
*/
this.regHandle = function(sDDId, sHandleId) {
if (!this.handleIds[sDDId]) {
this.handleIds[sDDId] = {};
}
this.handleIds[sDDId][sHandleId] = sHandleId;
};
/**
* Utility function to determine if a given element has been
* registered as a drag drop item.
*
* @param {String} id the element id to check
* @return {boolean} true if this element is a DragDrop item,
* false otherwise
*/
this.isDragDrop = function(id) {
return ( this.getDDById(id) ) ? true : false;
};
/**
* Returns the drag and drop instances that are in all groups the
* passed in instance belongs to.
*
* @param {DragDrop} p_oDD the obj to get related data for
* @param {boolean} bTargetsOnly if true, only return targetable objs
* @return {DragDrop[]} the related instances
*/
this.getRelated = function(p_oDD, bTargetsOnly) {
var oDDs = [];
for (var i in p_oDD.groups) {
for (j in this.ids[i]) {
var dd = this.ids[i][j];
if (! this.isTypeOfDD(dd)) {
continue;
}
if (!bTargetsOnly || dd.isTarget) {
oDDs[oDDs.length] = dd;
}
}
}
return oDDs;
};
/**
* Returns true if the specified dd target is a legal target for
* the specifice drag obj
*
* @param {DragDrop} the drag obj
* @param {DragDrop) the target
* @return {boolean} true if the target is a legal target for the
* dd obj
*/
this.isLegalTarget = function (oDD, oTargetDD) {
var targets = this.getRelated(oDD, true);
for (var i=0, len=targets.length;i<len;++i) {
if (targets[i].id == oTargetDD.id) {
return true;
}
}
return false;
};
/**
* My goal is to be able to transparently determine if an object is
* typeof DragDrop, and the exact subclass of DragDrop. typeof
* returns "object", oDD.constructor.toString() always returns
* "DragDrop" and not the name of the subclass. So for now it just
* evaluates a well-known variable in DragDrop.
*
* @param {Object} the object to evaluate
* @return {boolean} true if typeof oDD = DragDrop
*/
this.isTypeOfDD = function (oDD) {
return (oDD && oDD.__ygDragDrop);
};
/**
* Utility function to determine if a given element has been
* registered as a drag drop handle for the given Drag Drop object.
*
* @param {String} id the element id to check
* @return {boolean} true if this element is a DragDrop handle, false
* otherwise
*/
this.isHandle = function(sDDId, sHandleId) {
return ( this.handleIds[sDDId] &&
this.handleIds[sDDId][sHandleId] );
};
/**
* Returns the DragDrop instance for a given id
*
* @param {String} id the id of the DragDrop object
* @return {DragDrop} the drag drop object, null if it is not found
*/
this.getDDById = function(id) {
for (var i in this.ids) {
if (this.ids[i][id]) {
return this.ids[i][id];
}
}
return null;
};
/**
* Fired after a registered DragDrop object gets the mousedown event.
* Sets up the events required to track the object being dragged
*
* @param {Event} e the event
* @param oDD the DragDrop object being dragged
* @private
*/
this.handleMouseDown = function(e, oDD) {
this.currentTarget = YAHOO.util.Event.getTarget(e);
this.dragCurrent = oDD;
var el = oDD.getEl();
// track start position
this.startX = YAHOO.util.Event.getPageX(e);
this.startY = YAHOO.util.Event.getPageY(e);
this.deltaX = this.startX - el.offsetLeft;
this.deltaY = this.startY - el.offsetTop;
this.dragThreshMet = false;
this.clickTimeout = setTimeout(
function() {
var DDM = YAHOO.util.DDM;
DDM.startDrag(DDM.startX, DDM.startY);
},
this.clickTimeThresh );
};
/**
* Fired when either the drag pixel threshol or the mousedown hold
* time threshold has been met.
*
* @param x {int} the X position of the original mousedown
* @param y {int} the Y position of the original mousedown
*/
this.startDrag = function(x, y) {
clearTimeout(this.clickTimeout);
if (this.dragCurrent) {
this.dragCurrent.b4StartDrag(x, y);
this.dragCurrent.startDrag(x, y);
}
this.dragThreshMet = true;
};
/**
* Internal function to handle the mouseup event. Will be invoked
* from the context of the document.
*
* @param {Event} e the event
* @private
*/
this.handleMouseUp = function(e) {
if (! this.dragCurrent) {
return;
}
clearTimeout(this.clickTimeout);
if (this.dragThreshMet) {
this.fireEvents(e, true);
} else {
}
this.stopDrag(e);
this.stopEvent(e);
};
/**
* Utility to stop event propagation and event default, if these
* features are turned on.
*
* @param {Event} e the event as returned by this.getEvent()
*/
this.stopEvent = function(e) {
if (this.stopPropagation) {
YAHOO.util.Event.stopPropagation(e);
}
if (this.preventDefault) {
YAHOO.util.Event.preventDefault(e);
}
};
/**
* Internal function to clean up event handlers after the drag
* operation is complete
*
* @param {Event} e the event
* @private
*/
this.stopDrag = function(e) {
// Fire the drag end event for the item that was dragged
if (this.dragCurrent) {
if (this.dragThreshMet) {
this.dragCurrent.b4EndDrag(e);
this.dragCurrent.endDrag(e);
}
this.dragCurrent.onMouseUp(e);
}
this.dragCurrent = null;
this.dragOvers = {};
};
/**
* Internal function to handle the mousemove event. Will be invoked
* from the context of the html element.
*
* @TODO figure out what we can do about mouse events lost when the
* user drags objects beyond the window boundary. Currently we can
* detect this in internet explorer by verifying that the mouse is
* down during the mousemove event. Firefox doesn't give us the
* button state on the mousemove event.
*
* @param {Event} e the event
* @private
*/
this.handleMouseMove = function(e) {
if (! this.dragCurrent) {
return true;
}
// var button = e.which || e.button;
// check for IE mouseup outside of page boundary
if (YAHOO.util.Event.isIE && !e.button) {
this.stopEvent(e);
return this.handleMouseUp(e);
}
if (!this.dragThreshMet) {
var diffX = Math.abs(this.startX - YAHOO.util.Event.getPageX(e));
var diffY = Math.abs(this.startY - YAHOO.util.Event.getPageY(e));
if (diffX > this.clickPixelThresh ||
diffY > this.clickPixelThresh) {
this.startDrag(this.startX, this.startY);
}
}
if (this.dragThreshMet) {
this.dragCurrent.b4Drag(e);
this.dragCurrent.onDrag(e);
this.fireEvents(e, false);
}
this.stopEvent(e);
return true;
};
/**
* Iterates over all of the DragDrop elements to find ones we are
* hovering over or dropping on
*
* @param {Event} e the event
* @param {boolean} isDrop is this a drop op or a mouseover op?
* @private
*/
this.fireEvents = function(e, isDrop) {
var dc = this.dragCurrent;
// If the user did the mouse up outside of the window, we could
// get here even though we have ended the drag.
if (!dc || dc.isLocked()) {
return;
}
var x = YAHOO.util.Event.getPageX(e);
var y = YAHOO.util.Event.getPageY(e);
var pt = new YAHOO.util.Point(x,y);
// cache the previous dragOver array
var oldOvers = [];
var outEvts = [];
var overEvts = [];
var dropEvts = [];
var enterEvts = [];
// Check to see if the object(s) we were hovering over is no longer
// being hovered over so we can fire the onDragOut event
for (var i in this.dragOvers) {
var ddo = this.dragOvers[i];
if (! this.isTypeOfDD(ddo)) {
continue;
}
if (! this.isOverTarget(pt, ddo, this.mode)) {
outEvts.push( ddo );
}
oldOvers[i] = true;
delete this.dragOvers[i];
}
for (var sGroup in dc.groups) {
if ("string" != typeof sGroup) {
continue;
}
for (i in this.ids[sGroup]) {
var oDD = this.ids[sGroup][i];
if (! this.isTypeOfDD(oDD)) {
continue;
}
if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {
if (this.isOverTarget(pt, oDD, this.mode)) {
// look for drop interactions
if (isDrop) {
dropEvts.push( oDD );
// look for drag enter and drag over interactions
} else {
// initial drag over: dragEnter fires
if (!oldOvers[oDD.id]) {
enterEvts.push( oDD );
// subsequent drag overs: dragOver fires
} else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -