Flyingis

          Talking and thinking freely !
          Flying in the world of GIS !
          隨筆 - 156, 文章 - 16, 評論 - 589, 引用 - 0
          數據加載中……

          [翻譯] 如何在 JavaScript 中實現拖放(中)

          ??? 譯者: Flyingis?

          ??? 上一篇文章
          介紹了移動頁面元素所涉及到的捕獲鼠標移動和鼠標點擊的相關問題,本段文章將介紹如何移動和放置頁面元素。

          ??? 移動元素

          ??? 我們現在已經知道如何捕獲鼠標移動和點擊。接下來需要做的就是移動任何我們想拖動的元素。首先,將一個元素準確移動到頁面上我們想要的位置,該元素樣式表的position值必須為absolute,這意味著你可以設置它的style.top或style.left,測量值相對于頁面的左上角,因為我們所有的鼠標移動都是相對于頁面左上角的,通常都是這樣。

          ??? 一旦我們設置了item.style.position='absolute',接下來就需要改變該元素top和left的位置,使它移動!

          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?
          =
          ?'absolute';
          ????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
          ;
          ??}

          }

          ??? 你會注意到這些代碼是以我們前面的例子為基礎的(參考上篇文章),將它們放置在一起,你將能夠隨意的去移動元素。

          ??? 當我們點擊一個元素時,存儲了另外的一個變量,mouseOffset。mouseOffset簡單的包含了我們點擊元素的位置信息。如果我們有一張20*20px的圖像,然后點擊圖像的中間,mouseOffset應該是{x:10, y:10}。如果我們點擊圖像的左上角,mouseOffset應為{x:0, y:0}。我們在鼠標移動后的位置信息中用到它。如果我們沒有存儲這個值,不論你點擊元素的哪一個位置,元素相對于鼠標的位置都將會是相同的。

          ??? mouseOffset函數用到了另外一個函數getPosition。getPosition目的是返回元素相對于documemt文檔的坐標位置。如果我們簡單的去讀取item.offsetLeft或item.style.left,得到的將是元素相對于它父元素的位置,而不是document文檔的。在我們的腳本中,所有的元素都是相對于document文檔的,因此需要這樣做。

          ??? 要完成獲取元素相對于document文檔位置的工作,getPosition從它自身的父級開始,循環獲取它的left和top的值并累加,這樣我們就得到了我們想要的元素距文檔頂部和左側的累計值。

          ??? 當我們獲取了這條信息并移動鼠標的時候,mouseMove開始運行。首先我們需要保證item.style.position值為absolute,接著,我們將元素移動到任何一個地方,鼠標位置都會減去我們之前記錄的鼠標相對于元素的偏移量。當鼠標釋放時,dragObject將被設置為null,并且mouseMove函數不再做任何事情。

          ??? 放置元素

          ??? 我們前面的例子已經處理了這個問題,僅僅是拖動一個元素,然后將它放下。然后,在我們放下元素的時候通常還有其他的目的,我們以拖動元素到垃圾回收站為例,或我們可能想讓該元素和頁面中某個特定的區域對齊。

          ??? 不幸的是我們在這里進入了一個相對主要的問題。因為我們正在移動的元素總是直接處于我們的鼠標下,而不可能去引發mouseover、mousedown、mouseup或鼠標對頁面中其他元素的操作。如果你移動一個元素到垃圾回收站,你的鼠標會一直在移動元素的上方,而不是垃圾回收站。

          ??? 那么我們該如何處理這個問題呢?這里有幾種解決方案。在前面所提到的mouseOffset的目的是保證元素總是在鼠標下方正確的位置,如果你忽視了這點,然后總是使得元素在鼠標的右下方,你的鼠標將不會被你正在拖動的元素所隱藏,我們也不會碰到問題。但事實上往往不會這樣,為了美觀我們通常要保持元素在鼠標的下方。

          ??? 另外一種選擇是不移動你正在拖動的元素,你可以改變鼠標樣式,來告訴使用者你正在拖動一個元素,直到你將它放置到某個地方。這解決了我們的問題,但是帶來了和前面一種方案面臨的同樣問題:美觀。

          ??? 我們最后的一種解決方案既不影響你正在移動的元素,也不影響移動終點位置上的元素(例如垃圾回收站)。不幸的是,這比前面兩種解決方案的難度更大。我們將要做的是獲得一組我們要放置的目標,當鼠標釋放時,我們手工檢查當前鼠標相對于每個目標的位置,看鼠標是否釋放在這個目標中某一個目標的位置上,如果是的,我們就知道我們已經將元素放置在我們的目標上了。

          /*
          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 ;
          }

          ??? 這個例子中當鼠標釋放時,我們循環每個可能放置元素的目標,如果鼠標指針在目標上,我們則擁有了一個放置元素的事件,通過鼠標橫坐標大于目標元素左側橫坐標(mousePos.x>targPos.x),小于目標元素右側橫坐標(mousePos.x<(targPos.x+targWidth))來判定,對于Y坐標我們做同樣的判斷。如果所有的這些值都返回true,那么我們的鼠標就是在目標元素的范圍內。

          ??? 原文鏈接:http://www.webreference.com/programming/javascript/mk/column2/2.html

          ??? 另外兩篇:[翻譯] 如何在 JavaScript 中實現拖放(上)?? [翻譯] 如何在 JavaScript 中實現拖放(下)

          posted on 2006-10-13 14:53 Flyingis 閱讀(5308) 評論(2)  編輯  收藏 所屬分類: Web 客戶端技術

          評論

          # re: [翻譯] 如何在 JavaScript 中實現拖放(中)  回復  更多評論   

          不錯,收藏了。。呵呵
          2006-10-13 20:56 | Vista

          # re: [翻譯] 如何在 JavaScript 中實現拖放(中)  回復  更多評論   

          增開7群,號碼 30440732
          8群 30756649
          9群 30178567
          10群 28694497

          我們的qq群:15096318 學習程序的都可以來
          2006-10-18 15:45 | 123bingbing
          主站蜘蛛池模板: 大新县| 安乡县| 朔州市| 平乐县| 同仁县| 永昌县| 五常市| 平和县| 乌鲁木齐市| 耒阳市| 峨边| 晋城| 灵宝市| 新田县| 周宁县| 辰溪县| 宁国市| 缙云县| 澎湖县| 黑山县| 会昌县| 萝北县| 大安市| 山东| 慈利县| 无棣县| 兴城市| 福泉市| 驻马店市| 绵阳市| 舒兰市| 大竹县| 龙海市| 台江县| 康平县| 沅江市| 凤山县| 策勒县| 阿克苏市| 会昌县| 东平县|