新增第193个小实例:可拖拽排序的人物列表
This commit is contained in:
parent
5d6e0d1bdc
commit
475b7ab6e7
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
|
@ -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);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue