2020-11-29

HTML5拖拽事件

1. h5拖拽和js拖拽

  • JS里拖拽三事件:mousedown、mousemove、mouseup
    实现交互性效果,根据鼠标的移动的位置让元素联动

    dv.addEventListener('mousedown', function (e) {
        let x = e.clientX - this.offsetLeft
        let y = e.clientY - this.offsetTop
    
        function handleMove(ev) {
            dv.style.cssText = `left: ${ev.clientX - x}px; top: ${
                ev.clientY - y
            }px;`
        }
        function handleUp(ev) {
            this.removeEventListener('mousemove', handleMove)
            this.removeEventListener('mouseup', handleUp)
        }
        document.addEventListener('mousemove', handleMove)
    
        document.addEventListener('mouseup', handleUp)
    })
    
  • H5拖拽也可以实现,而且更简单,实际例子:百度图片识别、qq邮箱文件提交、百度网盘文件上传,并且能获取到文件的名称、大小、修改事件

    dv.addEventListener('dragstart', function (e) {
        let x = e.clientX - this.offsetLeft
        let y = e.clientY - this.offsetTop
    
        this.addEventListener('dragend', function (ev) {
            this.style.cssText = `left: ${ev.clientX - x}px; top: ${
                ev.clientY - y
            }px;`
        })
    })
    

2. 拖拽七事件

  • 除图片外的标签元素默认是不可以拖拽的,加上draggable="true"才能被拖拽
  • 拖拽七事件
    • dragstart 拖拽开始,拖拽前触发 ,事件只触发一次
    • drag 拖拽中,拖拽前、拖拽结束之间,连续触发
    • dragend 拖拽结束,拖拽结束触发 ,事件只触发一次
    • dragenter 拖拽进入目标触发
    • dragover 在目标元素上,进入目标、离开目标之间,连续触发
    • dragleave 离开目标元素触发
    • drop 在目标元素释放鼠标触发
2.1. 拖拽元素(被拖拽元素对象)事件 :
const box = document.getElementById('box');

// dragstart 拖拽开始时触发,只触发一次
box.ondragstart = function () {
    this.style.background = 'blue';

}

// drag拖拽触发的事件,连续触发,只要鼠标不松开会一直触发
box.ondrag = function () {
    this.style.background = 'yellow';
}

// dragend 拖拽结束时,触发的事件,只要鼠标一松开就触发
box.ondragend = function () {
    this.style.background = 'skyblue';
}
2.2. 目标元素(拖拽元素被拖到的对象)事件 :
// dragenter 拖拽元素移入目标元素时触发,鼠标进入才算哦
wrap.ondragenter = function () {
    this.innerHTML = '释放鼠标';
}

// dragove  拖拽的元素在目标元素中触发,会连续触发
wrap.ondragover = function (e) {
    this.style.background = '#999';
    console.log(num++);
    // e.preventDefault();
    return false;
}

// dragleave  拖拽的元素离开目标元素时触发,鼠标离开才算
wrap.ondragleave = function () {
    this.innerHTML = '请将元素拖进来';
}

// drop  在目标元素中松口鼠标触发,如果要触发这个事件,必须先将drapover事件取消默认事件
wrap.ondrop = function () {
    this.style.background = 'skyblue';
    console.log('你在目标元素中松口了鼠标');
    document.body.removeChild(box);
}

回收站拖拽删除

Vue-Layout可视化布局

2. 拖拽兼容问题

只作为了解, 因为现在火狐已经没有兼容问题

火狐浏览器下需设置dataTransfer对象才可以拖拽除图片外的其他标签

火狐在没有添加dataTransfer前不能使用ondrag和ondragend事件,其他都可以

2.1. dataTransfer对象

dataTransfer 是 拖拽事件对象的属性

  1. setData() : 设置数据 key和value(必须是字符串)

  2. getData() : 获取数据,根据key值,获取对应的value

    let right = document.querySelector('#right');
    let lis = right.querySelectorAll('li');
    console.log(lis);
    lis.forEach(function (li, index) {
        li.setAttribute('draggable', true);
    li.addEventListener('dragstart', function (e) {
            // 设置携带数据
            e.dataTransfer.setData('foo', index);
        });
    });
    
    let left = document.querySelector('#left');
    left.addEventListener(
        'dragover',
        function (e) {
            e.preventDefault();
        },
        { passive: false }
    );
    
    left.addEventListener('drop', function (e) {
        const index = e.dataTransfer.getData('foo');
        right.removeChild(lis[index]);
    });
    
  3. setDragImage :三个参数(指定的元素,坐标X,坐标Y)

    box.ondragstart = function (e) {
        console.log(e.dataTransfer);
        e.dataTransfer.setDragImage(img, 100, 100);
    }
    
  4. files: 获 取外部拖拽的文件,返回一个filesList列表
    filesList下有个type属性,返回文件的类型

    wrap.ondrop = function (e) {
        const dt = e.dataTransfer;
        console.log(dt.files)
        console.log(
            dt.files[0].name,
            dt.files[0].type,
            dt.files[0].lastModified,
            dt.files[0].lastModifiedDate.toLocaleDateString(),
            dt.files[0].lastModifiedDate.toLocaleTimeString(),
            dt.files[0].lastModifiedDate.toDateString(),
    	);
        return false;
    }
    

3. 读取读取文件信息

3.1Blob读取文件对象

Blob对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或者二进制格式进行读取。

  • Blob,Binary Large Object 的缩写,代表二进制类型的大对象,提供了一系列接口
  • MySQL中也有Blob类型,表示的是二进制数据容器
  • File类型的接口基于Blob类型
  • 构造函数Blob(array[, options])

URL对象

URL.createObjectURL()返回指定对象的URL,该URL的生命周期与创建它的窗口对象document绑定。该URL对象表示指定的File或者Blob对象

const oFile = e.dataTransfer.files.item(0); // 拿到第一个文件

if (/image/.test(oFile.type)) { // 判断文件类型
    let url = window.URL.createObjectURL(oFile); // 可以传入 File类型 或者 Blob类型
    console.log(url)
    let img = new Image();
    img.width = 100;
    img.src = url;
    img.onload = function () {
        box.appendChild(this);
    };
}
3.2 FileReader(读取文件信息)

FileReader类型实现了一种异步文件读取机制。可以把FileReader想象成XMLHttpRequest,区别在于,它只读取文件系统,而不是远程服务器。

  • 方法:
    • readAsText(file, encoding):以纯文本形式读取文件,将读取到的文本保存在result属性中
    • readAsDataURL(file):读取文件并将文件以URI的形式保存在result属性中
    • readAsBinaryString(file):读取文件并将一个字符串保存在result属性
    • readAsArrayBuffer(file):读取文件,并将一个包含文件内容的ArrayBuffer保存在result属性
  • 事件:
    • progress 每 50ms触发一次
    • error 读取出错时触发
    • load 成功加载后触发
wrap.ondrop = function (e) {
    const dt = e.dataTransfer;
    const oFile = dt.files.item(0);

    // 创建读取文件对象
    const file = new FileReader();

    // 获取文件的url
    file.readAsDataURL(oFile)
    
	// 当信息读取完成后执行
    file.onload = function () {
        // console.log(oFile);
        if (oFile.type.includes('image')) {
            const img = new Image();
            img.src = file.result;
            wrap.appendChild(img)
        }

    }
    return false;
}

性能低,没有必要吧这些字符串渲染到页面中

3.2 异步文件上传

FormData对象

FormData提供了一种表示表单数据的键值对构造方式,可以轻松将数据通过XMLHttpRequest.send()方法发送出去。

  • 方法
    • append(name, value) 向FormData中添加新的属性值,FormData中对应的属性值存在也不会覆盖原来的值,而是新增一个值,如果属性不存在则新增一项属性值
    • delete(name)从FromData中删除一个键值对
    • get(name)获取指定键的第一个值,想要获取全部值可以用 getAll(name)
    • set(name, value)与append区别在于,会覆盖
const xhr = new XMLHttpRequest();
xhr.onload = function () {
    console.log('aaa')
    console.log(xhr.responseText);
};

xhr.open(
    'post',
    'http://www.tanzhouweb.com/h5upload/upload.php',
    true
);
// 通过表单对象 携带数据
const fd = new FormData();
fd.append('file', file);
xhr.send(fd);
}
上一篇:HTML5 拖放(Drag 和 Drop)


下一篇:JVM虚拟机