一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

怎么用javascript進(jìn)行拖拽

 小嘯笑 2007-09-30

 

Javascript的特點(diǎn)是dom的處理與網(wǎng)頁(yè)效果,大多數(shù)情況我們只用到了這個(gè)語(yǔ)言的最簡(jiǎn)單的功能,比如制作圖片輪播/網(wǎng)頁(yè)的tab等等,這篇文章將向你展示如何在自己的網(wǎng)頁(yè)上制作拖拽.

有很多理由讓你的網(wǎng)站加入拖拽功能,最簡(jiǎn)單的一個(gè)是數(shù)據(jù)重組.例如:你有一個(gè)序列的內(nèi)容讓用戶排序,用戶需要給每個(gè)條目進(jìn)行輸入或者用select選擇,替代前面這個(gè)方法的就是拖拽.或許你的網(wǎng)站也需要一個(gè)用戶可以拖動(dòng)的導(dǎo)航窗口!那么這些效果都是很簡(jiǎn)單:因?yàn)槟憧梢院苋菀椎膶?shí)現(xiàn)!

網(wǎng)頁(yè)上實(shí)現(xiàn)拖拽其實(shí)也不是很復(fù)雜.第一你需要知道鼠標(biāo)坐標(biāo),第二你需要知道用戶鼠標(biāo)點(diǎn)擊一個(gè)網(wǎng)頁(yè)元素并實(shí)現(xiàn)拖拽,最后我們要實(shí)現(xiàn)移動(dòng)這個(gè)元素.

樣例- 拖拽頁(yè)面元素
Item #1
Item #2
Item #3
Item #4
Item #5
Item #6
Item #7
Item #8
Item #9
Item #10
Item #11
Item #12

獲取鼠標(biāo)移動(dòng)信息

第一我們需要獲取鼠標(biāo)的坐標(biāo).我們加一個(gè)用戶函數(shù)到document.onmousemove就可以了:

document.onmousemove = mouseMove;
function mouseMove(ev){
ev           = ev || window.event;
var mousePos = mouseCoords(ev);
}
function mouseCoords(ev){
if(ev.pageX || ev.pageY){
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop  - document.body.clientTop
};
}
Demo - Move your mouseMouse X Position:   Mouse Y Position:

實(shí)現(xiàn)上面的獨(dú)立腳本,選取存下來(lái)
<script>
function mouseMove(ev){
ev           = ev || window.event;
var mousePos = mouseCoords(ev);
document.getElementById(‘xxx‘).value = mousePos.x;
document.getElementById(‘yyy‘).value = mousePos.y;
}
function mouseCoords(ev){
if(ev.pageX || ev.pageY){
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop  - document.body.clientTop
};
}
document.onmousemove = mouseMove;
</script>
<input id=xxx type=text>
<br>
<input id=yyy type=text>


你首先要聲明一個(gè)evnet對(duì)象.不論何時(shí)你移動(dòng)鼠標(biāo)/點(diǎn)擊/按鍵等等,會(huì)對(duì)應(yīng)一個(gè)event的事件.在Internet Explorer里event是全局變量,會(huì)被存儲(chǔ)在window.event里. 在firefox中,或者其他瀏覽器,event事件會(huì)被相應(yīng)的自定義函數(shù)獲取.當(dāng)我們將mouseMove函數(shù)賦值于document.onmousemove,mouseMove會(huì)獲取鼠標(biāo)移動(dòng)事件.

(ev = ev || window.event) 這樣讓ev在所有瀏覽器下獲取了event事件,在Firefox下"||window.event"將不起作用,因?yàn)閑v已經(jīng)有了賦值.在MSIE下ev是空的,所以ev將設(shè)置為window.event.

因?yàn)槲覀冊(cè)谶@篇文章中需要多次獲取鼠標(biāo)坐標(biāo),所以我們?cè)O(shè)計(jì)了mouseCoords這個(gè)函數(shù),它只包含了一個(gè)參數(shù),就是the event.

我們需要運(yùn)行在MSIE與Firefox為首的其他瀏覽器下.Firefox以event.pageX和event.pageY來(lái)代表鼠標(biāo)相應(yīng)于文檔左上角的位置.如果你有一個(gè)500*500的窗口,而且你的鼠標(biāo)在正中間,那么paegX和pageY將是250,當(dāng)你將頁(yè)面往下滾動(dòng)500px,那么pageY將是750.此時(shí)pageX不變,還是250.

MSIE和這個(gè)相反,MSIE將event.clientX與event.clientY來(lái)代表鼠標(biāo)與ie窗口的位置,并不是文檔.當(dāng)我們有一個(gè)500*500的窗口,鼠標(biāo)在正中間,那么clientX與clientY也是250,如果你垂直滾動(dòng)窗口到任何位置,clientY仍然是250,因?yàn)橄鄬?duì)ie窗口并沒(méi)有變化.想得到正確的結(jié)果,我們必須加入scrollLeft與scrollTop這兩個(gè)相對(duì)于文檔鼠標(biāo)位置的屬性.最后,由于MSIE并沒(méi)有0,0的文檔起始位置,因?yàn)橥ǔ?huì)設(shè)置2px的邊框在周?chē)?,邊框的寬度包含在document.body.clientLeft與clientTop這兩個(gè)屬性中,我們?cè)偌尤脒@些到鼠標(biāo)的位置中.

很幸運(yùn),這樣mouseCoords函數(shù)就完成了,我們不再為坐標(biāo)的事操心了.

捕捉鼠標(biāo)點(diǎn)擊

下次我們將知道鼠標(biāo)何時(shí)點(diǎn)擊與何時(shí)放開(kāi).如果我們跳過(guò)這一步,我們?cè)谧鐾献r(shí)將永遠(yuǎn)不知道鼠標(biāo)移動(dòng)上面時(shí)的動(dòng)作,這將是惱人的與違反直覺(jué)的.

這里有兩個(gè)函數(shù)幫助我們:onmousedown與onmouseup.我們預(yù)先設(shè)置函數(shù)來(lái)接收document.onmousemove,這樣看起來(lái)很象我們會(huì)獲取document.onmousedown與document.onmouseup.但是當(dāng)我們獲取document.onmousedown時(shí),我們同時(shí)獲取了任何對(duì)象的點(diǎn)擊屬性如:text,images,tables等等.我們只想獲取那些需要拖拽的屬性,所以我們?cè)O(shè)置函數(shù)來(lái)獲取我們需要移動(dòng)的對(duì)象.

Demo - Click any image


You clicked on:
實(shí)現(xiàn)上面的獨(dú)立腳本,選取存下來(lái),就可以看到效果!
<script>
function mouseDown(ev){
ev         = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.onmousedown || target.getAttribute(‘DragObj‘)){
return false;
}
}
function makeClickable(item){
if(!item) return;
item.onmousedown = function(ev){
document.getElementById(‘ClickImage‘).value = this.name;
}
}
document.onmousedown = mouseDown;
window.onload = function(){
makeClickable(document.getElementById(‘ClickImage1‘));
makeClickable(document.getElementById(‘ClickImage2‘));
makeClickable(document.getElementById(‘ClickImage3‘));
makeClickable(document.getElementById(‘ClickImage4‘));
}</script>
<FIELDSET id=Demo3>
<h3>
Demo - Click any image
</h3>
<IMG id=ClickImage1
src="images/drag_drop_spade.gif"
name=Spade><IMG id=ClickImage2
src="images/drag_drop_heart.gif"
name=Heart><IMG id=ClickImage3
src="images/drag_drop_diamond.gif"
name=Diamond><IMG id=ClickImage4
src="images/drag_drop_club.gif"
name=Club>
<BR>You clicked on: <INPUT id=ClickImage type="text"> </FIELDSET>

移動(dòng)一個(gè)元素

我們知道了怎么捕捉鼠標(biāo)移動(dòng)與點(diǎn)擊.剩下的就是移動(dòng)元素了.首先,要確定一個(gè)明確的頁(yè)面位置,css樣式表要用‘a(chǎn)bsolute‘.設(shè)置元素絕對(duì)位置意味著我們可以用樣式表的.top和.left來(lái)定位,可以用相對(duì)位置來(lái)定位了.我們將鼠標(biāo)的移動(dòng)全部相對(duì)頁(yè)面top-left,基于這點(diǎn),我們可以進(jìn)行下一步了.

當(dāng)我們定義item.style.position=‘a(chǎn)bsolute‘,所有的操作都是改變left坐標(biāo)與top坐標(biāo),然后它移動(dòng)了.

document.onmousemove = mouseMove;
document.onmouseup   = mouseUp;
var dragObject  = null;
var mouseOffset = null;
function getMouseOffset(target, ev){
ev = ev || window.event;
var docPos    = getPosition(target);
var mousePos  = mouseCoords(ev);
return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}
function getPosition(e){
var left = 0;
var top  = 0;
while (e.offsetParent){
left += e.offsetLeft;
top  += e.offsetTop;
e     = e.offsetParent;
}
left += e.offsetLeft;
top  += e.offsetTop;
return {x:left, y:top};
}
function mouseMove(ev){
ev           = ev || window.event;
var mousePos = mouseCoords(ev);
if(dragObject){
dragObject.style.position = ‘a(chǎn)bsolute‘;
dragObject.style.top      = mousePos.y - mouseOffset.y;
dragObject.style.left     = mousePos.x - mouseOffset.x;
return false;
}
}
function mouseUp(){
dragObject = null;
}
function makeDraggable(item){
if(!item) return;
item.onmousedown = function(ev){
dragObject  = this;
mouseOffset = getMouseOffset(this, ev);
return false;
}
}

Demo - Drag any of the images

實(shí)現(xiàn)上面效果的代碼
<script>
var iMouseDown  = false;
var dragObject  = null;
var curTarget   = null;
function makeDraggable(item){
if(!item) return;
item.onmousedown = function(ev){
dragObject  = this;
mouseOffset = getMouseOffset(this, ev);
return false;
}
}
function getMouseOffset(target, ev){
ev = ev || window.event;
var docPos    = getPosition(target);
var mousePos  = mouseCoords(ev);
return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}
function getPosition(e){
var left = 0;
var top  = 0;
while (e.offsetParent){
left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
e     = e.offsetParent;
}
left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
return {x:left, y:top};
}
function mouseCoords(ev){
if(ev.pageX || ev.pageY){
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop  - document.body.clientTop
};
}
function mouseDown(ev){
ev         = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.onmousedown || target.getAttribute(‘DragObj‘)){
return false;
}
}
function mouseUp(ev){
dragObject = null;
iMouseDown = false;
}
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);
if(dragObject){
dragObject.style.position = ‘a(chǎn)bsolute‘;
dragObject.style.top      = mousePos.y - mouseOffset.y;
dragObject.style.left     = mousePos.x - mouseOffset.x;
}
// track the current mouse state so we can compare against it next time
lMouseState = iMouseDown;
// this prevents items on the page from being highlighted while dragging
if(curTarget || dragObject) return false;
}
document.onmousemove = mouseMove;
document.onmousedown = mouseDown;
document.onmouseup   = mouseUp;
window.onload = function() {
makeDraggable(document.getElementById(‘DragImage5‘));
makeDraggable(document.getElementById(‘DragImage6‘));
makeDraggable(document.getElementById(‘DragImage7‘));
makeDraggable(document.getElementById(‘DragImage8‘));
}
</script>
<FIELDSET id=Demo5 style="HEIGHT: 70px"><h3>Demo - Drag any of the
images</h3><IMG id=DragImage5
src="images/drag_drop_spade.gif"><IMG
id=DragImage6
src="images/drag_drop_heart.gif"><IMG
id=DragImage7
src="images/drag_drop_diamond.gif"><IMG
id=DragImage8
src="images/drag_drop_club.gif"> </FIELDSET>

你會(huì)注意到這個(gè)代碼幾乎是前面的全集,將前面的合在一起就實(shí)現(xiàn)了拖拽效果了.

當(dāng)我們點(diǎn)擊一個(gè)item時(shí),我們就獲取了很多變量,如鼠標(biāo)位置,鼠標(biāo)位置自然就包含了那個(gè)item的坐標(biāo)信息了.如果我們點(diǎn)擊了一個(gè)20*20px圖像的正中間,那么鼠標(biāo)的相對(duì)坐標(biāo)為{x:10,y:10}.當(dāng)我們點(diǎn)擊這個(gè)圖像的左上角那么鼠標(biāo)的相對(duì)坐標(biāo)為{x:0,y:0}.當(dāng)我們點(diǎn)擊時(shí),我們用這個(gè)方法取得一些鼠標(biāo)與圖片校對(duì)的信息.如果我們不能加載頁(yè)面item,那么信息將是document信息,會(huì)忽略了點(diǎn)擊的item信息.

mouseOffset函數(shù)使用了另一個(gè)函數(shù)getPosition.getPosition的作用是返回item相對(duì)頁(yè)面左上角的坐標(biāo),如果我們嘗試獲取item.offsetLeft或者item.style.left,那么我們將取得item相對(duì)與父級(jí)的位置,不是整個(gè)document.所有的腳本我們都是相對(duì)整個(gè)document,這樣會(huì)更好一些.

為了完成getPosition任務(wù),必須循環(huán)取得item的父級(jí),我們將加載內(nèi)容到item的左/上的位置.我們需要管理想要的top與left列表.

自從定義了mousemove這個(gè)函數(shù),mouseMove就會(huì)一直運(yùn)行.第一我們確定item的style.position為absolute,第二我們移動(dòng)item到前面定義好的位置.當(dāng)mouse點(diǎn)擊被釋放,dragObject被設(shè)置為null,mouseMove將不在做任何事.

Dropping an Item

前面的例子目的很簡(jiǎn)單,就是拖拽item到我們希望到的地方.我們經(jīng)常還有其他目的如刪除item,比如我們可以將item拖到垃圾桶里,或者其他頁(yè)面定義的位置.

很不幸,我們有一個(gè)很大的難題,當(dāng)我們拖拽,item會(huì)在鼠標(biāo)之下,比如mouseove,mousedown,mouseup或者其他mouse action.如果我們拖拽一個(gè)item到垃圾桶上,鼠標(biāo)信息還在item上,不在垃圾桶上.

怎么解決這個(gè)問(wèn)題呢?有幾個(gè)方法可以來(lái)解決.第一,這是以前比較推薦的,我們?cè)谝苿?dòng)鼠標(biāo)時(shí)item會(huì)跟隨鼠標(biāo),并占用了mouseover/mousemove等鼠標(biāo)事件,我們不這樣做,只是讓item跟隨著鼠標(biāo),并不占用mouseover等鼠標(biāo)事件,這樣會(huì)解決問(wèn)題,但是這樣并不好看,我們還是希望item能直接跟在mouse下.

另一個(gè)選擇是不做item的拖拽.你可以改變鼠標(biāo)指針來(lái)顯示需要拖拽的item,然后放在鼠標(biāo)釋放的位置.這個(gè)解決方案,也是因?yàn)槊缹W(xué)原因不予接受.

最后的解決方案是,我們并不去除拖拽效果.這種方法比前兩種繁雜許多,我們需要定義我們需要釋放目標(biāo)的列表,當(dāng)鼠標(biāo)釋放時(shí),手工去檢查釋放的位置是否是在目標(biāo)列表位置上,如果在,說(shuō)明是釋放在目標(biāo)位置上了.

/*
All code from the previous example is needed with the exception
of the mouseUp function which is replaced below
*/
var dropTargets = [];
function addDropTarget(dropTarget){
dropTargets.push(dropTarget);
}
function mouseUp(ev){
ev           = ev || window.event;
var mousePos = mouseCoords(ev);
for(var i=0; i<dropTargets.length; i++){
var curTarget  = dropTargets[i];
var targPos    = getPosition(curTarget);
var targWidth  = parseInt(curTarget.offsetWidth);
var targHeight = parseInt(curTarget.offsetHeight);
if(
(mousePos.x > targPos.x)                &&
(mousePos.x < (targPos.x + targWidth))  &&
(mousePos.y > targPos.y)                &&
(mousePos.y < (targPos.y + targHeight))){
// dragObject was dropped onto curTarget!
}
}
dragObject   = null;
}

Demo - Drag any image onto the trashcan

     
實(shí)現(xiàn)上面效果的代碼
<script>
var iMouseDown  = false;
var dragObject  = null;
Number.prototype.NaN0=function(){return isNaN(this)?0:this;}
// Demo 0 variables
var DragDrops   = [];
var curTarget   = null;
var lastTarget  = null;
function makeDraggable(item){
if(!item) return;
item.onmousedown = function(ev){
dragObject  = this;
mouseOffset = getMouseOffset(this, ev);
return false;
}
}
function getMouseOffset(target, ev){
ev = ev || window.event;
var docPos    = getPosition(target);
var mousePos  = mouseCoords(ev);
return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}
function getPosition(e){
var left = 0;
var top  = 0;
while (e.offsetParent){
left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
e     = e.offsetParent;
}
left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
return {x:left, y:top};
}
function mouseCoords(ev){
if(ev.pageX || ev.pageY){
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop  - document.body.clientTop
};
}
function mouseDown(ev){
ev         = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.onmousedown || target.getAttribute(‘DragObj‘)){
return false;
}
}
function mouseUp(ev){
//dragObject = null;
if(dragObject){
ev           = ev || window.event;
var mousePos = mouseCoords(ev);
var dT = dragObject.getAttribute(‘droptarget‘);
if(dT){
var targObj = document.getElementById(dT);
var objPos  = getPosition(targObj);
if((mousePos.x > objPos.x) && (mousePos.y > objPos.y)
&& (mousePos.x<(objPos.x+parseInt(targObj.offsetWidth)))
&& (mousePos.y<(objPos.y+parseInt(targObj.offsetHeight)))){
var nSrc = targObj.getAttribute(‘newSrc‘);
if(nSrc){
dragObject.src = nSrc;
setTimeout(function(){
if(!dragObject || !dragObject.parentNode) return;
dragObject.parentNode.removeChild(dragObject);
dragObject = null;
}, parseInt(targObj.getAttribute(‘timeout‘)));
} else {
dragObject.parentNode.removeChild(dragObject);
}
}
}
}
dragObject = null;
iMouseDown = false;
}
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);
if(dragObject){
dragObject.style.position = ‘a(chǎn)bsolute‘;
dragObject.style.top      = mousePos.y - mouseOffset.y;
dragObject.style.left     = mousePos.x - mouseOffset.x;
}
// track the current mouse state so we can compare against it next time
lMouseState = iMouseDown;
// this prevents items on the page from being highlighted while dragging
if(curTarget || dragObject) return false;
}
function addDropTarget(item, target){
item.setAttribute(‘droptarget‘, target);
}
document.onmousemove = mouseMove;
document.onmousedown = mouseDown;
document.onmouseup   = mouseUp;
window.onload = function (){
makeDraggable(document.getElementById(‘DragImage9‘));
makeDraggable(document.getElementById(‘DragImage10‘));
makeDraggable(document.getElementById(‘DragImage11‘));
makeDraggable(document.getElementById(‘DragImage12‘));
addDropTarget(document.getElementById(‘DragImage9‘),  ‘TrashImage1‘);
addDropTarget(document.getElementById(‘DragImage10‘), ‘TrashImage1‘);
addDropTarget(document.getElementById(‘DragImage11‘), ‘TrashImage1‘);
addDropTarget(document.getElementById(‘DragImage12‘), ‘TrashImage1‘);
}
</script>
<FIELDSET id=Demo6 style="HEIGHT: 70px"><h3>Demo - Drag any image onto the
trashcan</h3><IMG id=TrashImage1
src="images/drag_drop_trash.gif"
timeout="600" newSrc="images/transparent.gif">      
<IMG
id=DragImage9
src="images/drag_drop_spade.gif">
<IMG
id=DragImage10
src="images/drag_drop_heart.gif">
<IMG
id=DragImage11
src="images/drag_drop_diamond.gif">
<IMG
id=DragImage12
src="images/drag_drop_club.gif">
</FIELDSET>

鼠標(biāo)釋放時(shí)會(huì)去取是否有drop屬性,如果存在,同時(shí)鼠標(biāo)指針還在drop的范圍內(nèi),執(zhí)行drop操作.我們檢查鼠標(biāo)指針位置是否在目標(biāo)范圍是用(mousePos.x>targetPos.x),而且還要符合條件(mousePos.x<(targPos.x + targWidth)).如果所有的條件符合,說(shuō)明指針確實(shí)在范圍內(nèi),可以執(zhí)行drop指令了.

Pulling It All Together

最后我們擁有了所有的drag/drop的腳本片斷!下一個(gè)事情是我們將創(chuàng)建一個(gè)DOM處理.如果你不是很熟悉,請(qǐng)先閱讀我的JavaScript Primer on DOM Manipulation.

下面的代碼將創(chuàng)建container(容器),而且使任何一個(gè)需要drag/drop的item變成一個(gè)容器的item.代碼在這個(gè)文章第二個(gè)demo的后面,它可以用戶記錄一個(gè)list(列表),定為一個(gè)導(dǎo)航窗口在左邊或者右邊,或者更多的函數(shù)你可以想到的.

下一步我們將通過(guò)"假代碼"讓reader看到真代碼,下面為推薦:

  1. 當(dāng)document第一次載入時(shí),創(chuàng)建dragHelper DIV.dragHelper將給移動(dòng)的item加陰影.真實(shí)的item沒(méi)有被dragged,只是用了insertBefor和appendChild來(lái)移動(dòng)了,我們隱藏了dragHelper
  2. 有了mouseDown與mouseUp函數(shù).所有的操作會(huì)對(duì)應(yīng)到當(dāng)?shù)絠MouseDown的狀態(tài)中,只有當(dāng)mouse左鍵為按下時(shí)iMouseDown才為真,否則為假.
  3. 我們創(chuàng)建了全局變量DragDrops與全局函數(shù)CreateDragContainer.DragDrops包含了一系列相對(duì)彼此的容器.任何參數(shù)(containers)將通過(guò)CreatedcragContainer進(jìn)行重組與序列化,這樣可以自由的移動(dòng).CreateDragContainer函數(shù)也將item進(jìn)行綁定與設(shè)置屬性.
  4. 現(xiàn)在我們的代碼知道每個(gè)item的加入,當(dāng)我們移動(dòng)處mouseMove,mouseMove函數(shù)首先會(huì)設(shè)置變量target,鼠標(biāo)移動(dòng)在上面的item,如果這個(gè)item在容器中(checked with getAttribute):
    1. 運(yùn)行一小段代碼來(lái)改變目標(biāo)的樣式.創(chuàng)造rollover效果
    2. 檢查鼠標(biāo)是否沒(méi)有放開(kāi),如果沒(méi)有
      1. 設(shè)置curTarget代表當(dāng)前item
      2. 記錄item的當(dāng)前位置,如果需要的話,我們可以將它返回
      3. 克隆當(dāng)前的item到dragHelper中,我們可以移動(dòng)帶陰影效果的item.
      4. item拷貝到dragHelper后,原有的item還在鼠標(biāo)指針下,我們必須刪除掉dragObj,這樣腳本起作用,dragObj被包含在一個(gè)容器中.
      5. 抓取容器中所有的item當(dāng)前坐標(biāo),高度/寬度,這樣只需要記錄一次,當(dāng)item被drag時(shí),每隨mouse移動(dòng),每移鐘就會(huì)記錄成千上萬(wàn)次.
    3. 如果沒(méi)有,不需要做任何事,因?yàn)檫@不是一個(gè)需要移動(dòng)的item
  5. 檢查curTarget,它應(yīng)該包含一個(gè)被移動(dòng)的item,如果存在,進(jìn)行下面操作
    1. 開(kāi)始移動(dòng)帶有陰影的item,這個(gè)item就是前文所創(chuàng)建的
    2. 檢查每個(gè)當(dāng)前容器中的container,是否鼠標(biāo)已經(jīng)移動(dòng)到這些范圍內(nèi)了
      1. 我們檢查看一下正在拖動(dòng)的item是屬于哪個(gè)container
      2. 放置item在一個(gè)container的某一個(gè)item之前,或者整個(gè)container之后
      3. 確認(rèn)item是可見(jiàn)的
    3. 如果鼠標(biāo)不在container中,確認(rèn)item是不可見(jiàn)了.
  6. 剩下的事就是捕捉mouseUp的事件了
    實(shí)現(xiàn)一個(gè)拖動(dòng)的全代碼
        <STYLE>LI {
        MARGIN-BOTTOM: 10px
        }
        OL {
        MARGIN-TOP: 5px
        }
        .DragContainer {
        BORDER-RIGHT: #669999 2px solid; PADDING-RIGHT: 5px; BORDER-TOP: #669999 2px solid; PADDING-LEFT: 5px; FLOAT: left; PADDING-BOTTOM: 0px; MARGIN: 3px; BORDER-LEFT: #669999 2px solid; WIDTH: 100px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 2px solid
        }
        .OverDragContainer {
        BORDER-RIGHT: #669999 2px solid; PADDING-RIGHT: 5px; BORDER-TOP: #669999 2px solid; PADDING-LEFT: 5px; FLOAT: left; PADDING-BOTTOM: 0px; MARGIN: 3px; BORDER-LEFT: #669999 2px solid; WIDTH: 100px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 2px solid
        }
        .OverDragContainer {
        BACKGROUND-COLOR: #eee
        }
        .DragBox {
        BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee
        }
        .OverDragBox {
        BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee
        }
        .DragDragBox {
        BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee
        }
        .miniDragBox {
        BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee
        }
        .OverDragBox {
        BACKGROUND-COLOR: #ffff99
        }
        .DragDragBox {
        BACKGROUND-COLOR: #ffff99
        }
        .DragDragBox {
        FILTER: alpha(opacity=50); BACKGROUND-COLOR: #ff99cc
        }
        LEGEND {
        FONT-WEIGHT: bold; FONT-SIZE: 12px; COLOR: #666699; FONT-FAMILY: verdana, tahoma, arial
        }
        FIELDSET {
        PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px
        }
        .History {
        FONT-SIZE: 10px; OVERFLOW: auto; WIDTH: 100%; FONT-FAMILY: verdana, tahoma, arial; HEIGHT: 82px
        }
        #DragContainer8 {
        BORDER-RIGHT: #669999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #669999 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 0px; BORDER-LEFT: #669999 1px solid; WIDTH: 110px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 1px solid; HEIGHT: 110px
        }
        .miniDragBox {
        FLOAT: left; MARGIN: 0px 5px 5px 0px; WIDTH: 20px; HEIGHT: 20px
        }
        pre{border:1 solid #CCC;background-color:#F8F8F0;padding:10px;}
        </STYLE>
        <script>
        // 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 mouseCoords(ev){
        if(ev.pageX || ev.pageY){
        return {x:ev.pageX, y:ev.pageY};
        }
        return {
        x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
        y:ev.clientY + document.body.scrollTop  - document.body.clientTop
        };
        }
        function getMouseOffset(target, ev){
        ev = ev || window.event;
        var docPos    = getPosition(target);
        var mousePos  = mouseCoords(ev);
        return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
        }
        function getPosition(e){
        var left = 0;
        var top  = 0;
        while (e.offsetParent){
        left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
        top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
        e     = e.offsetParent;
        }
        left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
        top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
        return {x:left, y:top};
        }
        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);
        }
        </script>
        <!--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>

    你現(xiàn)在擁有了拖拽的所有東西.

    下面的三個(gè)demo是記錄事件歷史.當(dāng)你的鼠標(biāo)在item上移動(dòng),將記錄所生的事件,如果你不明白可以嘗試一下鼠標(biāo)的劃過(guò)或者拖動(dòng),看有什么發(fā)生.

    Demo - Drag and Drop any item

    Item #1
    Item #2
    Item #3
    Item #4
    Item #5
    Item #6
    Item #7
    Item #8
    Item #9
    Item #10
    Item #11
    Item #12
    History
    Demo - Drag and Drop any item
    1. Item #1
    2. Item #2
    3. Item #3
    4. Item #4
    5. Item #5

    Demo - Drag and Drop any item

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    關(guān)于譯者

    雪山老人,lamp程序員,web開(kāi)發(fā)者,你可以訪問(wèn)來(lái)了解他!

    關(guān)于作者

    Mark Kahn是一個(gè)web開(kāi)發(fā)者與DBA.你可以訪問(wèn)他的主頁(yè) http://www.聯(lián)系他!

      本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
      轉(zhuǎn)藏 分享 獻(xiàn)花(0

      0條評(píng)論

      發(fā)表

      請(qǐng)遵守用戶 評(píng)論公約

      類(lèi)似文章 更多

      亚洲国产成人av毛片国产| 国产日本欧美韩国在线| 99久久婷婷国产亚洲综合精品| 国产日韩欧美综合视频| 大香蕉再在线大香蕉再在线| 欧美日韩在线视频一区| 日本精品啪啪一区二区三区| 欧美中文字幕一区在线| 老司机精品视频免费入口| 草草视频福利在线观看| 大胆裸体写真一区二区| 日韩中文无线码在线视频| 日韩精品小视频在线观看| 久久香蕉综合网精品视频| 亚洲国产av国产av| 五月情婷婷综合激情综合狠狠 | 久久精品国产亚洲av麻豆| 一区二区三区日韩中文| 国产精品欧美一区二区三区不卡 | 人妻乱近亲奸中文字幕| 免费午夜福利不卡片在线 视频| 老司机精品线观看86| 欧美午夜色视频国产精品| 污污黄黄的成年亚洲毛片| 国产精品成人又粗又长又爽| 国产欧美日韩综合精品二区| 国产传媒一区二区三区| 三级高清有码在线观看| 日韩精品视频香蕉视频| 国产精品久久熟女吞精| 黄色三级日本在线观看| 国产精品蜜桃久久一区二区| 国产成人亚洲综合色就色| 欧美欧美日韩综合一区| 亚洲精品福利入口在线| 欧美激情视频一区二区三区| 又大又长又粗又黄国产| 中日韩免费一区二区三区| 国产在线日韩精品欧美| 欧美成人免费夜夜黄啪啪| 国产日韩欧美在线亚洲|