整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          javascript 拖拽效果實現(xiàn)

          拽原理

          先介紹一下實現(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中,拖放更容易編碼,其中的任何元素都是可拖動的。

          拖放事件:有各種拖放事件,其中一些在下面列出:

          • ondrag: 它用于在 HTML 中拖動元素或文本選擇時使用。
          • ondragstart: 它用于調(diào)用一個函數(shù) drag(event),該函數(shù)指定要拖動的數(shù)據(jù)。
          • ondragenter: 它用于確定丟棄目標是否接受丟棄。如果要接受丟棄,則必須取消此事件。
          • ondragleave:當鼠標在拖動發(fā)生時將元素留在有效放置目標之前時,就會發(fā)生這種情況。
          • ondragover: 它指定可以放置拖動數(shù)據(jù)的位置。
          • ondrop:它指定在拖動操作結(jié)束時發(fā)生丟棄的位置。
          • ondragend: 當用戶完成拖動元素時,就會發(fā)生這種情況。

          拖放 Drag and Drop實現(xiàn)步驟:

          • 步驟1:使對象可拖動 首先將可拖動屬性設(shè)置為 true,以使該元素可拖動 <img draggable = “true”>然后,指定拖動元素時應(yīng)發(fā)生的情況。ondragstart 屬性調(diào)用一個函數(shù) drag(event),該函數(shù)指定要拖動的數(shù)據(jù)。dataTransfer.setData() 方法設(shè)置數(shù)據(jù)類型和拖動數(shù)據(jù)的值事件偵聽器 ondragstart 將設(shè)置允許的效果(復(fù)制、移動、鏈接或某種組合).
          • 步驟2: 放下對象 ondragover 事件指定可以放下拖動數(shù)據(jù)的位置。默認情況下,不能將數(shù)據(jù)/元素放在其他元素中。若要允許刪除,它必須阻止元素的默認處理。這是通過調(diào)用 event.preventDefault() 方法最后,drop 事件來完成的,它允許執(zhí)行實際的丟棄

          例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)的屬性:

          • dataTransfer.setData(format, data): 它用于設(shè)置要拖動的數(shù)據(jù).
          • dataTransfer.clearData(format): 它用于調(diào)用此函數(shù),沒有清除所有數(shù)據(jù)的參數(shù)。使用 format 參數(shù)調(diào)用它僅刪除該特定數(shù)據(jù)。
          • dataTransfer.getData(format): 它返回指定格式的數(shù)據(jù)。如果沒有此類數(shù)據(jù),則返回空字符串.
          • dataTransfer.types:此屬性返回在 dragstart 事件中設(shè)置的所有格式的數(shù)組。
          • dataTransfer.files: 它用于返回要刪除的所有文件。
          • dataTransfer.setDragImage(element, x, y): 它用于將現(xiàn)有圖像顯示為拖動圖像,而不是光標旁邊的默認圖像。坐標指定放置位置。
          • dataTransfer.addElement(element): 它用于添加要繪制的指定元素作為拖動反饋圖像。
          • dataTransfer.effectAllowed(value): 它將告訴瀏覽器只允許用戶使用列出的操作類型。該屬性可以設(shè)置為以下值:none、copy、copyLink、copyMove、link、linkMove、move、all 和未初始化。
          • dataTransfer.dropEffect(value): 它用于控制在拖動和拖動事件期間向用戶提供的反饋。當用戶將鼠標懸停在目標元素上時,瀏覽器的光標將指示將要發(fā)生的操作類型(例如復(fù)制、移動等)。效果可以采用以下值之一:無、復(fù)制、鏈接、移動。

          例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>
          


          說明:

          • 通過將要拖動的元素的可拖動屬性draggable設(shè)置為 true 來開始拖動。
          • 使用 dataTransfer.getData() 方法獲取拖動的數(shù)據(jù)。此方法將返回在 setData() 方法中設(shè)置為相同類型的任何數(shù)據(jù)。
          • 調(diào)用 event.preventDefault() 方法,通過阻止元素的默認處理來允許刪除其他元素中的元素。
          • 該元素存儲在我們附加到放置元素中的變量數(shù)據(jù)中。

          效果:

          我們都知道普通的HTML自帶的功能相對有限,很多復(fù)雜的交互式場景,如果手動去寫功能的話會非常的復(fù)雜,而且可擴展性差,就拿HTML表格來說,對于初學(xué)者或者對于復(fù)雜的拖拽式交互編程不熟悉的話會很浪費時間,因此今天就介紹一個第三方的插件——Table-draagger,來輕松實現(xiàn)類似的功能。Table-draagger是用于構(gòu)建可重排序的拖放表的極簡主義純Javascript庫!



          Github

          https://github.com/sindu12jun/table-dragger


          特征

          Table-draagger因為其以下幾個特征而讓拖拽和排序的實現(xiàn)變得如此簡單:

          • 非常容易配置
          • 能夠同時對列或行進行排序
          • 排序時動畫流暢
          • 沒有臃腫的依賴
          • 提供觸摸事件(意味著在觸摸設(shè)備可以實現(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ù)的情況下使用默認的拖拽和排序方式,當然以下是你可以配置的選項:

          • options.mode

          1、將mode設(shè)置為column,用戶拖動和排序表的列

          2、將mode設(shè)置為row,用戶拖動并排序表的行

          3、設(shè)置mode為free,用戶根據(jù)點擊后鼠標移動的方向拖動行或列。注意,必須在自由模式下指定dragHandler。

          • options.dragHandler

          dragHandler是表中的拖動句柄選擇器默認情況下,在列模式下,dragHandler是表的第一行;在行模式下,則是第一列。

          • options.onlyBody

          在行模式下將onlyBody設(shè)置為true時,用戶只能在tbody中提升行。

          • API

          下面是返回對象的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}`);
          });
          


          總結(jié)

          Table-draagger為我們節(jié)省了很多手動封裝表格排序和拖拽功能的時間,當然目前很多第三方框架已經(jīng)實現(xiàn)了類似的功能,這更適用于原生的html表格,你還可以通過一些手段記憶用戶拖拽,這只是其中一種思路,Enjoy it!~


          主站蜘蛛池模板: 日韩电影一区二区三区| 一区二区亚洲精品精华液| 亚洲一区二区三区免费视频| 国产主播一区二区三区| 色欲AV蜜臀一区二区三区| A国产一区二区免费入口 | 视频一区二区在线播放| 欧美日韩综合一区二区三区| 日韩国产精品无码一区二区三区| 亚洲一区无码精品色| 视频在线一区二区| 精品一区二区三区在线视频观看| 亚洲A∨精品一区二区三区下载| 亚洲一区二区三区播放在线 | 亚洲中文字幕久久久一区| 亚洲一区综合在线播放| 文中字幕一区二区三区视频播放| 亚洲乱色熟女一区二区三区丝袜| 精品久久久久一区二区三区| 国产精品免费大片一区二区| AV怡红院一区二区三区| 国精产品一区一区三区免费视频 | 91精品一区二区三区在线观看| 久久精品一区二区免费看| 久久精品国产一区| 亚洲一区免费在线观看| 国产大秀视频在线一区二区| 日本一区二区视频| 日韩在线一区视频| 亚洲一区二区三区免费| 波多野结衣高清一区二区三区| 久久久91精品国产一区二区| 69福利视频一区二区| 国产精品无码一区二区在线| 日韩精品一区二区三区视频| 国产一区二区三区免费观看在线| 无码国产精品一区二区免费16| 亚洲美女视频一区| 国产人妖视频一区二区破除| 97久久精品午夜一区二区| 久久久老熟女一区二区三区|