html元素拖拽


二、基於HTML5拖拽API的拖拽
前序知識介紹
  一個典型的拖拽操作是這樣的:用戶用鼠標選中一個可拖動的(draggable)元素,移動鼠標到一個可放置的(droppable)元素,然后釋放鼠標。 在操作期間,會觸發一些事件類型,有一些事件類型可能會被多次觸發(比如drag 和 dragover 事件類型)。

一個完整的drag and drop流程通常包含以下幾個步驟:

  1. 設置可拖拽目標.設置屬性draggable="true"實現元素的可拖拽.
  2. 監聽dragstart設置拖拽數據
  3. 為拖拽操作設置反饋圖標(可選)
  4. 設置允許的拖放效果,如copy,move,link
  5. 設置拖放目標,默認情況下瀏覽器阻止所有的拖放操作,所以需要監聽dragenter或者dragover取消瀏覽器默認行為使元素可拖放.
  6. 監聽drop事件執行所需操作

  

這里涉及幾個知識點:

1、可拖動元素:又稱為源對象,是指我們鼠標點擊之后准備拖動的對象(圖片、div、文字等)
2、可放置元素:又稱為目標對象,是指可以放置源對象的區域

3、事件:

Event On Event Handler Description
drag ondrag 當拖動元素或選中的文本時觸發
dragend ondragend 當拖拽操作結束時觸發 (比如松開鼠標按鍵或敲“Esc”鍵)
dragenter ondragenter 當拖動元素或選中的文本到一個可釋放目標時觸發
dragexit ondragexit 當元素變得不再是拖動操作的選中目標時觸發
dragleave ondragleave 當拖動元素或選中的文本離開一個可釋放目標時觸發
dragover ondragover 當元素或選中的文本被拖到一個可釋放目標上時觸發
dragstart ondragstart 當用戶開始拖動一個元素或選中的文本時觸發
drop ondrop 當元素或選中的文本在可釋放目標上被釋放時觸發

                 ps:當從操作系統向瀏覽器中拖動文件時,不會觸發dragstart 和dragend 事件

4、接口:

HTML5為所有的拖動相關事件提供了一個新的屬性:

event.DataTransfer對象

屬性和方法

描述

dropEffect 拖拽交互類型,通常決定瀏覽器如何顯示鼠標光標並控制拖放操作.常見的取值有copy,move,linknone
effectAllowed 指定允許的交互類型,可以取值:copy,move,link,copyLink,copyMove,limkMoveallnone默認為uninitialized(允許所有操作)
files 包含File對象的FileList對象.從操作系統向瀏覽器拖放文件時有用.
types 保存DataTransfer對象中設置的所有數據類型.
setData(format, data) 以鍵值對設置數據,format通常為數據格式,如text,text/html
getData(format) 獲取設置的對應格式數據,format與setData()中一致
clearData(format) 清除指定格式的數據
setDragImage(imgElement, x, y) 設置自定義圖標

 

源對象和目標對象的事件間傳遞數據

event.dataTransfer {}//數據傳遞對象

源對象上的事件處理中保存數據:

event.dataTransfer.setData(key,value);//key,value必須都是字符串類型
如:
event.dataTransfer.setData("text/plain", "This is text to drag");

更多的數據類型參考

目標對象上的事件處理中讀取數據:

var value2 = event.dataTransfer.getData(key);

兼容性

demo

