Rumah  >  Artikel  >  hujung hadapan web  >  拖动Html元素集合 Drag and Drop any item_javascript技巧

拖动Html元素集合 Drag and Drop any item_javascript技巧

WBOY
WBOYasal
2016-05-16 19:22:481222semak imbas

<script> <br><br>// iMouseDown represents the current mouse button state: up or down <BR>/* <BR>lMouseState represents the previous mouse button state so that we can <BR>check for button clicks and button releases: <br><br>if(iMouseDown && !lMouseState) // button just clicked! <BR>if(!iMouseDown && lMouseState) // button just released! <BR>*/ <BR>var mouseOffset = null; <BR>var iMouseDown = false; <BR>var lMouseState = false; <BR>var dragObject = null; <br><br>// Demo 0 variables <BR>var DragDrops = []; <BR>var curTarget = null; <BR>var lastTarget = null; <BR>var dragHelper = null; <BR>var tempDiv = null; <BR>var rootParent = null; <BR>var rootSibling = null; <br><br>Number.prototype.NaN0=function(){return isNaN(this)?0:this;} <br><br>function CreateDragContainer(){ <BR> /* <BR> Create a new "Container Instance" so that items from one "Set" can not <BR> be dragged into items from another "Set" <BR> */ <BR> var cDrag = DragDrops.length; <BR> DragDrops[cDrag] = []; <br><br> /* <BR> Each item passed to this function should be a "container". Store each <BR> of these items in our current container <BR> */ <BR> for(var i=0; i<arguments.length; i++){ <BR> var cObj = arguments[i]; <BR> DragDrops[cDrag].push(cObj); <BR> cObj.setAttribute('DropObj', cDrag); <br><br> /* <BR> Every top level item in these containers should be draggable. Do this <BR> by setting the DragObj attribute on each item and then later checking <BR> this attribute in the mouseMove function <BR> */ <BR> for(var j=0; j<cObj.childNodes.length; j++){ <br><br> // Firefox puts in lots of #text nodes...skip these <BR> if(cObj.childNodes[j].nodeName=='#text') continue; <br><br> cObj.childNodes[j].setAttribute('DragObj', cDrag); <BR> } <BR> } <BR>} <br><br>function mouseCoords(ev){ <BR> if(ev.pageX || ev.pageY){ <BR> return {x:ev.pageX, y:ev.pageY}; <BR> } <BR> return { <BR> x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, <BR> y:ev.clientY + document.body.scrollTop - document.body.clientTop <BR> }; <BR>} <br><br>function getMouseOffset(target, ev){ <BR> ev = ev || window.event; <br><br> var docPos = getPosition(target); <BR> var mousePos = mouseCoords(ev); <BR> return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}; <BR>} <br><br>function getPosition(e){ <BR> var left = 0; <BR> var top = 0; <BR> while (e.offsetParent){ <BR> left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0); <BR> top += e.offsetTop + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0); <BR> e = e.offsetParent; <BR> } <br><br> left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0); <BR> top += e.offsetTop + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0); <br><br> return {x:left, y:top}; <br><br>} <br><br>function mouseMove(ev){ <BR> ev = ev || window.event; <br><br> /* <BR> We are setting target to whatever item the mouse is currently on <br><br> Firefox uses event.target here, MSIE uses event.srcElement <BR> */ <BR> var target = ev.target || ev.srcElement; <BR> var mousePos = mouseCoords(ev); <br><br> // mouseOut event - fires if the item the mouse is on has changed <BR> if(lastTarget && (target!==lastTarget)){ <BR> // reset the classname for the target element <BR> var origClass = lastTarget.getAttribute('origClass'); <BR> if(origClass) lastTarget.className = origClass; <BR> } <br><br> /* <BR> dragObj is the grouping our item is in (set from the createDragContainer function). <BR> if the item is not in a grouping we ignore it since it can't be dragged with this <BR> script. <BR> */ <BR> var dragObj = target.getAttribute('DragObj'); <br><br> // if the mouse was moved over an element that is draggable <BR> if(dragObj!=null){ <br><br> // mouseOver event - Change the item's class if necessary <BR> if(target!=lastTarget){ <BR> var oClass = target.getAttribute('overClass'); <BR> if(oClass){ <BR> target.setAttribute('origClass', target.className); <BR> target.className = oClass; <BR> } <BR> } <br><br> // if the user is just starting to drag the element <BR> if(iMouseDown && !lMouseState){ <BR> // mouseDown target <BR> curTarget = target; <br><br> // Record the mouse x and y offset for the element <BR> rootParent = curTarget.parentNode; <BR> rootSibling = curTarget.nextSibling; <br><br> mouseOffset = getMouseOffset(target, ev); <br><br> // We remove anything that is in our dragHelper DIV so we can put a new item in it. <BR> for(var i=0; i<dragHelper.childNodes.length; i++) dragHelper.removeChild(dragHelper.childNodes[i]); <br><br> // Make a copy of the current item and put it in our drag helper. <BR> dragHelper.appendChild(curTarget.cloneNode(true)); <BR> dragHelper.style.display = 'block'; <br><br> // set the class on our helper DIV if necessary <BR> var dragClass = curTarget.getAttribute('dragClass'); <BR> if(dragClass){ <BR> dragHelper.firstChild.className = dragClass; <BR> } <br><br> // disable dragging from our helper DIV (it's already being dragged) <BR> dragHelper.firstChild.removeAttribute('DragObj'); <br><br> /* <BR> Record the current position of all drag/drop targets related <BR> to the element. We do this here so that we do not have to do <BR> it on the general mouse move event which fires when the mouse <BR> moves even 1 pixel. If we don't do this here the script <BR> would run much slower. <BR> */ <BR> var dragConts = DragDrops[dragObj]; <br><br> /* <BR> first record the width/height of our drag item. Then hide it since <BR> it is going to (potentially) be moved out of its parent. <BR> */ <BR> curTarget.setAttribute('startWidth', parseInt(curTarget.offsetWidth)); <BR> curTarget.setAttribute('startHeight', parseInt(curTarget.offsetHeight)); <BR> curTarget.style.display = 'none'; <br><br> // loop through each possible drop container <BR> for(var i=0; i<dragConts.length; i++){ <BR> with(dragConts[i]){ <BR> var pos = getPosition(dragConts[i]); <br><br> /* <BR> save the width, height and position of each container. <br><br> Even though we are saving the width and height of each <BR> container back to the container this is much faster because <BR> we are saving the number and do not have to run through <BR> any calculations again. Also, offsetHeight and offsetWidth <BR> are both fairly slow. You would never normally notice any <BR> performance hit from these two functions but our code is <BR> going to be running hundreds of times each second so every <BR> little bit helps! <br><br> Note that the biggest performance gain here, by far, comes <BR> from not having to run through the getPosition function <BR> hundreds of times. <BR> */ <BR> setAttribute('startWidth', parseInt(offsetWidth)); <BR> setAttribute('startHeight', parseInt(offsetHeight)); <BR> setAttribute('startLeft', pos.x); <BR> setAttribute('startTop', pos.y); <BR> } <br><br> // loop through each child element of each container <BR> for(var j=0; j<dragConts[i].childNodes.length; j++){ <BR> with(dragConts[i].childNodes[j]){ <BR> if((nodeName=='#text') || (dragConts[i].childNodes[j]==curTarget)) continue; <br><br> var pos = getPosition(dragConts[i].childNodes[j]); <br><br> // save the width, height and position of each element <BR> setAttribute('startWidth', parseInt(offsetWidth)); <BR> setAttribute('startHeight', parseInt(offsetHeight)); <BR> setAttribute('startLeft', pos.x); <BR> setAttribute('startTop', pos.y); <BR> } <BR> } <BR> } <BR> } <BR> } <br><br> // If we get in here we are dragging something <BR> if(curTarget){ <BR> // move our helper div to wherever the mouse is (adjusted by mouseOffset) <BR> dragHelper.style.top = mousePos.y - mouseOffset.y; <BR> dragHelper.style.left = mousePos.x - mouseOffset.x; <br><br> var dragConts = DragDrops[curTarget.getAttribute('DragObj')]; <BR> var activeCont = null; <br><br> var xPos = mousePos.x - mouseOffset.x + (parseInt(curTarget.getAttribute('startWidth')) /2); <BR> var yPos = mousePos.y - mouseOffset.y + (parseInt(curTarget.getAttribute('startHeight'))/2); <br><br> // check each drop container to see if our target object is "inside" the container <BR> for(var i=0; i<dragConts.length; i++){ <BR> with(dragConts[i]){ <BR> if(((getAttribute('startLeft')) < xPos) && <BR> ((getAttribute('startTop')) < yPos) && <BR> ((getAttribute('startLeft') + getAttribute('startWidth')) > xPos) && <BR> ((getAttribute('startTop') + getAttribute('startHeight')) > yPos)){ <br><br> /* <BR> our target is inside of our container so save the container into <BR> the activeCont variable and then exit the loop since we no longer <BR> need to check the rest of the containers <BR> */ <BR> activeCont = dragConts[i]; <br><br> // exit the for loop <BR> break; <BR> } <BR> } <BR> } <br><br> // Our target object is in one of our containers. Check to see where our div belongs <BR> if(activeCont){ <BR> // beforeNode will hold the first node AFTER where our div belongs <BR> var beforeNode = null; <br><br> // loop through each child node (skipping text nodes). <BR> for(var i=activeCont.childNodes.length-1; i>=0; i--){ <BR> with(activeCont.childNodes[i]){ <BR> if(nodeName=='#text') continue; <br><br> // if the current item is "After" the item being dragged <BR> if( <BR> curTarget != activeCont.childNodes[i] && <BR> ((getAttribute('startLeft') + getAttribute('startWidth')) > xPos) && <BR> ((getAttribute('startTop') + getAttribute('startHeight')) > yPos)){ <BR> beforeNode = activeCont.childNodes[i]; <BR> } <BR> } <BR> } <br><br> // the item being dragged belongs before another item <BR> if(beforeNode){ <BR> if(beforeNode!=curTarget.nextSibling){ <BR> activeCont.insertBefore(curTarget, beforeNode); <BR> } <br><br> // the item being dragged belongs at the end of the current container <BR> } else { <BR> if((curTarget.nextSibling) || (curTarget.parentNode!=activeCont)){ <BR> activeCont.appendChild(curTarget); <BR> } <BR> } <br><br> // make our drag item visible <BR> if(curTarget.style.display!=''){ <BR> curTarget.style.display = ''; <BR> } <BR> } else { <br><br> // our drag item is not in a container, so hide it. <BR> if(curTarget.style.display!='none'){ <BR> curTarget.style.display = 'none'; <BR> } <BR> } <BR> } <br><br> // track the current mouse state so we can compare against it next time <BR> lMouseState = iMouseDown; <br><br> // mouseMove target <BR> lastTarget = target; <br><br> // track the current mouse state so we can compare against it next time <BR> lMouseState = iMouseDown; <br><br> // this helps prevent items on the page from being highlighted while dragging <BR> return false; <BR>} <br><br>function mouseUp(ev){ <BR> if(curTarget){ <BR> // hide our helper object - it is no longer needed <BR> dragHelper.style.display = 'none'; <br><br> // if the drag item is invisible put it back where it was before moving it <BR> if(curTarget.style.display == 'none'){ <BR> if(rootSibling){ <BR> rootParent.insertBefore(curTarget, rootSibling); <BR> } else { <BR> rootParent.appendChild(curTarget); <BR> } <BR> } <br><br> // make sure the drag item is visible <BR> curTarget.style.display = ''; <BR> } <BR> curTarget = null; <BR> iMouseDown = false; <BR>} <br><br>function mouseDown(){ <BR> iMouseDown = true; <BR> if(lastTarget){ <BR> return false; <BR> } <BR>} <br><br>document.onmousemove = mouseMove; <BR>document.onmousedown = mouseDown; <BR>document.onmouseup = mouseUp; <br><br>window.onload = function(){ <BR> // Create our helper object that will show the item while dragging <BR> dragHelper = document.createElement('DIV'); <BR> dragHelper.style.cssText = 'position:absolute;display:none;'; <br><br> CreateDragContainer( <BR> document.getElementById('DragContainer1'), <BR> document.getElementById('DragContainer2'), <BR> document.getElementById('DragContainer3') <BR> ); <br><br> document.body.appendChild(dragHelper); <BR>} <br><br></script>




  
Item #1

  
Item #2

  
Item #3

  
Item #4



  
Item #5

  
Item #6

  
Item #7

  
Item #8



  
Item #9

  
Item #10

  
Item #11

  
Item #12

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn