【JavaScript】拖动事件,鼠标拖动元素出现默认样式原因及解决方法,进度条拖动样式,拖动对象dataTransfer对象


在制作进度条的时候,想要制作一个进度条的拖动样式,所以我给他注册了拖动事件 drag,然后虽然可以拖拽产生相应的变化但是会出现一个禁止的标志
解决这个问题先要分析一些拖拽事件:

拖动事件

这里说一下拖动事件:

什么是拖放?拖放是一种常见的特性,即抓取对象以后拖到另一个位置。

为了让元素可拖动,需要使用 HTML5 draggable 属性(设置为draggable=true)。(链接和图片默认是可拖动的,不需要 draggable 属性。)

在拖动目标上触发事件 (源元素):

  1. dragstart
    要被拖拽的元素开始拖拽时触发,这个事件对象是被拖拽元素
  2. drag - 元素正在拖动时触发
  3. dragend - 用户完成元素拖动后触发
    在drop之后触发,就是拖拽完毕时触发,这个事件对象是被拖拽元素
    释放目标时触发的事件:
  4. dragenter
    拖拽元素进入目标元素时触发,这个事件对象是目标元素
  5. dragover
    拖拽某元素在目标元素上移动时触发,这个事件对象是目标元素
  6. dragleave
    拖拽某元素离开目标元素时触发,这个事件对象是目标元素
  7. drop
    ondrop 事件在可拖动元素或选取的文本放置在目标区域时触发。
    触发顺序:
    dragstart –> dragenter –> dragover –> drop –> dragend

使用拖拽事件后就可以对元素注册该事件,然后完成相应的工作,而产生的禁止标志实际上和拖动事件对象有关:

拖动事件对象

dataTransfer对象

dataTransfer对象是事件对象的一个属性,用于从被拖拽元素相放置目标传递字符串格式的数据。

因为它是事件对象的属性,所以只能在拖放事件的事件处理程序中访问dataTransfer对象。在事件处理程序中,可以使用这个对象的属性和方法来完善拖放功能。

dataTransfer对象的属性:
  1. dropEffect(重点)
    拖放的操作类型,决定了浏览器如何显示鼠标形状,可能的值为copy、move、link和none。
    1.属性作用: 用于设置目标元素将执行的操作,若属性值属于 effectAllowed 范围内,则鼠标指针将显示对应的指针样式,否则则显示禁止的指针样式。
    2.取值范围
    copy :被拖拽元素将被复制到目标元素内,若属于 effectAllowed 范围内时,则鼠标指针显示复制的样式,否则则显示禁止的指针样式。
    link :被拖拽元素将以超链接的形式打开资源,若属于 effectAllowed 范围内时,则鼠标指针显示超链接的样式,否则则显示禁止的指针样式。
    move :被拖拽元素将被移动到目标元素内,若属于 effectAllowed 范围内时,则鼠标指针显示移动的样式,否则则显示禁止的指针样式。
    none :被拖拽元素不能在目标元素上作任何操作,一直显示禁止的指针样式。除了文本框外其他元素的默认值均为none
    3.注意
    1)仅能在 dragover 事件中设置该属性值,其他事件中设置均无效
    2)当显示禁止的指针样式时,将无法触发目标元素的 drop 事件。 通过将effectAllowed 和 dropEffect两个属性进行匹配我们就可以很简单的根据拖拽行为即将要发生的事情,来设置对应的鼠标样式了。
  2. effectAllowed(重点)
    指定所允许的操作,可能的值为copy、move、link、copyLink、copyMove、linkMove、all、none和uninitialized(默认值,等同于all,即允许一切操作)。
    1.属性作用:用于设置被拖拽元素可执行的操作。
    2.取值范围:
    copy ,限定dropEffect的属性值为copy,否则会鼠标指针为禁止样式
    link ,限定dropEffect的属性值为link,否则会鼠标指针为禁止样式
    move ,限定dropEffect的属性值为move,否则会鼠标指针为禁止样式
    copyLink ,限定dropEffect的属性值为copy和link,否则会鼠标指针为禁止样式
    copyMove ,限定dropEffect的属性值为copy和move,否则会鼠标指针为禁止样式
    linkMove ,限定dropEffect的属性值为link和move,否则会鼠标指针为禁止样式
    all ,允许dropEffect的属性值为任意值
    none ,鼠标指针一直为禁止样式,不管dropEffect的属性值是什么
    uninitialized ,没有限定dropEffect属性的值,效果和 all 一样。
    3.注意:仅能在 dragstart 事件中设置该属性,其他事件中设置均无效。
  3. files:包含一个FileList对象,表示拖放所涉及的文件,主要用于处理从文件系统拖入浏览器的文件。
  4. types:储存在DataTransfer对象的数据的类型。
dataTransfer对象的方法:
  1. setData(format, data):在dataTransfer对象上储存数据。第一个参数format用来指定储存的数据类型,比如text、url、text/html等。
  2. getData(format):从dataTransfer对象取出数据。
  3. clearData(format):清除dataTransfer对象所储存的数据。如果指定了format参数,则只清除该格式的数据,否则清除所有数据。
  4. setDragImage(imgElement, x, y):指定拖动过程中显示的图像。默认情况下,许多浏览器显示一个被拖动元素的半透明版本。
  5. imgElement必须是一个图像元素,而不是指向图像的路径,参数x和y表示图像相对于鼠标的位置。

拖动元素div或img时出现禁止图标。

原因解析

在拖放的过程中遇到当一个div上有其他元素,例如P、label、img等,在拖动到P、label时会出现禁止拖动的图标

被拖动元素(比如说img元素),目标元素(拖动时鼠标经过的元素,比如说一个有高度和宽度的div元素)。
当被拖动元素img拖动中经过目标元素div时,如果目标元素div不能接收被拖动元素的drop时,就会出现禁止标记。

解决方案

拖动到的“目的地”并不接受拖动的元素-----这是因为当拖动元素经过document时,document对象默认阻止了拖动事件,而其他HTML组件也位于document对象内,因此它们也不能接受“放”。

  1. 因此我们需要将目标元素加两个事件ondragenter ondragover事件内容为event.preventDefault()禁止浏览器的默认行为
    在目标元素加事件,类似这样:
    ,在dragenter(evt) {evt.preventDefault()),就能消除禁止标记的出现。
  2. 使用dataTransfer对象对象的dropEffect属性可以更换产生的拖拽时鼠标样式

进度条拖动样式

使用拖拽事件注册的拖拽进度条会产生拖拽对象的鼠标样式,而拖动进度条并不希望产生该样式,拖拽时的鼠标样式也没有默认的小白

使用鼠标点击事件 鼠标移动事件 鼠标抬起事件 替代拖拽事件

鼠标点击事件注册在点击触发拖动的元素身上,鼠标移动事件和鼠标抬起事件放置到document身上

loading.onmousedown = function(e) {
        document.onmousemove = function(e) {
            video.removeEventListener('timeupdate', musicPlay);//消除进度条播放事件
           	//这里就可以对进度条进行操作
            }

        }
		
        document.onmouseup = function(e) {
            document.onmousemove = null;
            document.onmouseup = null;
        }

    }

这样还不行,当在拖动进度条时,可能会误触他的父元素,然后将其拖走然后无法触发mouseup事件,所以需要禁止选择这些可能会误触的元素

CSS的user-select属性

CSS 属性 user-select 控制用户能否选中文本。除了文本框内,它对被载入为 chrome 的内容没有影响。
语法:
none
元素及其子元素的文本不可选中。 请注意这个Selection 对象可以包含这些元素。 从Firefox 21开始, none 表现的像 -moz-none,因 此可以使用 -moz-user-select: text 在子元素上重新启用选择。
text
用户可以选择文本。
all
在一个HTML编辑器中,当双击子元素或者上下文时,那么包含该子元素的最顶层元素也会被选中。
contain
允许在元素内选择;但是,选区将被限制在该元素的边界之内。

  • 16
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,下面是一个简单的可左右拖动列宽的表格代码示例,同时也带上了一些基本的样式HTML: ```html <table id="myTable"> <thead> <tr> <th>Header 1</th> <th>Header 2</th> <th>Header 3</th> </tr> </thead> <tbody> <tr> <td>Row 1, Col 1</td> <td>Row 1, Col 2</td> <td>Row 1, Col 3</td> </tr> <tr> <td>Row 2, Col 1</td> <td>Row 2, Col 2</td> <td>Row 2, Col 3</td> </tr> <tr> <td>Row 3, Col 1</td> <td>Row 3, Col 2</td> <td>Row 3, Col 3</td> </tr> </tbody> </table> ``` CSS: ```css table { border-collapse: collapse; width: 100%; } th, td { padding: 8px; text-align: left; } thead { background-color: #f2f2f2; } th { background-color: #e6e6e6; } td { border-bottom: 1px solid #ddd; } /* 定义可拖动的列 */ .col-resize { width: 8px; cursor: col-resize; position: absolute; top: 0; right: 0; bottom: 0; z-index: 10; -moz-user-select: none; -webkit-user-select: none; user-select: none; } /* 定义拖动列时的样式 */ .col-resize:hover { background-color: #f4f4f4; } ``` JavaScript: ```javascript // 获取表格元素 var table = document.getElementById("myTable"); // 获取表头元素 var headers = table.getElementsByTagName("th"); // 循环遍历所有表头 for (var i = 0; i < headers.length; i++) { // 定义变量,用于存储当前列的宽度 var currentWidth; // 创建一个 div 元素,用于拖动改变列宽 var div = document.createElement("div"); // 给 div 元素添加自定义类名 div.className = "col-resize"; // 给 div 元素添加事件监听器,用于处理拖动事件 div.addEventListener("mousedown", function(event) { // 阻止默认事件 event.preventDefault(); // 将当前列的宽度存储到变量中 currentWidth = this.parentNode.offsetWidth; // 将当前列的索引存储到变量中 var columnIndex = Array.prototype.indexOf.call(this.parentNode.parentNode.children, this.parentNode); // 将鼠标按下事件添加到 document 上,用于处理拖动过程中的事件 document.addEventListener("mousemove", mousemove); // 将鼠标抬起事件添加到 document 上,用于处理拖动结束后的事件 document.addEventListener("mouseup", mouseup); // 定义一个鼠标移动事件处理函数 function mousemove(event) { // 计算拖动距离 var diff = event.pageX - currentWidth; // 设置当前列的宽度为拖动距离 headers[columnIndex].style.width = diff + "px"; } // 定义一个鼠标抬起事件处理函数 function mouseup(event) { // 将鼠标移动事件从 document 上移除 document.removeEventListener("mousemove", mousemove); // 将鼠标抬起事件从 document 上移除 document.removeEventListener("mouseup", mouseup); } }); // 将 div 元素添加到当前表头元素的子元素列表中 headers[i].appendChild(div); } ``` 这段代码使用了原生 JavaScript 实现了可左右拖动列宽的表格,并使用 CSS 添加了一些基本的样式。当鼠标按下拖动列宽的时候,通过添加事件监听器处理鼠标移动和抬起事件,并计算出拖动距离来改变列的宽度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

列队猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值