Ⅰ js實現div的拖拽
<style>
*{
margin:0;
padding:0
}
#user_cover{
position:fixed;
top:40%;
right:0;
width:4rem;
height:4rem;
background-color:rgba(0,0,0,0.3);
}
</style>
<divid="user_cover"></div>
<script>
functiononTouchMove(point){
document.getElementById('user_cover').style.top=(point.changedTouches[0].clientY)+"px";
document.getElementById('user_cover').style.left=(point.changedTouches[0].clientX)+"px";
}
functiononMouseDown(point){
document.onmousemove=function(event){
document.getElementById('user_cover').style.top=event.clientY+"px";
document.getElementById('user_cover').style.left=event.clientX+"px";
console.log(point);
console.log(event);
};
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
};
}
document.getElementById('user_cover').addEventListener('touchmove',onTouchMove,false);
document.getElementById('user_cover').addEventListener('mousedown',onMouseDown,false);
</script>
Ⅱ js怎麼實現一個拖拽事件
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; 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;
}
滑鼠釋放時會去取是否有drop屬性,如果存在,同時滑鼠指針還在drop的范圍內,執行drop操作.我們檢查滑鼠指針位置是否在目標范圍是用(mousePos.x>targetPos.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是不可見了.
Ⅲ THREE.js如何實現在x,y,z軸上的拖拽
THREE.js實現在x,y,z軸上的拖拽需要用戶注冊拖拽控制項。
1、注冊的js代碼如下:
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://raw.github.com/zz85/ThreeLabs/master/DragControls.js';
document.body.appendChild(script);
script.onload = function(){
var dragcontrols = new THREE.DragControls(camera, scene, renderer.domElement);
};
2、運行效果如下:
說明:以上每一個點都可以自由拖拽。
Ⅳ js 實現拖拽元素
因為需要計算元素的位置變化,所以需要掌握幾個關於位置的api
點擊需要拖動元素時,獲取該元素的初始位置。
滑鼠移動期間 獲取元素當前的位置信息
計算
進行事件監聽
拖拽的實現原理:通過事件mousedown(事件的觸發) →mousemove(事件的控制) →mouseup(事件的清除),拖拽的過程就是mousemove階段;
問題產生的原因:因為mousemove 的間隔性觸發,當兩次mousemove事件觸發的間隔中,滑鼠移動距離出了element的范圍,就會產生滑鼠脫離element范圍,拖拽就停止,
解決方法: 將mousemove事件掛在docment,而不是對應的element,此時滑鼠滑動只要不出docment范圍就不會觸發上述情況。
拖動事件完成的動作時是:mousedown(事件的觸發) →mousemove(事件的控制) →mouseup(事件的清除) 但是mouseup的時候 同時會觸發 點擊事件(如果元素上面有點擊事件的話)
處理辦法:記錄mousedown(記錄開始時間) →mousemove→mouseup(記錄結束時間) 的時間 根據時間長短判斷是進行了點擊事件還是進行了拖拽事件。
正常需求的話 就希望拖拽元素只在屏幕的可視范圍內進行拖拽,不能跑出去。
在onmousemove 中添加邊緣控制就好,具體范圍可以根據具體需求更改。