html元素拖拽

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

一個完整的drag and drop流程一般包含如下幾個步驟:html

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

  

這裏涉及幾個知識點:web

一、可拖動元素:又稱爲源對象,是指咱們鼠標點擊以後準備拖動的對象(圖片、div、文字等)
二、可放置元素:又稱爲目標對象,是指能夠放置源對象的區域瀏覽器

三、事件:app

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 事件ide

四、接口:函數

HTML5爲全部的拖動相關事件提供了一個新的屬性:this

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) 設置自定義圖標

 

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

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
相關文章
相關標籤/搜索