首页与我联系

原生手写代码实践 | 图片拖拽效果(一)

By 前端达人
Published in 5-案例分享
August 14, 2022
1 min read
原生手写代码实践 | 图片拖拽效果(一)

一、系列介绍

前端的小伙伴们,我想大多数都是颜值控吧,看到一个漂亮或新奇的效果,都想搞明白是怎么实现的吧。但是前端发展的实在太快,各种框架和组件五花八门,由于项目业务时间的问题,我们都习惯了使用各种框架和组件去实现,以至于离开这些东西,我们有可能连个最基础的动效都不清楚怎么实现,这就是我想写这个系列文章的原因,放低心态,从最基础的原生代码开始复习实践。

本系列文章小编将和大家一起从最基础的原生代码实践,做一些小的项目,从练习中实践中复习和掌握前端的一些基础知识,只有熟练了才能理解前端的本质,学习前端新的知识和框架时就能更快的掌握。文章会用到 ES6、css3的特性来实现目前比较流行交互和特效效果。

二、 图片拖拽效果介绍

本篇文章,如下视频所示,界面有5个方格拖放区域,我们可以在这些区域里拖拽图片,当鼠标拖动图片时,图片周围有白色的粗边框,在拖动的目标方格会出现白色的虚线边框,结束拖动时,图片将会放置在目标方格内。

drag.png

三、拖拽相关事件复习

在练习前,我们先复习下和拖拽相关的几个API事件,在某个元素被拖动时,会按照顺序触发以下事件:

  1. dragstart(按住鼠标不放,刚开始拖动元素时,就会触发 dragstart 事件)
  2. drag(dragstart 事件触发后,只要元素还在被拖动时,就会持续触发 drag 事件,类似 mouseover,随着鼠标移动而不断触发)
  3. dragend(当拖动元素的动作停止时,放到目标位置或非目标位置,都会触发此事件)

以上三个事件,都是针对被拖动元素的,并不会改变元素的外观,如果你想改变外观需要自己定义。除了这些事件,当你把元素拖动到一个有效的放置目标上时,会依次触发以下事件:

  1. dragenter(只要推动元素进入目标位置上,就会立即触发)
  2. dragover(dragenter事件触发后,会立即触发此事件,如果被拖动元素,还在目标元素内持续拖动,会持续触发此事件)
  3. dragleave 或 drop(当被拖动的元素,放置在目标之外,dragover事件就会立即停止,触发dragleave事件;如果被拖动元素被放到了目标上松开了鼠标,则会触发drop事件)

四、开始编写代码

复习完基础知识后,我们来开始实践吧,我们依次创建三个文件 index.html,style.css,script.js,然后在 index.html 文件里引入样式和脚本文件。接下来我们开始编写代码吧!

1、编写HTML代码

html代码文件比较简单,我们依次创建5个div方格,并将被拖动的图片元素初始化放置在第一个方格代内,并在元素上添加可拖动属性 draggable 值为 true,表示此元素可被拖动(可调用拖拽API),示例代码如下:

<divclass="empty">
    <divclass="fill"draggable="true"></div>
</div>

<divclass="empty"></div>
<divclass="empty"></div>
<divclass="empty"></div>
<divclass="empty"></div>

2、编写CSS样式

接下来,我们来编写相关的CSS样式,代码很简单,这里只是简单说明下:

  1. 首先我们先定义全局样式,让五个方格水平垂直居中,这里我们使用flex弹性盒子布局;
  2. 接下来我们定义五个方格样式:宽高150px,背景元素为白色,边框为黑色;
  3. 被拖动的图片样式:宽高145px,图片路径我们调用了unsplash.com 提供的图片服务,可以按照图片大小随机图片,在我们做测试时,这个服务非常有用;
  4. 为了让用户比较直观的感受哪个元素正在被拖动,我们定义元素被拖动的外观样式,给图片定义5px宽的灰色边框。
  5. 在拖动至目标元素时,为了让用户更直观的感受到哪些位置是可以放置的目标元素,我们需要给其定义 hovered 样式,进入目标位置元素时,样式发生变化,背景为黑灰色,并有白色的边框虚线。
  6. 为了适应手机端,将五个方格由水平排列更改为垂直排列。

以上就是我们编写样式代码的思路,相关的CSS代码如下:

*{
    box-sizing: border-box;
}

body{
    background-color: steelblue;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
    margin: 0;
}

.empty{
    height: 150px;
    width: 150px;
    margin: 10px;
    border: solid 3px black;
    background-color: white;
}

.fill{
    background-image: url("https://source.unsplash.com/random/150x150");
    height: 145px;
    width: 145px;
    cursor: pointer;
}

.hold{
    border: solid 5px #ccc;
}

.hovered{
    background-color: #333;
    border-color: white;
    border-style: dashed;
}

@media(max-width: 800px) {
    body{
        flex-direction: column;
    }
}

3、编写JS脚本

最后我们来编写脚本代码,在编写前,我们需要提前规划思考下,具体思路如下:

  1. 首先定义两个DOM对象变量fill和empties,一个代表被拖动的图片对象,一个是可放置元素的目标对象(数组)。
  2. 在被拖动的图片元素上,绑定 dragstart 和 dragend事件。
  3. 在可被放置图片的目标元素进行循坏迭代,依次绑定 dragenter、dragover、dragleave、drop 事件。
  4. 接下来我们分别来定义相关事件函数, dragstart :当目标刚被拖动时,我们为元素添加白色的粗边框属性 .hold,并将当前此元素的容器背景div隐藏,这里使用样式 invisible。
  5. 鼠标放下时,拖拽动作结束,触发dragend事件,我们定义 dragEnd() 函数,将图片元素的容器样式更改为fill。
  6. 接下来,我们来定义拖动至目标元素触发的相关事件函数,进入目标元素时,触发dragEnter:阻止默认的浏览器行为,为其添加进入目标位置的元素样式:hovered。在目标位置元素移动拖动元素时的dragOver函数:阻止浏览器的默认行为;当元素离开目标位置时dragLeave,我们需要将当前元素的样式更改为原始的样式empty;最后定义 dragDrop 函数,用户在目标位置,松开鼠标时触发,我们先将当前位置的样式更改为empty,并在其中添加拖动的图片元素容器。

思路就聊到这里,下面给出脚本相关的代码,示例代码如下:

constfill=document.querySelector(".fill");
constempties=document.querySelectorAll(".empty");

fill.addEventListener('dragstart',dragStart);
fill.addEventListener('dragend',dragEnd);

for(constemptyofempties){
    empty.addEventListener('dragenter',dragEnter);
    empty.addEventListener('dragover',dragOver);
    empty.addEventListener('dragleave',dragLeave);
    empty.addEventListener('drop',dragDrop);
}

functiondragStart(){
this.className += " hold";
setTimeout(()=>this.className='invisible',0)
}

functiondragEnd(){
this.className='fill'
}

functiondragOver(e){
    e.preventDefault();
}

functiondragEnter(e){
    e.preventDefault();
this.className += " hovered"
}

functiondragLeave(){
this.className='empty'
}

functiondragDrop(){
this.className="empty"
this.append(fill)
}

结束语

好了,今天的项目就到这里结束了,想必大家都熟悉了拖拽相关的事件和如何应用,大家可以点击阅读原文体验交互效果(在PC端体验),如果想获取源码,请公众号回复 “a1” 获取本项目源码。

版权声明

qrcode.jpg

注:本文属于原创文章,版权属于「前端达人」公众号及 qianduandaren.com 所有,未经授权,谢绝一切形式的转载


Tags

javascript原生项目
Previous Article
深入理解CSS线性渐变(linear-gradient)上
前端达人

前端达人

专注前端知识分享

Table Of Contents

1
一、系列介绍
2
二、 图片拖拽效果介绍
3
三、拖拽相关事件复习
4
四、开始编写代码
5
结束语
6
版权声明

相关文章

「手写原生项目专题」一个带计时进度的在线答题应用(五)
October 07, 2022
1 min

前端站点

VUE官网React官网TypeScript官网

公众号:前端达人

前端达人公众号