当前位置: 首页 > Web前端 > HTML

如何自定义拖动样式

时间:2023-03-28 17:44:22 HTML

欢迎关注我的公众号:网页前端侦探,图片默认可以拖动,一般是半透明预览图(以下简称“预览图”),如下图预览图是系统自动生成的,一般不能自定义,但是有时候会觉得拖动出来的预览图尺寸太大,不方便放置。拖动图片到指定区域,触发保存操作。因为拖动时预览图太大,覆盖了放置区域,体验很差。如果预览图片的尺寸可以小一些,比如这样:体验会不会好很多?下面一起来讨论一下1.预览图的默认尺寸首先,拖动预览图的尺寸与页面上图片的CSS尺寸有关,也就是说显示的图片越大,拖动的越大预览图像但是,预览图像的大小不是无限的。根据我的测试,预览图的最大尺寸是400400,比如下图尺寸是500500,但是拖动出来的预览图只有400*400,但是对于实际开发来说,这个尺寸还是太大了大的。以上是MacOSChrome下的性能效果。Firefox性能要好很多,不会出现预览图片过大的情况。另外我测试了WindowsChrome的性能效果也差不多,只是最大尺寸为200*200,性能如下2.使用setDragImage修改预览图。原生拖拽只能通过setDragImage修改预览图。看起来很厉害,其实很鸡肋。只需使用以下函数dragstart_handler(ev){varimg=newImage();img.src='例子.jpg';ev.dataTransfer.setDragImage(img,0,0);}这里指定这样一张图片为预览图,需要绑定dragstart事件,这里使用事件委托方式document.addEventListener('dragstart',ev=>{if(ev.target.tagName==='IMG'){dragstart_handler(ev)}})这是效果。为什么自定义预览只有在第二次拖动后才会出现??鸡肋由此而来,官方规定example.jpg为已有图片。如果尚未创建或加载,浏览器将使用默认的拖动图像。第二次拖动的时候图片就加载好了,所以才会生效。可以说,几乎所有setDragImage不起作用的情况都是出于这个原因。另外还有一个问题就是不能直接指定预览图的大小,例如functiondragstart_handler(ev){varimg=newImage();img.src='例子.jpg';img.width=50;//无效img.height=50;ev.dataTransfer.setDragImage(img,0,0);}这个也是无效的,内存中的图片会按照原来的大小显示3.指定预览图为页面元素其实如果要修改预览图的大小也可以通过canvas渲染原图,然后修改大小生成图片,但是canvas在渲染图片的时候经常会出现跨域问题,canvas也有一定的门槛,所以这里不使用.回去看官方语法dataTransfer.setDragImage(img|element,xOffset,yOffset);可以看到第一个参数不仅支持动态创建图片,还支持页面上实际存在的元素(页面上存在的元素必须加载)假设我们在页面中添加自定义预览图然后指定预览图片为example.jpgev.dataTransfer.setDragImage(图片,0,0);效果如下,拖动图片就像拖动example.jpg一样,也可以通过css直接修改大小!#img{宽度:100px;height:100px;}预览图的大小也是按照example.jpg如果把example.jpg换成和原图一样的链接,是不是相当于自定义了预览图的大小?现在需要隐藏自定义图片,毕竟只是借用而已,不需要在页面显示,这里有一个小技巧,不能真正隐藏这张图片,比如#img{display:没有任何;/*或*/不透明度:0;/*or*/visibility:none}这些方法都不行,因为预览图跟在这个自定义图片后面,如果直接隐藏,预览图会直接消失。此时采用的方法可以将这张图片移出可视区域,比如这样#img{position:absolute;top:-9999px;}这样就没有问题了。在实际工作中,这张图片应该是自动生成的。并自动获取当前拖动图片的链接,完整实现为/**custom_drag_img*author:xboxyan*/constimg=document.createElement('img');img.style="position:absolute;top:-9999px;最大宽度:100像素;最大高度:100像素;“document.body.append(img)document.addEventListener('dragstart',ev=>{if(ev.target.tagName==='IMG'){img.src=ev.target.src;ev.dataTransfer.setDragImage(img,0,0);}})可以把这段代码注入其他地方试试效果,比如原效果如下:效果注入以上代码后如下:在某些场景下体验是不是好多了?4.自定义预览图样式上面的预览图不仅可以指定图片元素,还可以指定其他元素,比如div,添加一些装饰

.drag_img{位置:绝对;顶部:-9999px;最大宽度:100px;最大高度:100px;border:3pxsolidyellow;}这样可以在预览图上添加黄色边框(强调)或者通过伪元素添加角标。drag_img::after{content:'';位置:绝对;顶部:0;右:0;宽度:20px;高度:20px;背景:线性渐变(-135deg,#f4433650%,transparent51%);}但是添加cssfilter没有生效,还是原来的style.drag_img{position:absolute;顶部:-9999px;最大宽度:100px;最大高度:100px;过滤器:棕褐色(1);/*Brownfilter*/}这可能与系统生成预览图的策略有关。这是不可能知道的,也无法修改。本质上还是原生的预览图,只适合图片拖动(但是性能超级好)。如果要完全自定义拖动效果,自定义普通的可拖动元素,必须通过JS模拟实现大致思路如下:去掉默认预览图,复制一份当前目标元素,cloneObj监听拖拽事件,通过transform改变cloneObj的位置。拖动后,移除cloneObj。详细原理可以参考我之前的文章:实现一个美化的原生拖拽虽然draggable-polyfill是自定义实现,但是完全不影响原有的业务拖拽逻辑。这就是polyfill的魅力所在,非常适合原生拖拽场景项目地址:https://github.com/XboxYan/draggable-polyfill,非常轻量级,不到100行代码,不影响业务逻辑,非常适合学习和使用,欢迎star~3年前的老代码,最近优化了一波,很实用,欢迎star6.综上,图片拖动预览的自定义完成。其实主要是用来修改预览大小的。它在某些场景中非常有用。这里有一些要点:拖动时生成的预览图是系统生成的,不能直接修改。在macOSChrome下,预览图最大尺寸为400*400,在某些场景下,体验不是很友好。setDragImage可以修改预览图。指定页面上的其他元素,不仅imgsetDragImage指定的元素不能真正隐藏,否则预览图不可见,可以移到看不见的地方如果需要完全自定义拖拽,可以使用draggable-polyfill解决方案。欢迎star~总的来说,整体实现还是很简单的。既然是原生方案,性能就不用多说了,不会影响原有的功能。美化的作用,如果你有类似的需求,请速速使用~最后,如果你觉得还不错,对你有帮助,欢迎点赞、收藏、转发???欢迎关注我的公众号:前-结束侦探