html5列表与布局

HTML5逐步分析实现拖放功能的方法

一、什么是拖放

拖放就是通过鼠标放在一个物体上,按住鼠标不放就可以把一个物体托动到另一个位置。其实我们平时一直都有接触,如图

html5列表与布局(HTML5逐步分析实现拖放功能的方法)

那么在网页上其实也可以实现同样效果的拖放功能,如图

html5列表与布局(HTML5逐步分析实现拖放功能的方法)

那么,就让我们来看看如何实现的吧

二、拖放事件

在IE4的时候,Js就可以实现拖放功能了,当时只支持拖放图像和一些文本。后来随着IE版本的更新,拖放事件也在慢慢完善,HTML5就以IE的拖放功能制定了该规范,Firefox 3.5、Safari 3+、chrome以及它们之后的版本都支持了该功能。

默认情况下,网页中的图像、链接和文本是可以拖动的,而其余的元素若想要被拖动,必须将 draggable 属性设置为 true,这是HTML5规定的新属性,用于设置元素是否能被拖动。因此,图像、链接、文本的 draggable 属性默认为 true,其余元素的 draggable 属性默认为 false

在实现拖放功能时有这样两个概念,分别是被拖动元素目标元素,它们都有各自支持的事件,那么我们来了解一下

(1)被拖动元素的事件

被拖动元素所支持的事件如下表所示 

事件 含义
dragstart 准备拖动被拖动元素时触发
drag 拖动的过程中触发(频繁触发)
dragend 拖动结束时触发

我们来用一个例子测试一下这三个事件

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            .box{
                width: 100px;
                height: 100px;
                background-color: lightgreen;
            }
        </style>
    </head>
    <body>
        <li  draggable='true'></li>
        <script>
            let box = document.querySelector('.box')
            // 绑定dragstart事件
            box.addEventListener('dragstart', function() {
                console.log('拖拽开始了');
            })
            // 绑定drag事件
            box.addEventListener('drag', function() {
                console.log('元素被拖动');
            })
            // 绑定dragend事件
            box.addEventListener('dragend', function() {
                console.log('拖拽结束');
            })
        </script>
    </body>
    </html>
    
  • 我们来看看测试效果

    html5列表与布局(HTML5逐步分析实现拖放功能的方法)

    (2)目标元素的事件

    在实现拖放功能的过程中,目标元素上的事件有如下三个

     

    事件 含义
    dragenter 被拖放元素进入目标元素时触发
    dragover 被拖放元素在目标元素内时触发(频繁触发)
    dragleave 被拖动元素离开目标元素时触发
    drop 当被拖动元素被放到了目标元素中时触发

    这里我要详细讲解一下这三个事件的触发规则:

    同样的,我们来用具体的例子,先来体会一下前三个事件

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            .box{
                width: 100px;
                height: 100px;
                background-color: lightgreen;
            }
            .location{
                width: 100px;
                height: 100px;
                background-color: lightpink;
            }
        </style>
    </head>
    <body>
        <li  draggable='true'></li>
        <li ></li>
        <script>
            let located = document.querySelector('.location')
            // 绑定dragenter事件
            located.addEventListener('dragenter', function() {
                console.log('元素进入了目标元素');
            })
            // 绑定dragover事件
            located.addEventListener('dragover', function() {
                console.log('元素在目标元素内');
            })
            // 绑定dragleave事件
            located.addEventListener('dragleave', function() {
                console.log('元素离开了目标元素');
            })
        </script>
    </body>
    </html>
    
  • 我们来看看测试效果,这里你们要仔细看被拖放元素多少面积进入或离开目标元素时才触发的对应事件

    html5列表与布局(HTML5逐步分析实现拖放功能的方法)

    那么最后我们再来将一下如何才能触发 drop事件,只需要阻止 dragenter事件dragover事件 的默认行为即可。

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            .box{
                width: 100px;
                height: 100px;
                background-color: lightgreen;
            }
            .location{
                width: 100px;
                height: 100px;
                background-color: lightpink;
            }
        </style>
    </head>
    <body>
        <li  draggable='true'></li>
        <li ></li>
        <script>
            let located = document.querySelector('.location')
            located.addEventListener('dragenter', function(e) {
                e.preventDefault()
            })
            located.addEventListener('dragover', function(e) {
                e.preventDefault()
            })
            located.addEventListener('drop', function() {
                console.log('元素被放置');
            })
        </script>
    </body>
    </html>
    
  • 来看下测试效果图

    html5列表与布局(HTML5逐步分析实现拖放功能的方法)

    值得注意的是,在我们没有对 drop事件 做处理之前,将被拖放元素拖动到目标元素中时,鼠标样式会变成禁止的样式,如图

    html5列表与布局(HTML5逐步分析实现拖放功能的方法)

    而当我们设置元素为可放置了以后,鼠标样式是这样的。如图

    html5列表与布局(HTML5逐步分析实现拖放功能的方法)

    三、dataTransfer对象

    上面只是简简单单地实现了拖放功能,但并没用利用该功能做出什么实际性的功能,这里我们介绍一个拖放事件中事件对象上的一个特别重要的属性——dataTransfer

    我们通过 event.dataTransfer 来获取该对象,其主要的作用就是从被拖放元素向目标元素传递一个字符串数据

    (1)方法

    dataTransfer上有两个方法,如下表所示

     

    方法 含义
    setData 设置字符串,并设置数据类型
    getData 获取对应数据类型的字符串

    setData() 方法接收两个参数,第一个参数表示的是字符串的数据类型,HTML5规定了两种数据类型,分别是 text/plaintext/uri-list,前者表示普通字符串,后者表示URL字符串;第二个参数 就是用于存放的字符串

    getData() 方法只接收一个参数,即需要接收的字符串类型

    我们来简单使用一下这两个方法

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            .box{
                width: 100px;
                height: 100px;
                background-color: lightgreen;
            }
            .location{
                width: 100px;
                height: 100px;
                background-color: lightpink;
            }
        </style>
    </head>
    <body>
        <li  draggable='true'></li>
        <li ></li>
        <script>
    		let box = document.querySelector('.box')
    		// 为被拖放元素绑定 dragstart 事件
            box.addEventListener('dragstart', function(e) {
            	// 设置类型为 text/plain 的 字符串
                e.dataTransfer.setData('text/plain', '我是拖放开始时被设置的字符串')
            })
    
            let located = document.querySelector('.location')
            
            located.addEventListener('dragenter', function(e) {
                e.preventDefault()
            })
            located.addEventListener('dragover', function(e) {
                e.preventDefault()
            })
            located.addEventListener('drop', function(e) {
            	// 将被拖放元素放置到目标元素时获取字符串
                let res = e.dataTransfer.getData('text/plain')
                console.log(res);
            })
        </script>
    </body>
    </html>
    
  • 来看下测试结果

    html5列表与布局(HTML5逐步分析实现拖放功能的方法)

    (2)属性

    dataTransfer对象 上还有两个比较常用的属性,如下表所示

     

    属性 含义
    dropEffect 被拖放元素的放置行为
    effectAllowed 目标元素支持的放置行为

    首先说一下,这个两个属性需要搭配使用,它们决定了被拖放元素目标元素 之间的关系的,当设定好两者的关系后,在进行拖动操作的时候,鼠标会根据不同的关系显示不同的样式,除此之外,没有别的特别的作用。

    dropEffect 可以设置以下几个属性

     

    含义
    none 默认值。不能把拖动的元素放在这里
    move 应该把拖动的元素移动到该目标元素
    copy 应该把拖动元素复制到该目标元素
    link 表示目标元素会打开被拖放进来的元素对应的链接

    【注意】:dropEffect 属性必须在 dragenter事件 中设置,否则无效

    effectAllowed 可以设置以下几个属性

    含义
    uninitialized 被拖放元素没有设置放置性为
    none 被拖放元素不能有放置性为
    copy 只允许值为 ‘copy’ 的 dropEffect 目标元素
    link 只允许值为 ‘link’ 的 dropEffect 目标元素
    move 只允许值为 ‘move’ 的 dropEffect 目标元素
    copyLink 只允许值为 ‘copy’ 和 ‘link’ 的 dropEffect 目标元素
    copymove 只允许值为 ‘copy’ 和 ‘move’ 的 dropEffect 目标元素
    linkMove 只允许值为 ‘link’ 和 ‘move’ 的 dropEffect 目标元素
    all 只允许任意值的 dropEffect 目标元素

    【注意】:effectAllowed 属性必须在 dragstart事件 中设置,否则无效

    上面也说了,这两个属性基本上只是用来改变鼠标样式的,所以如果想实现特定的功能还得我们自己来重写事件的处理函数。

    下面来看一个拖放实例:

    需求: 将一段文本拖放到一个元素中

    因为文本是默认支持的拖放元素,所以我们可以不对其做任何的事件绑定。

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            .location{
                width: 100px;
                height: 100px;
                border: 1px solid black;
            }
        </style>
    </head>
    <body>
        <li class="box">我是一段测试文字</li>
        <li class="location"></li>
        <script>    
            let located = document.querySelector('.location')
    
            located.addEventListener('dragenter', function(e) {
                e.dataTransfer.dropEffect = 'copy'
                e.preventDefault()
            })
            located.addEventListener('dragover', function(e) {
                e.preventDefault()
            })
            located.addEventListener('drop', function(e) {
                e.target.innerHTML = e.dataTransfer.getData('text/plain')
            })
        </script>
    </body>
    </html>
    
  • 测试动图

    html5列表与布局(HTML5逐步分析实现拖放功能的方法)

    四、结束语

    到此这篇关于HTML5逐步分析实现拖放功能的方法的文章就介绍到这了,更多相关HTML5拖放功能内容请搜索开心学习网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持开心学习网!

    标签: