譯者: Flyingis
上一篇文章 介紹了移動(dòng)頁(yè)面元素所涉及到的捕獲鼠標移動(dòng)和鼠標點(diǎn)擊的相關(guān)問(wèn)題,本段文章將介紹如何移動(dòng)和放置頁(yè)面元素。
移動(dòng)元素
我們現在已經(jīng)知道如何捕獲鼠標移動(dòng)和點(diǎn)擊。接下來(lái)需要做的就是移動(dòng)任何我們想拖動(dòng)的元素。首先,將一個(gè)元素準確移動(dòng)到頁(yè)面上我們想要的位置,該元素樣式表的position值必須為absolute,這意味著(zhù)你可以設置它的style.top或style.left,測量值相對于頁(yè)面的左上角,因為我們所有的鼠標移動(dòng)都是相對于頁(yè)面左上角的,通常都是這樣。
一旦我們設置了item.style.position=‘a(chǎn)bsolute‘,接下來(lái)就需要改變該元素top和left的位置,使它移動(dòng)!











































































你會(huì )注意到這些代碼是以我們前面的例子為基礎的(參考上篇文章),將它們放置在一起,你將能夠隨意的去移動(dòng)元素。
當我們點(diǎn)擊一個(gè)元素時(shí),存儲了另外的一個(gè)變量,mouseOffset。mouseOffset簡(jiǎn)單的包含了我們點(diǎn)擊元素的位置信息。如果我們有一張20*20px的圖像,然后點(diǎn)擊圖像的中間,mouseOffset應該是{x:10, y:10}。如果我們點(diǎn)擊圖像的左上角,mouseOffset應為{x:0, y:0}。我們在鼠標移動(dòng)后的位置信息中用到它。如果我們沒(méi)有存儲這個(gè)值,不論你點(diǎn)擊元素的哪一個(gè)位置,元素相對于鼠標的位置都將會(huì )是相同的。
mouseOffset函數用到了另外一個(gè)函數getPosition。getPosition目的是返回元素相對于documemt文檔的坐標位置。如果我們簡(jiǎn)單的去讀取item.offsetLeft或item.style.left,得到的將是元素相對于它父元素的位置,而不是document文檔的。在我們的腳本中,所有的元素都是相對于document文檔的,因此需要這樣做。
要完成獲取元素相對于document文檔位置的工作,getPosition從它自身的父級開(kāi)始,循環(huán)獲取它的left和top的值并累加,這樣我們就得到了我們想要的元素距文檔頂部和左側的累計值。
當我們獲取了這條信息并移動(dòng)鼠標的時(shí)候,mouseMove開(kāi)始運行。首先我們需要保證item.style.position值為absolute,接著(zhù),我們將元素移動(dòng)到任何一個(gè)地方,鼠標位置都會(huì )減去我們之前記錄的鼠標相對于元素的偏移量。當鼠標釋放時(shí),dragObject將被設置為null,并且mouseMove函數不再做任何事情。
放置元素
我們前面的例子已經(jīng)處理了這個(gè)問(wèn)題,僅僅是拖動(dòng)一個(gè)元素,然后將它放下。然后,在我們放下元素的時(shí)候通常還有其他的目的,我們以拖動(dòng)元素到垃圾回收站為例,或我們可能想讓該元素和頁(yè)面中某個(gè)特定的區域對齊。
不幸的是我們在這里進(jìn)入了一個(gè)相對主要的問(wèn)題。因為我們正在移動(dòng)的元素總是直接處于我們的鼠標下,而不可能去引發(fā)mouseover、mousedown、mouseup或鼠標對頁(yè)面中其他元素的操作。如果你移動(dòng)一個(gè)元素到垃圾回收站,你的鼠標會(huì )一直在移動(dòng)元素的上方,而不是垃圾回收站。
那么我們該如何處理這個(gè)問(wèn)題呢?這里有幾種解決方案。在前面所提到的mouseOffset的目的是保證元素總是在鼠標下方正確的位置,如果你忽視了這點(diǎn),然后總是使得元素在鼠標的右下方,你的鼠標將不會(huì )被你正在拖動(dòng)的元素所隱藏,我們也不會(huì )碰到問(wèn)題。但事實(shí)上往往不會(huì )這樣,為了美觀(guān)我們通常要保持元素在鼠標的下方。
另外一種選擇是不移動(dòng)你正在拖動(dòng)的元素,你可以改變鼠標樣式,來(lái)告訴使用者你正在拖動(dòng)一個(gè)元素,直到你將它放置到某個(gè)地方。這解決了我們的問(wèn)題,但是帶來(lái)了和前面一種方案面臨的同樣問(wèn)題:美觀(guān)。
我們最后的一種解決方案既不影響你正在移動(dòng)的元素,也不影響移動(dòng)終點(diǎn)位置上的元素(例如垃圾回收站)。不幸的是,這比前面兩種解決方案的難度更大。我們將要做的是獲得一組我們要放置的目標,當鼠標釋放時(shí),我們手工檢查當前鼠標相對于每個(gè)目標的位置,看鼠標是否釋放在這個(gè)目標中某一個(gè)目標的位置上,如果是的,我們就知道我們已經(jīng)將元素放置在我們的目標上了。









































這個(gè)例子中當鼠標釋放時(shí),我們循環(huán)每個(gè)可能放置元素的目標,如果鼠標指針在目標上,我們則擁有了一個(gè)放置元素的事件,通過(guò)鼠標橫坐標大于目標元素左側橫坐標(mousePos.x>targPos.x),小于目標元素右側橫坐標(mousePos.x<(targPos.x+targWidth))來(lái)判定,對于Y坐標我們做同樣的判斷。如果所有的這些值都返回true,那么我們的鼠標就是在目標元素的范圍內。
原文鏈接:http://www.webreference.com/programming/javascript/mk/column2/2.html
另外兩篇:[翻譯] 如何在 JavaScript 中實(shí)現拖放(上) [翻譯] 如何在 JavaScript 中實(shí)現拖放(下)

