javascript 實現(xiàn)拖拽實現(xiàn)原理。如下:
10多年的稷山網(wǎng)站建設經(jīng)驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。網(wǎng)絡營銷推廣的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調整稷山建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“稷山網(wǎng)站設計”,“稷山網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
用JavaScript事件方法表示就是:
① onmousedown + onmousemove → startDrag()
? ② onmouseup → stopDrag()
1.首先調用js文件,如下:
script?src=""?type="text/javascript"/script
2.然后使用startDrag()方法綁定拖拽效果,startDrag()方法有兩個參數(shù),第一個是點擊的對象(即點擊那里可以實現(xiàn)拖拽,例如彈出層的標題欄),第二個是拖拽的對象(例如一個彈出層)。也就是startDrag(觸發(fā)拖拽對象,被拖拽對象)。
style?type="text/css"
#box{position:absolute;?left:100px;?top:100px;?padding:5px;?background:#f0f3f9;?font-size:12px;?-moz-box-shadow:2px?2px?4px?#666666;?-webkit-box-shadow:2px?2px?4px?#666666;}
#main{border:1px?solid?#a0b3d6;?background:white;}
#bar{line-height:24px;?background:#beceeb;?border-bottom:1px?solid?#a0b3d6;?padding-left:5px;?cursor:move;}
#content{width:420px;?height:250px;?padding:10px?5px;}
/style
div?id="box"
div?id="main"
div?id="bar"拖拽/div
div?id="content"
內容……
/div
/div
/div
JS部分
script?src=""?type="text/javascript"/script
script?type="text/javascript"
var?oBox?=?document.getElementById("box");
var?oBar?=?document.getElementById("bar");
startDrag(oBar,?oBox);
/script
Javascript的特點是dom的處理與網(wǎng)頁效果,大多數(shù)情況我們只用到了這個語言的最簡單的功能,比如制作圖片輪播/網(wǎng)頁的tab等等,這篇文章將向你展示如何在自己的網(wǎng)頁上制作拖拽.
有很多理由讓你的網(wǎng)站加入拖拽功能,最簡單的一個是數(shù)據(jù)重組.例如:你有一個序列的內容讓用戶排序,用戶需要給每個條目進行輸入或者用select 選擇,替代前面這個方法的就是拖拽.或許你的網(wǎng)站也需要一個用戶可以拖動的導航窗口!那么這些效果都是很簡單:因為你可以很容易的實現(xiàn)!
網(wǎng)頁上實現(xiàn)拖拽其實也不是很復雜.第一你需要知道鼠標坐標,第二你需要知道用戶鼠標點擊一個網(wǎng)頁元素并實現(xiàn)拖拽,最后我們要實現(xiàn)移動這個元素.
獲取鼠標移動信息
第一我們需要獲取鼠標的坐標.我們加一個用戶函數(shù)到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事件會被相應的自定義函數(shù)獲?。斘覀儗ouseMove函數(shù)賦值于document.onmousemove,mouseMove會獲取鼠標移動事件.
(ev = ev || window.event) 這樣讓ev在所有瀏覽器下獲取了event事件,在Firefox下"||window.event"將不起作用,因為ev已經(jīng)有了賦值.在MSIE下ev是空的,所以ev將設置為window.event.
因為我們在這篇文章中需要多次獲取鼠標坐標,所以我們設計了mouseCoords這個函數(shù),它只包含了一個參數(shù),就是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函數(shù)就完成了,我們不再為坐標的事操心了.
捕捉鼠標點擊
下次我們將知道鼠標何時點擊與何時放開.如果我們跳過這一步,我們在做拖拽時將永遠不知道鼠標移動上面時的動作,這將是惱人的與違反直覺的.
這里有兩個函數(shù)幫助我們:onmousedown與onmouseup.我們預先設置函數(shù)來接收document.onmousemove,這樣看起來很象我們會獲取document.onmousedown與document.onmouseup.但是當我們獲取 document.onmousedown時,我們同時獲取了任何對象的點擊屬性如:text,images,tables等等.我們只想獲取那些需要拖拽的屬性,所以我們設置函數(shù)來獲取我們需要移動的對象.
移動一個元素
我們知道了怎么捕捉鼠標移動與點擊.剩下的就是移動元素了.首先,要確定一個明確的頁面位置,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;
}
}
你會注意到這個代碼幾乎是前面的全集,將前面的合在一起就實現(xiàn)了拖拽效果了.
當我們點擊一個item時,我們就獲取了很多變量,如鼠標位置,鼠標位置自然就包含了那個item的坐標信息了.如果我們點擊了一個20*20px圖像的正中間,那么鼠標的相對坐標為{x:10,y:10}.當我們點擊這個圖像的左上角那么鼠標的相對坐標為 {x:0,y:0}.當我們點擊時,我們用這個方法取得一些鼠標與圖片校對的信息.如果我們不能加載頁面item,那么信息將是document信息,會忽略了點擊的item信息.
mouseOffset函數(shù)使用了另一個函數(shù)getPosition.getPosition的作用是返回 item相對頁面左上角的坐標,如果我們嘗試獲取item.offsetLeft或者item.style.left,那么我們將取得item相對與父級的位置,不是整個document.所有的腳本我們都是相對整個document,這樣會更好一些.
為了完成getPosition任務,必須循環(huán)取得item的父級,我們將加載內容到item的左/上的位置.我們需要管理想要的top與left列表.
自從定義了mousemove這個函數(shù),mouseMove就會一直運行.第一我們確定item的 style.position為absolute,第二我們移動item到前面定義好的位置.當mouse點擊被釋放,dragObject被設置為 null,mouseMove將不在做任何事.
Dropping an Item
前面的例子目的很簡單,就是拖拽item到我們希望到的地方.我們經(jīng)常還有其他目的如刪除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的范圍內,執(zhí)行drop操作.我們檢查鼠標指針位置是否在目標范圍是用(mousePos.xtargetPos.x),而且還要符合條件(mousePos.x(targPos.x + targWidth)).如果所有的條件符合,說明指針確實在范圍內,可以執(zhí)行drop指令了.
Pulling It All Together
最后我們擁有了所有的drag/drop的腳本片斷!下一個事情是我們將創(chuàng)建一個DOM處理.
下面的代碼將創(chuàng)建container(容器),而且使任何一個需要drag/drop的item變成一個容器的item.代碼在這個文章第二個demo的后面,它可以用戶記錄一個list(列表),定為一個導航窗口在左邊或者右邊,或者更多的函數(shù)你可以想到的.
下一步我們將通過"假代碼"讓reader看到真代碼,下面為推薦:
1、當document第一次載入時,創(chuàng)建dragHelper DIV.dragHelper將給移動的item加陰影.真實的item沒有被dragged,只是用了insertBefor和appendChild來移動了,我們隱藏了dragHelper
2、有了mouseDown與mouseUp函數(shù).所有的操作會對應到當?shù)絠MouseDown的狀態(tài)中,只有當mouse左鍵為按下時iMouseDown才為真,否則為假.
3、我們創(chuàng)建了全局變量DragDrops與全局函數(shù)CreateDragContainer.DragDrops包含了一系列相對彼此的容器.任何參數(shù)(containers)將通過CreatedcragContainer進行重組與序列化,這樣可以自由的移動.CreateDragContainer函數(shù)也將item進行綁定與設置屬性.
4、現(xiàn)在我們的代碼知道每個item的加入,當我們移動處mouseMove,mouseMove函數(shù)首先會設置變量target,鼠標移動在上面的item,如果這個item在容器中(checked with getAttribute):
* 運行一小段代碼來改變目標的樣式.創(chuàng)造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就是前文所創(chuàng)建的
* 檢查每個當前容器中的container,是否鼠標已經(jīng)移動到這些范圍內了
o 我們檢查看一下正在拖動的item是屬于哪個container
o 放置item在一個container的某一個item之前,或者整個container之后
o 確認item是可見的
* 如果鼠標不在container中,確認item是不可見了.
script type="text/javascript"
var _y;
var scrolling=false;
document.onmousedown=function(e){
var e = window.event || e;
_y = e.clientY;
scrolling=true;
};
document.onmousemove = function(e){
if(!scrolling) return;
var e = window.event || e;
document.body.style.cursor="move";
var move=(e.clientY-_y)/10;
var scrollTop=document.body.scrollTop + document.documentElement.scrollTop;
window.scrollTo(0,scrollTop+move);
};
document.onmouseup=function(){
scrolling=false;
document.body.style.cursor="default";
};
/script
不足是會選中文字- -!
你的代碼沒用代碼排版太雜亂,我直接把自己寫的拖拽給你參考一下,這段代碼只是無聊時寫的,所以沒寫吸附和區(qū)域限制,你可以參考修改一下。使用方法在底部。
function?ClickMove(id){
var?_this?=?this;
this.ele?=?document.querySelector(id);
this.left?=?this.ele.offsetLeft;
this.top?=?this.ele.offsetTop;
this.ele.onmousedown?=?function(ev){
_this.mDown(ev);
}
}
ClickMove.prototype.mDown?=?function(ev){
var?_this?=?this;
if(?getComputedStyle(this.ele).position?!=?'absolute'?)?this.ele.style.position?=?'relative';
var?eleX?=?ev.clientX?-?this.ele.offsetLeft;
var?eleY?=?ev.clientY?-?this.ele.offsetTop;
document.documentElement.onmousemove?=?function(ev){
_this.ele.style.left?=?ev.clientX?-?eleX?-?_this.left?+?'px';
_this.ele.style.top?=?ev.clientY?-?eleY?-?_this.top??+?'px';
}
document.documentElement.onmouseup?=?function(){
this.onmousemove?=?null;
}
}
/*
元素你只要給一個寬高背景就好,其他的不用給都可以。
使用方法:寫ID或者class名字
class方式demo:?var?div1?=?new?ClickMove('.box1');
id方式demo:?var?div1?=?new?ClickMove('#box1');
*/
本文實例講述了JS基于面向對象實現(xiàn)的拖拽庫。分享給大家供大家參考。具體如下:
這是一個面向對象的JS拖拽庫,可設置水平鎖定、垂直鎖定、鎖定位置、鎖定范圍等,設定這些范圍后,只能在設定的模式下拖動,我覺得這是個挺不錯的拖拽實例。
運行效果截圖如下:
在線演示地址如下:
具體代碼如下:
!DOCTYPE
html
PUBLIC
"-//W3C//DTD
XHTML
1.0
Transitional//EN"
""
html
xmlns=""
head
meta
http-equiv="Content-Type"
content="text/html;
charset=utf-8"
/
title拖拽庫/title
style
type="text/css"
div,h2,p{margin:0;padding:0;}
body{font:14px/1.5
arial;}
#box{width:100px;height:100px;background:#fef4eb;padding:5px;margin:50px;border:1px
solid
#f60;}
#box
.title{height:25px;background:#f60;}
#tool{margin-bottom:10px;}
/style
script
type="text/javascript"
function
Drag()
{
//初始化
this.initialize.apply(this,
arguments)
}
Drag.prototype
=
{
//初始化
initialize
:
function
(drag,
options)
{
this.drag
=
this.$(drag);
this._x
=
this._y
=
0;
this._moveDrag
=
this.bind(this,
this.moveDrag);
this._stopDrag
=
this.bind(this,
this.stopDrag);
this.setOptions(options);
this.handle
=
this.$(this.options.handle);
this.maxContainer
=
this.$(this.options.maxContainer);
this.maxTop
=
Math.max(this.maxContainer.clientHeight,
this.maxContainer.scrollHeight)
-
this.drag.offsetHeight;
this.maxLeft
=
Math.max(this.maxContainer.clientWidth,
this.maxContainer.scrollWidth)
-
this.drag.offsetWidth;
this.limit
=
this.options.limit;
this.lockX
=
this.options.lockX;
this.lockY
=
this.options.lockY;
this.lock
=
this.options.lock;
this.onStart
=
this.options.onStart;
this.onMove
=
this.options.onMove;
this.onStop
=
this.options.onStop;
this.handle.style.cursor
=
"move";
this.changeLayout();
this.addHandler(this.handle,
"mousedown",
this.bind(this,
this.startDrag))
},
changeLayout
:
function
()
{
this.drag.style.top
=
this.drag.offsetTop
+
"px";
this.drag.style.left
=
this.drag.offsetLeft
+
"px";
this.drag.style.position
=
"absolute";
this.drag.style.margin
=
"0"
},
startDrag
:
function
(event)
{
var
event
=
event
||
window.event;
this._x
=
event.clientX
-
this.drag.offsetLeft;
this._y
=
event.clientY
-
this.drag.offsetTop;
this.addHandler(document,
"mousemove",
this._moveDrag);
this.addHandler(document,
"mouseup",
this._stopDrag);
event.preventDefault
event.preventDefault();
this.handle.setCapture
this.handle.setCapture();
this.onStart()
},
moveDrag
:
function
(event)
{
var
event
=
event
||
window.event;
var
iTop
=
event.clientY
-
this._y;
var
iLeft
=
event.clientX
-
this._x;
if
(this.lock)
return;
this.limit
(iTop
(iTop
=
0),
iLeft
(iLeft
=
0),
iTop
this.maxTop
(iTop
=
this.maxTop),
iLeft
this.maxLeft
(iLeft
=
this.maxLeft));
this.lockY
||
(this.drag.style.top
=
iTop
+
"px");
this.lockX
||
(this.drag.style.left
=
iLeft
+
"px");
event.preventDefault
event.preventDefault();
this.onMove()
},
stopDrag
:
function
()
{
this.removeHandler(document,
"mousemove",
this._moveDrag);
this.removeHandler(document,
"mouseup",
this._stopDrag);
this.handle.releaseCapture
this.handle.releaseCapture();
this.onStop()
},
//參數(shù)設置
setOptions
:
function
(options)
{
this.options
=
{
handle:
this.drag,
//事件對象
limit:
true,
//鎖定范圍
lock:
false,
//鎖定位置
lockX:
false,
//鎖定水平位置
lockY:
false,
//鎖定垂直位置
maxContainer:
document.documentElement
||
document.body,
//指定限制容器
onStart:
function
()
{},
//開始時回調函數(shù)
onMove:
function
()
{},
//拖拽時回調函數(shù)
onStop:
function
()
{}
//停止時回調函數(shù)
};
for
(var
p
in
options)
this.options[p]
=
options[p]
},
//獲取id
$
:
function
(id)
{
return
typeof
id
===
"string"
?
document.getElementById(id)
:
id
},
//添加綁定事件
addHandler
:
function
(oElement,
sEventType,
fnHandler)
{
return
oElement.addEventListener
?
oElement.addEventListener(sEventType,
fnHandler,
false)
:
oElement.attachEvent("on"
+
sEventType,
fnHandler)
},
//刪除綁定事件
removeHandler
:
function
(oElement,
sEventType,
fnHandler)
{
return
oElement.removeEventListener
?
oElement.removeEventListener(sEventType,
fnHandler,
false)
:
oElement.detachEvent("on"
+
sEventType,
fnHandler)
},
//綁定事件到對象
bind
:
function
(object,
fnHandler)
{
return
function
()
{
return
fnHandler.apply(object,
arguments)
}
}
};
//應用
window.onload
=
function
()
{
var
oBox
=
document.getElementById("box");
var
oTitle
=
oBox.getElementsByTagName("h2")[0];
var
oSpan
=
document.getElementsByTagName("span")[0];
var
oDrag
=
new
Drag(oBox,
{handle:oTitle,
limit:false});
var
aInput
=
document.getElementsByTagName("input");
//鎖定范圍接口
aInput[0].onclick
=
function
()
{
oDrag.limit
=
!oDrag.limit;
this.value
=
oDrag.limit
?
"取消鎖定范圍"
:
"鎖定范圍"
};
//水平鎖定接口
aInput[1].onclick
=
function
()
{
oDrag.lockX
=
!oDrag.lockX;
this.value
=
oDrag.lockX
?
"取消水平鎖定"
:
"水平鎖定"
};
//垂直鎖定接口
aInput[2].onclick
=
function
()
{
oDrag.lockY
=
!oDrag.lockY;
this.value
=
oDrag.lockY
?
"取消垂直鎖定"
:
"垂直鎖定"
};
//鎖定位置接口
aInput[3].onclick
=
function
()
{
oDrag.lock
=
!oDrag.lock;
this.value
=
oDrag.lock
?
"取消鎖定位置"
:
"鎖定位置"
};
//開始拖拽時方法
oDrag.onStart
=
function
()
{
oSpan.innerHTML
=
"開始拖拽"
};
//開始拖拽時方法
oDrag.onMove
=
function
()
{
oSpan.innerHTML
=
"left:"
+
this.drag.offsetLeft
+
",
top:"
+
this.drag.offsetTop
};
//開始拖拽時方法
oDrag.onStop
=
function
()
{
oSpan.innerHTML
=
"結束拖拽"
};
};
/script
/head
body
div
id="tool"
input
type="button"
value="鎖定范圍"
/
input
type="button"
value="水平鎖定"
/
input
type="button"
value="垂直鎖定"
/
input
type="button"
value="鎖定位置"
/
/div
p拖放狀態(tài):span未開始/span/p
div
id="box"
h2
class="title"/h2
/div
/body
/html
希望本文所述對大家的JavaScript程序設計有所幫助。
網(wǎng)站題目:javascript拖拽,css實現(xiàn)拖拽
本文來源:http://vcdvsql.cn/article30/dsdgiso.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護、企業(yè)網(wǎng)站制作、網(wǎng)站設計公司、小程序開發(fā)、網(wǎng)站改版、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)