拽原理
先介紹一下實現(xiàn)元素拖動需要的坐標屬性,offsetLeft、offsetTop 和 clientX、clientY。
offsetLeft 和offsetTop 用在dom節(jié)點中,可以返回當前元素距離某個父輩元素左邊緣的距離。
clientX、clientY 在事件中使用,返回當事件被觸發(fā)時鼠標指針向?qū)τ跒g覽器頁面的水平坐標。
注:操作當前元素要定義成絕對定位
//css #box{ width: 100px; height: 100px; background: red; position: absolute; } //dom元素 <div id="box"></div>
window.onload = function(){ var drag = document.getElementById('box');//選擇dom元素 drag.onmousedown = function(event){ var event = event || window.event; //兼容IE瀏覽器 // 鼠標點擊物體那一刻相對于物體左側(cè)邊框的距離=點擊時的位置相對于瀏覽器最左邊的距離-物體左邊框相對于瀏覽器最左邊的距離 var diffX = event.clientX - drag.offsetLeft; var diffY = event.clientY - drag.offsetTop; if(typeof drag.setCapture !== 'undefined'){ drag.setCapture(); } document.onmousemove = function(event){ var event = event || window.event; var moveX = event.clientX - diffX; var moveY = event.clientY - diffY; if(moveX < 0){//判斷最左右邊臨界點 moveX = 0 }else if(moveX > window.innerWidth - drag.offsetWidth){ moveX = window.innerWidth - drag.offsetWidth } if(moveY < 0){//判斷最上下邊臨界點 moveY = 0; }else if(moveY > window.innerHeight - drag.offsetHeight){ moveY = window.innerHeight - drag.offsetHeight } drag.style.left = moveX + 'px'; drag.style.top = moveY + 'px' console.log('x:'+moveX,'y:'+moveY); } document.onmouseup = function(event){ //鼠標松開 清除onmousemove、onmouseup事件 this.onmousemove = null; this.onmouseup = null; //修復(fù)低版本ie bug if(typeof drag.releaseCapture!='undefined'){ drag.releaseCapture(); } } } }
拖拽效果
本文中,我們將了解HTML拖放,并借助示例了解其實現(xiàn).
拖放是一個非常交互式和用戶友好的概念,它可以通過抓住對象更輕松地將對象移動到其他位置。這允許用戶在元素上單擊并按住鼠標按鈕,將其拖動到其他位置,然后釋放鼠標按鈕以將元素放到該位置。在HTML 5中,拖放更容易編碼,其中的任何元素都是可拖動的。
拖放事件:有各種拖放事件,其中一些在下面列出:
拖放 Drag and Drop實現(xiàn)步驟:
例1:
<!DOCTYPE HTML>
<html>
<head>
<style>
#getData {
width: 250px;
height: 200px;
padding: 10px;
border: 1px solid #4f4d4d;
}
</style>
<script>
function allowDrop(even) {
even.preventDefault();
}
function drag(even) {
even.dataTransfer.setData("text", even.target.id);
}
function drop(even) {
even.preventDefault();
var fetchData = even.dataTransfer.getData("text");
even.target.appendChild(document.getElementById(fetchData));
}
</script>
</head>
<body>
<h3>Drag the GeekforGeeks image into the rectangle:</h3>
<div id="getData"
ondrop="drop(event)"
ondragover="allowDrop(event)">
</div>
<br>
<img id="dragData"
src="gfg.png"
draggable="true"
ondragstart="drag(event)"
width="250"
height="200">
</body>
</html>
Output:
Dragging the image into the box
拖放過程的數(shù)據(jù)傳遞: 當拖放的整個過程發(fā)生時,將使用數(shù)據(jù)傳輸屬性。它用于保存從源拖放到所需位置的數(shù)據(jù)。這些是與之關(guān)聯(lián)的屬性:
例2:
<!DOCTYPE HTML>
<html>
<head>
<title>Drag and Drop box</title>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function dragStart(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function dragDrop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
<style>
#box {
margin: auto;
width: 50%;
height: 200px;
border: 3px solid green;
padding: 10px;
}
#box1,
#box2,
#box3 {
float: left;
margin: 5px;
padding: 10px;
}
#box1 {
width: 50px;
height: 50px;
background-color: #F5B5C5;
}
#box2 {
width: 100px;
height: 100px;
background-color: #B5D5F5;
}
#box3 {
width: 150px;
height: 150px;
background-color: #BEA7CC;
}
p {
font-size: 20px;
font-weight: bold;
text-align: center;
}
.gfg {
font-size: 40px;
color: #009900;
font-weight: bold;
text-align: center;
}
</style>
</head>
<body>
<div class="gfg">GeeksforGeeks</div>
<p>Drag and drop of boxes</p>
<div id="box">
<div id="box1" draggable="true"
ondragstart="dragStart(event)">
</div>
<div id="box2" draggable="true"
ondragstart="dragStart(event)">
</div>
<div id="box3" ondrop="dragDrop(event)"
ondragover="allowDrop(event)">
</div>
</div>
</body>
</html>
說明:
效果:
我們都知道普通的HTML自帶的功能相對有限,很多復(fù)雜的交互式場景,如果手動去寫功能的話會非常的復(fù)雜,而且可擴展性差,就拿HTML表格來說,對于初學(xué)者或者對于復(fù)雜的拖拽式交互編程不熟悉的話會很浪費時間,因此今天就介紹一個第三方的插件——Table-draagger,來輕松實現(xiàn)類似的功能。Table-draagger是用于構(gòu)建可重排序的拖放表的極簡主義純Javascript庫!
https://github.com/sindu12jun/table-dragger
Table-draagger因為其以下幾個特征而讓拖拽和排序的實現(xiàn)變得如此簡單:
可以在npm上獲得它:
npm install table-dragger --save
或者引用壓縮的js文件
<script src="../node_modules/table-dragger/dist/table-dragger.min.js"></script>
或者嘗試開發(fā)中的不穩(wěn)定版本
npm install table-dragger@next --save
請看以下代碼:
import tableDragger from 'table-dragger' tableDragger(el, options?)
<table id="table"> <thead> <tr> <th class='handle'>header1</th> <th class='handle'>header2</th> </tr> </thead> <tbody> <tr> <td>conten1</td> <td>conten2</td> </tr> </tbody> </table>
var el = document.getElementById('table'); var dragger = tableDragger(el, { mode: 'row', dragHandler: '.handle', onlyBody: true, }); dragger.on('drop',function(from, to){ console(from); console(to); });
你可以在不設(shè)置任何參數(shù)的情況下使用默認的拖拽和排序方式,當然以下是你可以配置的選項:
1、將mode設(shè)置為column,用戶拖動和排序表的列
2、將mode設(shè)置為row,用戶拖動并排序表的行
3、設(shè)置mode為free,用戶根據(jù)點擊后鼠標移動的方向拖動行或列。注意,必須在自由模式下指定dragHandler。
dragHandler是表中的拖動句柄選擇器默認情況下,在列模式下,dragHandler是表的第一行;在行模式下,則是第一列。
在行模式下將onlyBody設(shè)置為true時,用戶只能在tbody中提升行。
下面是返回對象的API
tableDragger(document.querySelector('#event-table'), { mode: 'free', dragHandler: '.handle', onlyBody: true }) .on('drag', () => { console.log('drag'); }) .on('drop', (from, to, el, mode) => { console.log(`drop ${el.nodeName} from ${from} ${mode} to ${to} ${mode}`); }) .on('shadowMove', (from, to, el, mode) => { console.log(`move ${el.nodeName} from ${from} ${mode} to ${to} ${mode}`); }) .on('out', (el, mode) => { console.log(`move out or drop ${el.nodeName} in mode ${mode}`); });
Table-draagger為我們節(jié)省了很多手動封裝表格排序和拖拽功能的時間,當然目前很多第三方框架已經(jīng)實現(xiàn)了類似的功能,這更適用于原生的html表格,你還可以通過一些手段記憶用戶拖拽,這只是其中一種思路,Enjoy it!~
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。