js可拖動的代碼(js規定拖動的區域)

  • 1、js怎麼實現一個拖拽事件
  • 2、js實現圖片拖動代碼,希望大神給代碼詳細的注釋(解釋)下。
  • 3、js實現div的拖拽
  • 4、js鼠標拖動div

Javascript的特點是dom的處理與網頁效果,大多數情況我們只用到了這個語言的最簡單的功能,比如製作圖片輪播/網頁的tab等等,這篇文章將向你展示如何在自己的網頁上製作拖拽.

有很多理由讓你的網站加入拖拽功能,最簡單的一個是數據重組.例如:你有一個序列的內容讓用戶排序,用戶需要給每個條目進行輸入或者用select 選擇,替代前面這個方法的就是拖拽.或許你的網站也需要一個用戶可以拖動的導航窗口!那麼這些效果都是很簡單:因為你可以很容易的實現!

網頁上實現拖拽其實也不是很複雜.第一你需要知道鼠標坐標,第二你需要知道用戶鼠標點擊一個網頁元素並實現拖拽,最後我們要實現移動這個元素.

獲取鼠標移動信息

第一我們需要獲取鼠標的坐標.我們加一個用戶函數到document.onmousemove就可以了:

Java代碼 收藏代碼

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

};

}

你首先要聲明一個evnet對象.不論何時你移動鼠標/點擊/按鍵等等,會對應一個event的事件.在Internet Explorer里event是全局變量,會被存儲在window.event里. 在firefox中,或者其他瀏覽器,event事件會被相應的自定義函數獲取.當我們將mouseMove函數賦值於document.onmousemove,mouseMove會獲取鼠標移動事件.

(ev = ev || window.event) 這樣讓ev在所有瀏覽器下獲取了event事件,在Firefox下”||window.event”將不起作用,因為ev已經有了賦值.在MSIE下ev是空的,所以ev將設置為window.event.

因為我們在這篇文章中需要多次獲取鼠標坐標,所以我們設計了mouseCoords這個函數,它只包含了一個參數,就是the event.

我們需要運行在MSIE與Firefox為首的其他瀏覽器下.Firefox以event.pageX和event.pageY來代表鼠標相應於文檔左上角的位置.如果你有一個500*500的窗口,而且你的鼠標在正中間,那麼paegX和pageY將是250,當你將頁面往下滾動500px,那麼 pageY將是750.此時pageX不變,還是250.

MSIE和這個相反,MSIE將event.clientX與event.clientY來代表鼠標與ie窗口的位置,並不是文檔.當我們有一個 500*500的窗口,鼠標在正中間,那麼clientX與clientY也是250,如果你垂直滾動窗口到任何位置,clientY仍然是250,因為相對ie窗口並沒有變化.想得到正確的結果,我們必須加入scrollLeft與scrollTop這兩個相對於文檔鼠標位置的屬性.最後,由於MSIE 並沒有0,0的文檔起始位置,因為通常會設置2px的邊框在周圍,邊框的寬度包含在document.body.clientLeft與 clientTop這兩個屬性中,我們再加入這些到鼠標的位置中.

很幸運,這樣mouseCoords函數就完成了,我們不再為坐標的事操心了.

捕捉鼠標點擊

下次我們將知道鼠標何時點擊與何時放開.如果我們跳過這一步,我們在做拖拽時將永遠不知道鼠標移動上面時的動作,這將是惱人的與違反直覺的.

這裡有兩個函數幫助我們:onmousedown與onmouseup.我們預先設置函數來接收document.onmousemove,這樣看起來很象我們會獲取document.onmousedown與document.onmouseup.但是當我們獲取 document.onmousedown時,我們同時獲取了任何對象的點擊屬性如:text,images,tables等等.我們只想獲取那些需要拖拽的屬性,所以我們設置函數來獲取我們需要移動的對象.

移動一個元素

我們知道了怎麼捕捉鼠標移動與點擊.剩下的就是移動元素了.首先,要確定一個明確的頁面位置,css樣式表要用’absolute’.設置元素絕對位置意味着我們可以用樣式表的.top和.left來定位,可以用相對位置來定位了.我們將鼠標的移動全部相對頁面top-left,基於這點,我們可以進行下一步了.

當我們定義item.style.position=’absolute’,所有的操作都是改變left坐標與top坐標,然後它移動了.

Java代碼 收藏代碼

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;

}

}

你會注意到這個代碼幾乎是前面的全集,將前面的合在一起就實現了拖拽效果了.

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

mouseOffset函數使用了另一個函數getPosition.getPosition的作用是返回 item相對頁面左上角的坐標,如果我們嘗試獲取item.offsetLeft或者item.style.left,那麼我們將取得item相對與父級的位置,不是整個document.所有的腳本我們都是相對整個document,這樣會更好一些.

為了完成getPosition任務,必須循環取得item的父級,我們將加載內容到item的左/上的位置.我們需要管理想要的top與left列表.

自從定義了mousemove這個函數,mouseMove就會一直運行.第一我們確定item的 style.position為absolute,第二我們移動item到前面定義好的位置.當mouse點擊被釋放,dragObject被設置為 null,mouseMove將不在做任何事.

Dropping an Item

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

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

怎麼解決這個問題呢?有幾個方法可以來解決.第一,這是以前比較推薦的,我們在移動鼠標時item會跟隨鼠標,並佔用了mouseover/mousemove等鼠標事件,我們不這樣做,只是讓item跟隨着鼠標,並不佔用mouseover等鼠標事件,這樣會解決問題,但是這樣並不好看,我們還是希望item能直接跟在mouse下.

另一個選擇是不做item的拖拽.你可以改變鼠標指針來顯示需要拖拽的item,然後放在鼠標釋放的位置.這個解決方案,也是因為美學原因不予接受.

最後的解決方案是,我們並不去除拖拽效果.這種方法比前兩種繁雜許多,我們需要定義我們需要釋放目標的列表,當鼠標釋放時,手工去檢查釋放的位置是否是在目標列表位置上,如果在,說明是釋放在目標位置上了.

Java代碼 收藏代碼

/*

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; idropTargets.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;

}

鼠標釋放時會去取是否有drop屬性,如果存在,同時鼠標指針還在drop的範圍內,執行drop操作.我們檢查鼠標指針位置是否在目標範圍是用(mousePos.xtargetPos.x),而且還要符合條件(mousePos.x(targPos.x + targWidth)).如果所有的條件符合,說明指針確實在範圍內,可以執行drop指令了.

Pulling It All Together

最後我們擁有了所有的drag/drop的腳本片斷!下一個事情是我們將創建一個DOM處理.

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

下一步我們將通過”假代碼”讓reader看到真代碼,下面為推薦:

1、當document第一次載入時,創建dragHelper DIV.dragHelper將給移動的item加陰影.真實的item沒有被dragged,只是用了insertBefor和appendChild來移動了,我們隱藏了dragHelper

2、有了mouseDown與mouseUp函數.所有的操作會對應到當到iMouseDown的狀態中,只有當mouse左鍵為按下時iMouseDown才為真,否則為假.

3、我們創建了全局變量DragDrops與全局函數CreateDragContainer.DragDrops包含了一系列相對彼此的容器.任何參數(containers)將通過CreatedcragContainer進行重組與序列化,這樣可以自由的移動.CreateDragContainer函數也將item進行綁定與設置屬性.

4、現在我們的代碼知道每個item的加入,當我們移動處mouseMove,mouseMove函數首先會設置變量target,鼠標移動在上面的item,如果這個item在容器中(checked with getAttribute):

* 運行一小段代碼來改變目標的樣式.創造rollover效果

* 檢查鼠標是否沒有放開,如果沒有

o 設置curTarget代表當前item

o 記錄item的當前位置,如果需要的話,我們可以將它返回

o 克隆當前的item到dragHelper中,我們可以移動帶陰影效果的item.

o item拷貝到dragHelper後,原有的item還在鼠標指針下,我們必須刪除掉dragObj,這樣腳本起作用,dragObj被包含在一個容器中.

o 抓取容器中所有的item當前坐標,高度/寬度,這樣只需要記錄一次,當item被drag時,每隨mouse移動,每移鍾就會記錄成千上萬次.

* 如果沒有,不需要做任何事,因為這不是一個需要移動的item

5、檢查curTarget,它應該包含一個被移動的item,如果存在,進行下面操作:

* 開始移動帶有陰影的item,這個item就是前文所創建的

* 檢查每個當前容器中的container,是否鼠標已經移動到這些範圍內了

o 我們檢查看一下正在拖動的item是屬於哪個container

o 放置item在一個container的某一個item之前,或者整個container之後

o 確認item是可見的

* 如果鼠標不在container中,確認item是不可見了.

!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “”

html xmlns=”” xml:lang=”en”

head

meta http-equiv=”Content-Type” content=”text/html;charset=UTF-8″

titleDocument/title

/head

body

div id=”box1″ style = ‘width:100px; height: 100px; background:#ccc; position:fixed;’/div

!– 注意 盒子一定要定位 position:fixed; 或者 position:absolute;–

/body

script type=”text/javascript”

function getPos(e){//這是一個 獲取鼠標位置的函數

var oEvent = e || event;

return {x: oEvent.clientX + document.documentElement.scrollLeft || document.body.scrollLeft,

y: oEvent.clientY +document.documentElement.scrollTop || document.body.scrollTop};

}

document.getElementById(‘box1’).onmousedown = function(e){ //你要拖動對象在mousedown的時候發生的事情

var oEvent = e || event;

var pos = getPos(oEvent);

var _this = this;

_this.style.cursor = ‘move’;//改變鼠標狀態

_this.disY = pos.y – _this.offsetTop;

_this.disX = pos.x – _this.offsetLeft;

document.onmousemove =function(e){ //在鼠標按下的時候 並且 移動的時候 發生的事情

var oEvent = e || event;

var dpos = getPos(oEvent);

var t = dpos.y-_this.disY ; //移動的時候獲取的 移動 top值

var l = dpos.x-_this.disX ;//移動的時候獲取的 移動 left

_this.style.top=t + “px”; //這兩條給盒子賦值

_this.style.left=l + “px”;

};

document.onmouseup = function(){//鼠標彈起的時候做的事情 一些釋放 操作

_this.style.cursor = ‘pointer’

this.onmousemove = null;

this.onmouseup = null;

try{

_this.releaseCapture();}catch(e){}

};

try{

_this.setCapture();}catch(b){} //這裡是為了 讓盒子拖動的時候不要複製頁面裏面的其他內容

return false;

};

/script

/html

div id=”c” onmousedown=”mm(event);”123123/div

evt參數是就是上面的event對象;

Event 對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。

因為火狐不支持直接獲取event對象.因此FF在觸發拖拽事件前需要明確傳遞event.

IE則不需要.所以才出現 e = evt || event; 主要是兼容所用.

e.clientX是獲取當前鼠標的橫坐標.

你的obj.style.left是獲取不到的因為該div沒有設置style屬性所以只要將樣式改為行內就行了

!DOCTYPE html

html lang=”en”

head

    meta charset=”UTF-8″

    title文哥討厭IE/title

/head

body

    div id=”over” onmousedown=”down(this,event)” style=”width:100px;height:30px;background:red;position:absolute;left:20px;top:500px;” onmousemove=”move(this,event)” onmouseup=”seup(this,event)”

        

    /div

script type=”text/javascript”

    var posX,posY;

    var downX,downY;

    var mark=false;

    function down(obj,event)

    {

        obj.style.cursor=”move”;

        posX=obj.style.left;

        posY=obj.style.top;

        downX=event.clientX;

        downY=event.clientY;

        mark=true;

        ///alert(posX);

        ///alert(posY);

    }

    function move(obj,event)

    {

        var moveX=event.clientX;

        var moveY=event.clientY;

        if (mark) {

            obj.style.left=parseInt(moveX) + parseInt(posX) – parseInt(downX) + “px”;

            obj.style.top=parseInt(moveY) + parseInt(posY) – parseInt(downY)+ “px”;

        }

    }

    function seup(obj,event)

    {

        if (mark) {

            var moveX=event.clientX;

            var moveY=event.clientY;

            obj.style.left=parseInt(moveX) + parseInt(posX) – parseInt(downX)+ “px”;

            obj.style.top=parseInt(moveY) + parseInt(posY) – parseInt(downY)+ “px”;

            downX=moveX;

            downY=moveY;

        }

        obj.style.cursor=”default”;

            mark = false; 

    }

/script

/body

/html

原創文章,作者:WADYJ,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/127226.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
WADYJ的頭像WADYJ
上一篇 2024-10-03 23:13
下一篇 2024-10-03 23:13

相關推薦

  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • Python字符串寬度不限制怎麼打代碼

    本文將為大家詳細介紹Python字符串寬度不限制時如何打代碼的幾個方面。 一、保持代碼風格的統一 在Python字符串寬度不限制的情況下,我們可以寫出很長很長的一行代碼。但是,為了…

    編程 2025-04-29
  • Python基礎代碼用法介紹

    本文將從多個方面對Python基礎代碼進行解析和詳細闡述,力求讓讀者深刻理解Python基礎代碼。通過本文的學習,相信大家對Python的學習和應用會更加輕鬆和高效。 一、變量和數…

    編程 2025-04-29
  • 倉庫管理系統代碼設計Python

    這篇文章將詳細探討如何設計一個基於Python的倉庫管理系統。 一、基本需求 在着手設計之前,我們首先需要確定倉庫管理系統的基本需求。 我們可以將需求分為以下幾個方面: 1、庫存管…

    編程 2025-04-29
  • Python滿天星代碼:讓編程變得更加簡單

    本文將從多個方面詳細闡述Python滿天星代碼,為大家介紹它的優點以及如何在編程中使用。無論是剛剛接觸編程還是資深程序員,都能從中獲得一定的收穫。 一、簡介 Python滿天星代碼…

    編程 2025-04-29
  • 寫代碼新手教程

    本文將從語言選擇、學習方法、編碼規範以及常見問題解答等多個方面,為編程新手提供實用、簡明的教程。 一、語言選擇 作為編程新手,選擇一門編程語言是很關鍵的一步。以下是幾個有代表性的編…

    編程 2025-04-29
  • Python實現簡易心形代碼

    在這個文章中,我們將會介紹如何用Python語言編寫一個非常簡單的代碼來生成一個心形圖案。我們將會從安裝Python開始介紹,逐步深入了解如何實現這一任務。 一、安裝Python …

    編程 2025-04-29
  • 怎麼寫不影響Python運行的長段代碼

    在Python編程的過程中,我們不可避免地需要編寫一些長段代碼,包括函數、類、複雜的控制語句等等。在編寫這些代碼時,我們需要考慮代碼可讀性、易用性以及對Python運行性能的影響。…

    編程 2025-04-29
  • 北化教務管理系統介紹及開發代碼示例

    本文將從多個方面對北化教務管理系統進行介紹及開發代碼示例,幫助開發者更好地理解和應用該系統。 一、項目介紹 北化教務管理系統是一款針對高校學生和教職工的綜合信息管理系統。系統實現的…

    編程 2025-04-29
  • Python愛心代碼動態

    本文將從多個方面詳細闡述Python愛心代碼動態,包括實現基本原理、應用場景、代碼示例等。 一、實現基本原理 Python愛心代碼動態使用turtle模塊實現。在繪製一個心形的基礎…

    編程 2025-04-29

發表回復

登錄後才能評論