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











































































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









































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