zoukankan      html  css  js  c++  java
  • 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、事件:

    EventOn Event HandlerDescription
    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="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
  • 相关阅读:
    ComponentOne Studio Enterprise ———C1控件barchat 的统计图格式 设置
    OpenStack开发学习笔记04————
    短信推送API接口实现---------阿里大于
    OpenStack开发学习笔记03————创建一个openstack
    OpenStack开发学习笔记02————环境的安装和部署
    OpenStack开发学习笔记01
    MVC模式在Java Web应用程序中的实例分析
    javascript的setTimeout以及setInterval休眠问题。
    BFC 神奇背后的原理
    jquery checkBox的问题
  • 原文地址:https://www.cnblogs.com/lichihua/p/11113081.html
Copyright © 2011-2022 走看看