<div id="demo1">
  <ul class="panel-list">
    <li class="panel-item"></li>
    <li class="panel-item"></li>
    <li class="panel-item"></li>
    <li class="panel-item"></li>
    <li class="panel-item"></li>
  </ul>
  <h2>拖拽下面的方塊到上面任意容器中</h2>

  <!-- 設置draggable使元素成為可拖拽元素 -->
  <div class="movable" id="demo1-src" draggable="true" draggable="true">
      <img style="width:100%;" src="__ADMIN__/img/pbl/11.jpg">
  </div>

  <style>
    #demo1 {
      margin: 20px;
    }
    #demo1 .panel-list {
      overflow: hidden;
      list-style: none;
      margin: 0;
      padding: 0;
    }
    #demo1 .panel-item {
      float: left;
      margin-right: 30px;
      width: 100px;
      height: 100px;
      background: #ddd;
      border: 1px solid #ddd;
    }
    #demo1-src {
      display: inline-block;
      width: 50px;
      height: 50px;
      background: purple;
    }
    #demo1 .over {
      border: 1px dashed #000;
      -webkit-transform: scale(0.8, 0.8);
    }
  </style>
  <script>
  (function () {

    var dnd = {
      // 初始化
      init: function () {
        var me = this;
        me.src = document.querySelector('#demo1-src');//獲取指定css選擇器的元素
        me.panelList = document.querySelector('.panel-list');//獲取指定css選擇器的元素
        console.log( me.panelList );
        //addEventListener('要監聽的事件名','事件觸發的函數',布爾:指定事件是否在捕獲或冒泡階段執行)
        // 為拖拽源監聽dragstart,設置關聯數據
        me.src.addEventListener('dragstart', me.onDragStart, false);

        // 拖拽鼠標移入元素,在拖放目標上設置視覺反饋
        me.panelList.addEventListener('dragenter', me.onDragEnter, false);

        // 取消元素dragover默認行為,使其可拖放
        me.panelList.addEventListener('dragover', me.onDragOver, false);

        // 拖拽移出元素,清除視覺反饋
        me.panelList.addEventListener('dragleave', me.onDragLeave, false);

        // 鼠標釋放,在拖放目標上接收數據並處理
        me.panelList.addEventListener('drop', me.onDrop, false);
      },
      onDragStart: function (e) {
        //setData(format, data) 以鍵值對設置數據,format通常為數據格式,如text,text/html   
        //設置可拖動元素的id(存起來)
        e.dataTransfer.setData('text/plain', 'demo1-src');
       e.target.style.height="100px";
       e.target.style.cursor="move";
      },
      //當拖動元素或選中的文本到一個可釋放目標時觸發
      onDragEnter: function (e) {
        console.log(e.target);
        //e.target : <ul class="panel-list"></ul>
        //panel-list元素的子元素的類名列表中包含panel-item類則添加over類(呈現虛框效果)
        if (e.target.classList.contains('panel-item')) {
          //為panel-item的元素添加over類
          e.target.classList.add('over');
        }
      },
      //當拖動元素或選中的文本離開一個可釋放目標時觸發(移除over類)
      onDragLeave: function (e) {
        e.target.style.cursor="move";
        if (e.target.classList.contains('panel-item')) {
          e.target.classList.remove('over');
        }
      },
      //當元素或選中的文本被拖到一個可釋放目標上時觸發(取消事件的默認動作比如說表單自動提交)
      onDragOver: function (e) {
        e.preventDefault();
      },
      //當元素或選中的文本在可釋放目標上被釋放時觸發
      onDrop: function (e) {
        var id = e.dataTransfer.getData('text/plain');
        var src = document.getElementById(id);
        var target = e.target;
        if (target.classList.contains('panel-item')) {
          target.appendChild(src);
          target.classList.remove('over');
        }
      }

    };

    dnd.init();
  }());
  </script>
</div>


<div id="demo2">
  <h3>從文件夾中拖拽圖片到下面的區域進行預覽</h3>
  <ul class="preview"></ul>
  <style>
  #demo2 {
    margin: 20px;
  }
  #demo2 .preview {
    height: 300px;
    background: #ddd;
  }
  #demo2 li {
    float: left;
    margin-left: 40px;
  }
  #demo2 img {
    max-height: 150px;
    width: auto;
  }
  </style>

  <script>
  (function (w) {
    var doc = w.document;

    var dnd = {
      init: function () {
        var me = this;
        var preview = doc.querySelector('#demo2 .preview');

        preview.addEventListener('dragover', function (e) {
          e.preventDefault();
        }, false);

        preview.addEventListener('drop', function (e) {
          // 操作系統拖放文件到瀏覽器需要取消默認行為
          e.preventDefault();

          [].forEach.call(e.dataTransfer.files, function (file) {
            if (file && file.type.match('image.*')) {
              var reader = new FileReader();

              reader.onload = function (e) {
                var img = doc.createElement('img');
                img.src = e.target.result;
                var li = doc.createElement('li');
                li.appendChild(img);
                preview.appendChild(li);
              };

              reader.readAsDataURL(file);
            }
          });
        }, false);
      }

    };

    dnd.init();
  }(window));
  </script>
</div> <!-- demo2 -->
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM