📄 htmldraganddrop.js
字号:
/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml*/dojo.provide("dojo.dnd.HtmlDragAndDrop");dojo.provide("dojo.dnd.HtmlDragSource");dojo.provide("dojo.dnd.HtmlDropTarget");dojo.provide("dojo.dnd.HtmlDragObject");dojo.require("dojo.dnd.HtmlDragManager");dojo.require("dojo.dnd.DragAndDrop");dojo.require("dojo.dom");dojo.require("dojo.style");dojo.require("dojo.html");dojo.require("dojo.html.extras");dojo.require("dojo.lang.extras");dojo.require("dojo.lfx.*");dojo.require("dojo.event");dojo.dnd.HtmlDragSource = function(node, type){ node = dojo.byId(node); this.dragObjects = []; this.constrainToContainer = false; if(node){ this.domNode = node; this.dragObject = node; // register us dojo.dnd.DragSource.call(this); // set properties that might have been clobbered by the mixin this.type = (type)||(this.domNode.nodeName.toLowerCase()); }}dojo.inherits(dojo.dnd.HtmlDragSource, dojo.dnd.DragSource);dojo.lang.extend(dojo.dnd.HtmlDragSource, { dragClass: "", // CSS classname(s) applied to node when it is being dragged onDragStart: function(){ var dragObj = new dojo.dnd.HtmlDragObject(this.dragObject, this.type); if(this.dragClass) { dragObj.dragClass = this.dragClass; } if (this.constrainToContainer) { dragObj.constrainTo(this.constrainingContainer || this.domNode.parentNode); } return dragObj; }, setDragHandle: function(node){ node = dojo.byId(node); dojo.dnd.dragManager.unregisterDragSource(this); this.domNode = node; dojo.dnd.dragManager.registerDragSource(this); }, setDragTarget: function(node){ this.dragObject = node; }, constrainTo: function(container) { this.constrainToContainer = true; if (container) { this.constrainingContainer = container; } }, /* * * see dojo.dnd.DragSource.onSelected */ onSelected: function() { for (var i=0; i<this.dragObjects.length; i++) { dojo.dnd.dragManager.selectedSources.push(new dojo.dnd.HtmlDragSource(this.dragObjects[i])); } }, /** * Register elements that should be dragged along with * the actual DragSource. * * Example usage: * var dragSource = new dojo.dnd.HtmlDragSource(...); * // add a single element * dragSource.addDragObjects(dojo.byId('id1')); * // add multiple elements to drag along * dragSource.addDragObjects(dojo.byId('id2'), dojo.byId('id3')); * * el A dom node to add to the drag list. */ addDragObjects: function(/*DOMNode*/ el) { for (var i=0; i<arguments.length; i++) { this.dragObjects.push(arguments[i]); } }});dojo.dnd.HtmlDragObject = function(node, type){ this.domNode = dojo.byId(node); this.type = type; this.constrainToContainer = false; this.dragSource = null;}dojo.inherits(dojo.dnd.HtmlDragObject, dojo.dnd.DragObject);dojo.lang.extend(dojo.dnd.HtmlDragObject, { dragClass: "", opacity: 0.5, createIframe: true, // workaround IE6 bug // if true, node will not move in X and/or Y direction disableX: false, disableY: false, createDragNode: function() { var node = this.domNode.cloneNode(true); if(this.dragClass) { dojo.html.addClass(node, this.dragClass); } if(this.opacity < 1) { dojo.style.setOpacity(node, this.opacity); } if(node.tagName.toLowerCase() == "tr"){ // dojo.debug("Dragging table row") // Create a table for the cloned row var doc = this.domNode.ownerDocument; var table = doc.createElement("table"); var tbody = doc.createElement("tbody"); tbody.appendChild(node); table.appendChild(tbody); // Set a fixed width to the cloned TDs var domTds = this.domNode.childNodes; var cloneTds = node.childNodes; for(var i = 0; i < domTds.length; i++){ if((cloneTds[i])&&(cloneTds[i].style)){ cloneTds[i].style.width = dojo.style.getContentWidth(domTds[i]) + "px"; } } node = table; } if((dojo.render.html.ie55||dojo.render.html.ie60) && this.createIframe){ with(node.style) { top="0px"; left="0px"; } var outer = document.createElement("div"); outer.appendChild(node); this.bgIframe = new dojo.html.BackgroundIframe(outer); outer.appendChild(this.bgIframe.iframe); node = outer; } node.style.zIndex = 999; return node; }, onDragStart: function(e){ dojo.html.clearSelection(); this.scrollOffset = dojo.html.getScrollOffset(); this.dragStartPosition = dojo.style.getAbsolutePosition(this.domNode, true); this.dragOffset = {y: this.dragStartPosition.y - e.pageY, x: this.dragStartPosition.x - e.pageX}; this.dragClone = this.createDragNode(); this.containingBlockPosition = this.domNode.offsetParent ? dojo.style.getAbsolutePosition(this.domNode.offsetParent) : {x:0, y:0}; if (this.constrainToContainer) { this.constraints = this.getConstraints(); } // set up for dragging with(this.dragClone.style){ position = "absolute"; top = this.dragOffset.y + e.pageY + "px"; left = this.dragOffset.x + e.pageX + "px"; } document.body.appendChild(this.dragClone); dojo.event.topic.publish('dragStart', { source: this } ); }, /** Return min/max x/y (relative to document.body) for this object) **/ getConstraints: function() { if (this.constrainingContainer.nodeName.toLowerCase() == 'body') { var width = dojo.html.getViewportWidth(); var height = dojo.html.getViewportHeight(); var x = 0; var y = 0; } else { width = dojo.style.getContentWidth(this.constrainingContainer); height = dojo.style.getContentHeight(this.constrainingContainer); x = this.containingBlockPosition.x + dojo.style.getPixelValue(this.constrainingContainer, "padding-left", true) + dojo.style.getBorderExtent(this.constrainingContainer, "left"); y = this.containingBlockPosition.y + dojo.style.getPixelValue(this.constrainingContainer, "padding-top", true) + dojo.style.getBorderExtent(this.constrainingContainer, "top"); } return { minX: x, minY: y, maxX: x + width - dojo.style.getOuterWidth(this.domNode), maxY: y + height - dojo.style.getOuterHeight(this.domNode) } }, updateDragOffset: function() { var scroll = dojo.html.getScrollOffset(); if(scroll.y != this.scrollOffset.y) { var diff = scroll.y - this.scrollOffset.y; this.dragOffset.y += diff; this.scrollOffset.y = scroll.y; } if(scroll.x != this.scrollOffset.x) { var diff = scroll.x - this.scrollOffset.x; this.dragOffset.x += diff; this.scrollOffset.x = scroll.x; } }, /** Moves the node to follow the mouse */ onDragMove: function(e){ this.updateDragOffset(); var x = this.dragOffset.x + e.pageX; var y = this.dragOffset.y + e.pageY; if (this.constrainToContainer) { if (x < this.constraints.minX) { x = this.constraints.minX; } if (y < this.constraints.minY) { y = this.constraints.minY; } if (x > this.constraints.maxX) { x = this.constraints.maxX; } if (y > this.constraints.maxY) { y = this.constraints.maxY; } } this.setAbsolutePosition(x, y); dojo.event.topic.publish('dragMove', { source: this } ); }, /** * Set the position of the drag clone. (x,y) is relative to <body>. */ setAbsolutePosition: function(x, y){ // The drag clone is attached to document.body so this is trivial if(!this.disableY) { this.dragClone.style.top = y + "px"; } if(!this.disableX) { this.dragClone.style.left = x + "px"; } }, /** * If the drag operation returned a success we reomve the clone of * ourself from the original position. If the drag operation returned * failure we slide back over to where we came from and end the operation * with a little grace. */ onDragEnd: function(e){ switch(e.dragStatus){ case "dropSuccess": dojo.dom.removeNode(this.dragClone); this.dragClone = null; break; case "dropFailure": // slide back to the start var startCoords = dojo.style.getAbsolutePosition(this.dragClone, true); // offset the end so the effect can be seen var endCoords = [this.dragStartPosition.x + 1, this.dragStartPosition.y + 1]; // animate var line = new dojo.lfx.Line(startCoords, endCoords); var anim = new dojo.lfx.Animation(500, line, dojo.lfx.easeOut); var dragObject = this; dojo.event.connect(anim, "onAnimate", function(e) { dragObject.dragClone.style.left = e[0] + "px"; dragObject.dragClone.style.top = e[1] + "px"; }); dojo.event.connect(anim, "onEnd", function (e) { // pause for a second (not literally) and disappear dojo.lang.setTimeout(function() { dojo.dom.removeNode(dragObject.dragClone); // Allow drag clone to be gc'ed dragObject.dragClone = null; }, 200); }); anim.play(); break; } // shortly the browser will fire an onClick() event, // but since this was really a drag, just squelch it dojo.event.connect(this.domNode, "onclick", this, "squelchOnClick"); dojo.event.topic.publish('dragEnd', { source: this } ); }, squelchOnClick: function(e){ // squelch this onClick() event because it's the result of a drag (it's not a real click) e.preventDefault(); // but if a real click comes along, allow it dojo.event.disconnect(this.domNode, "onclick", this, "squelchOnClick"); }, constrainTo: function(container) { this.constrainToContainer=true; if (container) { this.constrainingContainer = container; } else { this.constrainingContainer = this.domNode.parentNode; } }});dojo.dnd.HtmlDropTarget = function(node, types){ if (arguments.length == 0) { return; } this.domNode = dojo.byId(node); dojo.dnd.DropTarget.call(this); if(types && dojo.lang.isString(types)) { types = [types]; } this.acceptedTypes = types || [];}dojo.inherits(dojo.dnd.HtmlDropTarget, dojo.dnd.DropTarget);dojo.lang.extend(dojo.dnd.HtmlDropTarget, { onDragOver: function(e){ if(!this.accepts(e.dragObjects)){ return false; } // cache the positions of the child nodes this.childBoxes = []; for (var i = 0, child; i < this.domNode.childNodes.length; i++) { child = this.domNode.childNodes[i]; if (child.nodeType != dojo.dom.ELEMENT_NODE) { continue; } var pos = dojo.style.getAbsolutePosition(child, true); var height = dojo.style.getInnerHeight(child); var width = dojo.style.getInnerWidth(child); this.childBoxes.push({top: pos.y, bottom: pos.y+height, left: pos.x, right: pos.x+width, node: child}); } // TODO: use dummy node return true; }, _getNodeUnderMouse: function(e){ // find the child for (var i = 0, child; i < this.childBoxes.length; i++) { with (this.childBoxes[i]) { if (e.pageX >= left && e.pageX <= right && e.pageY >= top && e.pageY <= bottom) { return i; } } } return -1; }, createDropIndicator: function() { this.dropIndicator = document.createElement("div"); with (this.dropIndicator.style) { position = "absolute"; zIndex = 999; borderTopWidth = "1px"; borderTopColor = "black"; borderTopStyle = "solid"; width = dojo.style.getInnerWidth(this.domNode) + "px"; left = dojo.style.getAbsoluteX(this.domNode, true) + "px"; } }, onDragMove: function(e, dragObjects){ var i = this._getNodeUnderMouse(e); if(!this.dropIndicator){ this.createDropIndicator(); } if(i < 0) { if(this.childBoxes.length) { var before = (dojo.html.gravity(this.childBoxes[0].node, e) & dojo.html.gravity.NORTH); } else { var before = true; } } else { var child = this.childBoxes[i]; var before = (dojo.html.gravity(child.node, e) & dojo.html.gravity.NORTH); } this.placeIndicator(e, dragObjects, i, before); if(!dojo.html.hasParent(this.dropIndicator)) { document.body.appendChild(this.dropIndicator); } }, /** * Position the horizontal line that indicates "insert between these two items" */ placeIndicator: function(e, dragObjects, boxIndex, before) { with(this.dropIndicator.style){ if (boxIndex < 0) { if (this.childBoxes.length) { top = (before ? this.childBoxes[0].top : this.childBoxes[this.childBoxes.length - 1].bottom) + "px"; } else { top = dojo.style.getAbsoluteY(this.domNode, true) + "px"; } } else { var child = this.childBoxes[boxIndex]; top = (before ? child.top : child.bottom) + "px"; } } }, onDragOut: function(e) { if(this.dropIndicator) { dojo.dom.removeNode(this.dropIndicator); delete this.dropIndicator; } }, /** * Inserts the DragObject as a child of this node relative to the * position of the mouse. * * @return true if the DragObject was inserted, false otherwise */ onDrop: function(e){ this.onDragOut(e); var i = this._getNodeUnderMouse(e); if (i < 0) { if (this.childBoxes.length) { if (dojo.html.gravity(this.childBoxes[0].node, e) & dojo.html.gravity.NORTH) { return this.insert(e, this.childBoxes[0].node, "before"); } else { return this.insert(e, this.childBoxes[this.childBoxes.length-1].node, "after"); } } return this.insert(e, this.domNode, "append"); } var child = this.childBoxes[i]; if (dojo.html.gravity(child.node, e) & dojo.html.gravity.NORTH) { return this.insert(e, child.node, "before"); } else { return this.insert(e, child.node, "after"); } }, insert: function(e, refNode, position) { var node = e.dragObject.domNode; if(position == "before") { return dojo.html.insertBefore(node, refNode); } else if(position == "after") { return dojo.html.insertAfter(node, refNode); } else if(position == "append") { refNode.appendChild(node); return true; } return false; }});
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -