新增第193个小实例:可拖拽排序的人物列表

This commit is contained in:
DESKTOP-BM6RJU5\wyanh 2022-11-22 16:52:08 +08:00
parent 5d6e0d1bdc
commit 475b7ab6e7
4 changed files with 173 additions and 0 deletions

View File

@ -200,6 +200,7 @@
190. HTML5+CSS3小实例3D翻转Tab选项卡切换特效
191. HTML5+CSS3+JS小实例文字依次点击验证
192. HTML5+CSS3+JS小实例过山车文字动画特效
193. HTML5+CSS3+JS小实例可拖拽排序的人物列表
#### 赞赏作者
![image](https://gitee.com/wyanhui02/html_css_demo/raw/master/images/%E8%B5%9E%E8%B5%8F%E4%BD%9C%E8%80%85/%E8%B5%9E%E8%B5%8F%E7%A0%81.jpg)

49
code/193/193.css Normal file
View File

@ -0,0 +1,49 @@
*{
/* 初始化 */
margin: 0;
padding: 0;
}
body{
/* 100%窗口宽高 */
height: 100vh;
/* 弹性布局 水平+垂直居中 */
display: flex;
justify-content: center;
align-items: center;
background-color: #333;
}
.list-item{
width: 400px;
height: 70px;
/* 通过var函数调用已经设置好的自定义属性--color设置背景颜色 */
background-color: var(--color);
border-radius: 8px;
margin: 15px 0;
padding-left: 20px;
display: flex;
align-items: center;
/* 光标变移动图标 */
cursor: move;
}
.list-item img{
width: 50px;
height: 50px;
object-fit: cover;
object-position: top;
margin-right: 20px;
}
.list-item span{
color: #fff;
font-size: 22px;
letter-spacing: 2px;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
/* 接下来添加拖拽时的样式 */
.list-item.moving{
background-color: transparent;
border: 2px dashed #ccc;
}
.list-item.moving img,
.list-item.moving span{
display: none;
}

40
code/193/193.html Normal file
View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>可拖拽排序的人物列表</title>
<link rel="stylesheet" href="193.css">
</head>
<body>
<div class="list">
<!-- --color是自定义属性 -->
<div class="list-item" draggable="true" style="--color:#b01a01;">
<img src="/images/op/1.jpg" alt="">
<span>路飞</span>
</div>
<div class="list-item" draggable="true" style="--color:#70d265;">
<img src="/images/op/2.jpg" alt="">
<span>索隆</span>
</div>
<div class="list-item" draggable="true" style="--color:#f0e941;">
<img src="/images/op/3.jpg" alt="">
<span>山治</span>
</div>
<div class="list-item" draggable="true" style="--color:#da8218;">
<img src="/images/op/4.jpg" alt="">
<span>娜美</span>
</div>
<div class="list-item" draggable="true" style="--color:#f1e867;">
<img src="/images/op/5.jpg" alt="">
<span>乌索普</span>
</div>
</div>
</body>
</html>
<script src="193.js"></script>

83
code/193/193.js Normal file
View File

@ -0,0 +1,83 @@
// 要操作的元素
const list=document.querySelector('.list'),
item=document.querySelectorAll('.list-item');
// 判断当前拖动的是哪个元素
let source_node;
// 开始拖动的事件
list.ondragstart=e=>{
// 获取当前拖动的元素
source_node=e.target;
// 记录起始位置
record(item);
// 添加moving样式
setTimeout(() => {
e.target.classList.add('moving');
}, 0);
// 设置被拖动元素允许移动到新的位置
e.dataTransfer.effectAllowed='move';
}
// 在元素正在拖动到放置目标时触发
list.ondragover=e=>{
e.preventDefault();
}
// 拖动进行中的事件
list.ondragenter=e=>{
e.preventDefault();
// 拖回到原来的位置,就什么也不做
if(e.target===list || e.target===source_node){
return false;
}
// 获取.list的所有子元素
const children=Array.from(list.children);
// 当前劫持元素的索引值
const sourceIndex=children.indexOf(source_node);
// 覆盖到谁上面的索引值
const targetIndex=children.indexOf(e.target);
if(sourceIndex<targetIndex){
// insertBefore(要插入的节点,在谁前面)
// 从下向上拖动
list.insertBefore(source_node,e.target.nextElementSibling);
}else{
// 从上向下拖动
list.insertBefore(source_node,e.target);
}
// 传入改变位置的两个元素,比较差异,执行动画
last([e.target,source_node]);
}
// 拖动结束时取消虚线
list.ondragend=e=>{
e.target.classList.remove('moving');
}
// 记录起始位置
function record(eleAll){
for(let i=0;i<eleAll.length;i++){
const {top,left}=eleAll[i].getBoundingClientRect();
eleAll[i]._top=top;
eleAll[i]._left=left;
}
}
// 记录最后的位置,并执行动画
function last(eleAll){
for(let i=0;i<eleAll.length;i++){
const dom=eleAll[i];
const {top,left}=dom.getBoundingClientRect();
if(dom._left){
dom.style.transform=`translate3d(${dom._left-left}px,${dom._top-top}px,0px)`;
let rafId=requestAnimationFrame(function(){
dom.style.transition='transform 0.3s ease-out';
dom.style.transform='none';
})
dom.addEventListener('transitionend',()=>{
dom.style.transition='none';
cancelAnimationFrame(rafId);
})
}
}
}