How to Drag and Drop in JavaScript

 

/ iMouseDown represents the current mouse button state: up or down
/*
lMouseState represents the previous mouse button state so that we can
check for button clicks and button releases:
if(iMouseDown && !lMouseState) // button just clicked!
if(!iMouseDown && lMouseState) // button just released!
*/
var mouseOffset = null;
var iMouseDown  = false;
var lMouseState = false;
var dragObject  = null;
// Demo 0 variables
var DragDrops   = [];
var curTarget   = null;
var lastTarget  = null;
var dragHelper  = null;
var tempDiv     = null;
var rootParent  = null;
var rootSibling = null;
Number.prototype.NaN0=function(){return isNaN(this)?0:this;}
function CreateDragContainer(){
	/*
	Create a new "Container Instance" so that items from one "Set" can not
	be dragged into items from another "Set"
	*/
	var cDrag        = DragDrops.length;
	DragDrops[cDrag] = [];
	/*
	Each item passed to this function should be a "container".  Store each
	of these items in our current container
	*/
	for(var i=0; i<arguments.length; i++){
		var cObj = arguments[i];
		DragDrops[cDrag].push(cObj);
		cObj.setAttribute('DropObj', cDrag);
		/*
		Every top level item in these containers should be draggable.  Do this
		by setting the DragObj attribute on each item and then later checking
		this attribute in the mouseMove function
		*/
		for(var j=0; j<cObj.childNodes.length; j++){
			// Firefox puts in lots of #text nodes...skip these
			if(cObj.childNodes[j].nodeName=='#text') continue;
			cObj.childNodes[j].setAttribute('DragObj', cDrag);
		}
	}
}
function mouseMove(ev){
	ev         = ev || window.event;
	/*
	We are setting target to whatever item the mouse is currently on
	Firefox uses event.target here, MSIE uses event.srcElement
	*/
	var target   = ev.target || ev.srcElement;
	var mousePos = mouseCoords(ev);
	// mouseOut event - fires if the item the mouse is on has changed
	if(lastTarget && (target!==lastTarget)){
		// reset the classname for the target element
		var origClass = lastTarget.getAttribute('origClass');
		if(origClass) lastTarget.className = origClass;
	}
	/*
	dragObj is the grouping our item is in (set from the createDragContainer function).
	if the item is not in a grouping we ignore it since it can't be dragged with this
	script.
	*/
	var dragObj = target.getAttribute('DragObj');
	 // if the mouse was moved over an element that is draggable
	if(dragObj!=null){
		// mouseOver event - Change the item's class if necessary
		if(target!=lastTarget){
			var oClass = target.getAttribute('overClass');
			if(oClass){
				target.setAttribute('origClass', target.className);
				target.className = oClass;
			}
		}
		// if the user is just starting to drag the element
		if(iMouseDown && !lMouseState){
			// mouseDown target
			curTarget     = target;
			// Record the mouse x and y offset for the element
			rootParent    = curTarget.parentNode;
			rootSibling   = curTarget.nextSibling;
			mouseOffset   = getMouseOffset(target, ev);
			// We remove anything that is in our dragHelper DIV so we can put a new item in it.
			for(var i=0; i<dragHelper.childNodes.length; i++) dragHelper.removeChild(dragHelper.childNodes[i]);
			// Make a copy of the current item and put it in our drag helper.
			dragHelper.appendChild(curTarget.cloneNode(true));
			dragHelper.style.display = 'block';
			// set the class on our helper DIV if necessary
			var dragClass = curTarget.getAttribute('dragClass');
			if(dragClass){
				dragHelper.firstChild.className = dragClass;
			}
			// disable dragging from our helper DIV (it's already being dragged)
			dragHelper.firstChild.removeAttribute('DragObj');
			/*
			Record the current position of all drag/drop targets related
			to the element.  We do this here so that we do not have to do
			it on the general mouse move event which fires when the mouse
			moves even 1 pixel.  If we don't do this here the script
			would run much slower.
			*/
			var dragConts = DragDrops[dragObj];
			/*
			first record the width/height of our drag item.  Then hide it since
			it is going to (potentially) be moved out of its parent.
			*/
			curTarget.setAttribute('startWidth',  parseInt(curTarget.offsetWidth));
			curTarget.setAttribute('startHeight', parseInt(curTarget.offsetHeight));
			curTarget.style.display  = 'none';
			// loop through each possible drop container
			for(var i=0; i<dragConts.length; i++){
				with(dragConts[i]){
					var pos = getPosition(dragConts[i]);
					/*
					save the width, height and position of each container.
					Even though we are saving the width and height of each
					container back to the container this is much faster because
					we are saving the number and do not have to run through
					any calculations again.  Also, offsetHeight and offsetWidth
					are both fairly slow.  You would never normally notice any
					performance hit from these two functions but our code is
					going to be running hundreds of times each second so every
					little bit helps!
					Note that the biggest performance gain here, by far, comes
					from not having to run through the getPosition function
					hundreds of times.
					*/
					setAttribute('startWidth',  parseInt(offsetWidth));
					setAttribute('startHeight', parseInt(offsetHeight));
					setAttribute('startLeft',   pos.x);
					setAttribute('startTop',    pos.y);
				}
				// loop through each child element of each container
				for(var j=0; j<dragConts[i].childNodes.length; j++){
					with(dragConts[i].childNodes[j]){
						if((nodeName=='#text') || (dragConts[i].childNodes[j]==curTarget)) continue;
						var pos = getPosition(dragConts[i].childNodes[j]);
						// save the width, height and position of each element
						setAttribute('startWidth',  parseInt(offsetWidth));
						setAttribute('startHeight', parseInt(offsetHeight));
						setAttribute('startLeft',   pos.x);
						setAttribute('startTop',    pos.y);
					}
				}
			}
		}
	}
	// If we get in here we are dragging something
	if(curTarget){
		// move our helper div to wherever the mouse is (adjusted by mouseOffset)
		dragHelper.style.top  = mousePos.y - mouseOffset.y;
		dragHelper.style.left = mousePos.x - mouseOffset.x;
		var dragConts  = DragDrops[curTarget.getAttribute('DragObj')];
		var activeCont = null;
		var xPos = mousePos.x - mouseOffset.x + (parseInt(curTarget.getAttribute('startWidth')) /2);
		var yPos = mousePos.y - mouseOffset.y + (parseInt(curTarget.getAttribute('startHeight'))/2);
		// check each drop container to see if our target object is "inside" the container
		for(var i=0; i<dragConts.length; i++){
			with(dragConts[i]){
				if(((getAttribute('startLeft'))                               < xPos) &&
					((getAttribute('startTop'))                                < yPos) &&
					((getAttribute('startLeft') + getAttribute('startWidth'))  > xPos) &&
					((getAttribute('startTop')  + getAttribute('startHeight')) > yPos)){
						/*
						our target is inside of our container so save the container into
						the activeCont variable and then exit the loop since we no longer
						need to check the rest of the containers
						*/
						activeCont = dragConts[i];
						// exit the for loop
						break;
				}
			}
		}
		// Our target object is in one of our containers.  Check to see where our div belongs
		if(activeCont){
			// beforeNode will hold the first node AFTER where our div belongs
			var beforeNode = null;
			// loop through each child node (skipping text nodes).
			for(var i=activeCont.childNodes.length-1; i>=0; i--){
				with(activeCont.childNodes[i]){
					if(nodeName=='#text') continue;
					// if the current item is "After" the item being dragged
					if(
						curTarget != activeCont.childNodes[i]                              &&
						((getAttribute('startLeft') + getAttribute('startWidth'))  > xPos) &&
						((getAttribute('startTop')  + getAttribute('startHeight')) > yPos)){
							beforeNode = activeCont.childNodes[i];
					}
				}
			}
			// the item being dragged belongs before another item
			if(beforeNode){
				if(beforeNode!=curTarget.nextSibling){
					activeCont.insertBefore(curTarget, beforeNode);
				}
			// the item being dragged belongs at the end of the current container
			} else {
				if((curTarget.nextSibling) || (curTarget.parentNode!=activeCont)){
					activeCont.appendChild(curTarget);
				}
			}
			// make our drag item visible
			if(curTarget.style.display!=''){
				curTarget.style.display  = '';
			}
		} else {
			// our drag item is not in a container, so hide it.
			if(curTarget.style.display!='none'){
				curTarget.style.display  = 'none';
			}
		}
	}
	// track the current mouse state so we can compare against it next time
	lMouseState = iMouseDown;
	// mouseMove target
	lastTarget  = target;
	// track the current mouse state so we can compare against it next time
	lMouseState = iMouseDown;
	// this helps prevent items on the page from being highlighted while dragging
	return false;
}
function mouseUp(ev){
	if(curTarget){
		// hide our helper object - it is no longer needed
		dragHelper.style.display = 'none';
		// if the drag item is invisible put it back where it was before moving it
		if(curTarget.style.display == 'none'){
			if(rootSibling){
				rootParent.insertBefore(curTarget, rootSibling);
			} else {
				rootParent.appendChild(curTarget);
			}
		}
		// make sure the drag item is visible
		curTarget.style.display = '';
	}
	curTarget  = null;
	iMouseDown = false;
}
function mouseDown(){
	iMouseDown = true;
	if(lastTarget){
		return false;
	}
}
document.onmousemove = mouseMove;
document.onmousedown = mouseDown;
document.onmouseup   = mouseUp;
window.onload = function(){
	// Create our helper object that will show the item while dragging
	dragHelper = document.createElement('DIV');
	dragHelper.style.cssText = 'position:absolute;display:none;';
	CreateDragContainer(
		document.getElementById('DragContainer1'),
		document.getElementById('DragContainer2'),
		document.getElementById('DragContainer3')
	);
	document.body.appendChild(dragHelper);
}
<!--the mouse over and dragging class are defined on each item-->
<div class="DragContainer" id="DragContainer1">
	<div class="DragBox" id="Item1"  overClass="OverDragBox" dragClass="DragDragBox">Item #1</div>
	<div class="DragBox" id="Item2"  overClass="OverDragBox" dragClass="DragDragBox">Item #2</div>
	<div class="DragBox" id="Item3"  overClass="OverDragBox" dragClass="DragDragBox">Item #3</div>
	<div class="DragBox" id="Item4"  overClass="OverDragBox" dragClass="DragDragBox">Item #4</div>
</div>
<div class="DragContainer" id="DragContainer2">
	<div class="DragBox" id="Item5"  overClass="OverDragBox" dragClass="DragDragBox">Item #5</div>
	<div class="DragBox" id="Item6"  overClass="OverDragBox" dragClass="DragDragBox">Item #6</div>
	<div class="DragBox" id="Item7"  overClass="OverDragBox" dragClass="DragDragBox">Item #7</div>
	<div class="DragBox" id="Item8"  overClass="OverDragBox" dragClass="DragDragBox">Item #8</div>
</div>
<div class="DragContainer" id="DragContainer3">
	<div class="DragBox" id="Item9"  overClass="OverDragBox" dragClass="DragDragBox">Item #9</div>
	<div class="DragBox" id="Item10" overClass="OverDragBox" dragClass="DragDragBox">Item #10</div>
	<div class="DragBox" id="Item11" overClass="OverDragBox" dragClass="DragDragBox">Item #11</div>
	<div class="DragBox" id="Item12" overClass="OverDragBox" dragClass="DragDragBox">Item #12</div>
</div>
 
Qt Quick enables you to build UIs around the behavior of components and how they connect with one another. You create components using Qt Quick and QML types that are available in the Design mode. You can specify values for the properties of a component to change its appearance and behavior. All QML types have a set of predefined properties, some of which control things that are visible to users, while others are used behind the scene. While it is useful to learn the basics of Qt Quick, you can also rely on Qt Design Studio to write the code for you when you drag-and-drop the ready-made components to the working area and change them to your liking by modifying their properties in the Design mode. You can always check up details in the extensive Qt Quick documentation by pressing F1. Creating Qt Quick Projects You can use wizards to create Qt Quick projects. Editing QML Files in Design Mode You can use the Form Editor or the Text Editor in the Design mode to develop Qt Quick applications. Creating Components In addition to your imported artwork, you can use the Design mode to customize ready-made components or design any custom form and shape directly as QML types. You can import visual assets in various formats, such as PNG, JPG, and SVG for use in the components. Managing Item Hierarchy You can manage the items in the current QML file and their relationships in the Navigator. Specifying Item Properties You can specify values for the properties of a component to change its appearance and behavior. All QML types have a set of predefined properties. Some properties, such as position, size, and visibility, are common to all QML types, whereas others are specific to the QML type. You can specify properties for your components in the Properties pane. Creating Animations You can use a timeline and keyframe based editor in the Timeline view to animate the properties of UI components. Animating properties enables their values to move through intermediate values at specified keyframes instead of immediately changing to the target value. Adding Connections You can create connections between the UI components and the application to enable them to communicate with each other. For example, how does the appearance of a button change on a mouse click and which action does the application need to perform in response to it. You can also create connections between UI components by binding their properties together. This way, when the value of a property changes in a parent component, it can be automatically changed in all the child components, for example. Adding States Qt Quick allows you to declare various UI states that describe how component properties change from a base state. Therefore, states can be a useful way of organizing your UI logic. You can associate transitions with items to define how their properties will animate when they change due to a state change. Related Topics Editing PathView Properties You can use a graphical spline editor to specify PathView paths. A path view lays out data provided by data models on a Path. Browsing ISO 7000 Icons You can add ISO 7000 icons from a library delivered with Qt Creator to UIs and change their color. Qt Quick UI Forms Some of the wizards create Qt Quick projects that contain UI forms (.ui.qml files). The forms use a purely declarative subset of the QML language and you can edit them in the Design mode. Using QML Modules with Plugins QML modules may use plugins to expose components defined in C++ to QML applications. Qt Creator cannot load the plugins to determine the details of the contained components, and therefore, the modules must provide extra type information for code completion and the semantic checks to work correctly. Converting UI Projects to Applications Qt Quick UI projects (.qmlproject) are useful for creating user interfaces. To use them for application development, you have to convert them to Qt Quick Application projects that contain .pro, .cpp, and .qrc files. Designing User Interfaces ◦ Creating Qt Quick Projects
09-11
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值