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
相关文章
相关标签/搜索