这里简单说下实现轻点、长按列表实现错位排序动画实现思路,这里只用到了JQ,没有使用其他的库。胸有成竹、不屑一顾的大神请直接跳到最后点个赞也好,非常感谢。
用户手势交互可以直接使用mouse事件处理(移动端用touch事件),监听mouse事件在对应dom上的状态。
对于列表item这里采用的className 为menu,当鼠标在列表的item按下时,这里添加一个定时器,定时器延迟操作可以设置长按事件的等待时间。这里记录一下按下时的系统时间。
在mouseup事件里再去获取一次系统时间,若两次的时间差小于设置的长按事件界定时长,那么处理轻点事件,若大于该时长,处理长按事件。
这里就能区分用户操作是轻点还是长按了。
这里初始化的所有列表位置布局是用JS创建dom对象并添加CSS样式实现的,本人CSS水平有限,没有想到这类场景如何用CSS去添加动画。创建完所有的item后,计算获取每个item对应位置信息这里标为“rect”属性;先创建rect对象,包含四个属性:x,y,width,height。
获取rect的目的有两个:
1、是在鼠标移动的过程中去检测当前的even触点位置是否在某个可交换的item上。
2、判断进行错位动画时获取需要改变后的调整的位置。
JS动态创建下的dom对象无法改变在文档流中的位置,但是改变后的位置又可能为后续环节使用,所以除了在dom对象上添加了rect属性外,还添加了index属性。这样在排序的过程中,index属性也相应改变,在最后获取排序结果时根据index操作即可。
上面已经分析了如何执行轻点事件,那么当item在执行轻点事件时候进行移除操作,
执行移除当前点击的item
因为删除了item后面的所有item的index属性都要修改,所以这里添加了一个方法来时现实index的重排。
注:参数index是要删除item的索引值。
依次改变要删除item后面的全部item的rect,并实现错位动画
修改rect属性
添加错位动画
好了,这里就完成了轻点删除及错位动画。
在遍历所有item前调用了一个排序方法获取以index为排序依据的dom集合!!!
这里用到了mousemove方法。
1、当拖拽开始后,全局保存下当前的所选的item,获取mouse的even的x值跟y值,控制当前所选的item位置跟随触点变化。
2、检测触点移动的位置是否处在可交换的其他item上,若条件符合,根据当前的被拖拽的item的与可交换的item的index属性进行判断,修改二者之间的其他item位置,重置其rect及index属性值。
源码粘出来想看的可以看看,觉得太长的可以忽略,个人随笔,肯定有不严谨的地方,希望大神留言指正,互相学习。
dragPlus.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.wrap {
width: 380px;
height: auto;
zoom: 1;
overflow: hidden;
border: 1px solid #8E8E8E;
margin-top: 100px;
margin-left: 400px;
position: relative;
}
.menu {
background-color: darkred;
color: #FFFFFF;
font-size: 16px;
text-align: center;
line-height: 30px;
position: absolute;
display: inline-block;
z-index: 10;
}
.active {
border: 1px dashed #8E8E8E;
position: absolute;
display: inline-block;
z-index: -1;
}
.onclick {
transform: scale(1.2);
position: absolute;
background-color: darkred;
line-height: 30px;
height: 30px;
width: 70px;
text-align: center;
color: #FFFFFF;
}
</style>
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js" type="text/javascript"></script>
<script src="./dragPlus.js"></script>
</head>
<body>
<div class="wrap" id="wrap"></div>
</body>
<script>
var drag = new DragPlus('wrap', ["测试1", "测试2", "测试3", "测试4", "测试5", "测试1", "测试2", "测试3", "测试4", "测试5", ], 3);
</script>
<script src="./dragTouchEven.js"></script>
</html>
dragPlus.js
function DragPlus(vm, items, column) {
this.contain = $("#" + vm);
this.items = items;
this.column = column;
this.sep = 10;
this.reload();
this.duran = 500;
this.currentOptionElement = null;
}
DragPlus.prototype = {
//刷新
reload: function() {
var width = $(this.contain).width();
var itemWidth = (width - this.sep * (this.column + 1)) / this.column;
var itemHeight = itemWidth;
var row = parseInt(this.items.length / this.column) + ((this.items.length % this.column) ? 1 : 0);
var maxY = itemHeight * row + this.sep * (row + 1);
for (var i = 0; i < this.items.length; i++) {
var text = this.items[i];
var tempDiv = document.createElement("div");
$(tempDiv).attr('class', 'menu')
var x = this.sep + (i % this.column) * (itemWidth + this.sep);
var y = this.sep + parseInt(i / this.column) * (itemWidth + this.sep);
$(tempDiv).css("left", x);
$(tempDiv).css("top", y);
$(tempDiv).text(text);
$(tempDiv).width(itemWidth);
$(tempDiv).height(itemHeight);
$(this.contain).append(tempDiv);
var rect = {}
rect.x = x;
rect.y = y;
rect.width = itemWidth;
rect.height = itemHeight;
$(tempDiv).attr("rect", JSON.stringify(rect))
}
$(this.contain).height(maxY)
this.resetIndex(null);
},
//删除
deleteItem: function(item) {
var index = $(item).attr("index");
var rect = $.parseJSON($(item).attr("rect"));
this.items.splice(index, 1);
$(item).remove()
this.resetIndex(index);
this.addChangePositionAnimate(index, rect);
},
//改变位置动画
addChangePositionAnimate: function(index, rect) {
var items = this.resort();
for (var i = items.length - 1; i >= index; i--) {
var item = items[i];
var newRect = (i == index) ? rect : $.parseJSON($(items[i - 1]).attr("rect"));
$(item).attr("rect", JSON.stringify(newRect));
this.animate(item, newRect);
}
var that = this;
setTimeout(function() {
that.resetParentRect();
}, that.duran);
},
//添加动画
animate: function(item, rect) {
var that = this;
$(item).animate({
left: rect.x + 'px',
top: rect.y + 'px'
}, that.duran);
},
//重置item索引属性
resetIndex: function(index) {
if (index == null) {
var items = document.getElementsByClassName("menu");
for (var i = 0; i < items.length; i++) {
var item = items[i];
$(item).attr("index", i)
}
} else {
var items = this.resort();
for (var i = index; i < items.length; i++) {
var item = items[i];
var nowIndex = $(item).attr("index");
$(item).attr("index", nowIndex - 1);
}
}
},
//重置父视图高度
resetParentRect: function() {
if (this.items.length == 0) {
$(this.contain).height(this.sep);
} else {
var width = $(this.contain).width();
var itemHeight = (width - this.sep * (this.column + 1)) / this.column;
var row = parseInt(this.items.length / this.column) + ((this.items.length % this.column) ? 1 : 0);
var maxY = itemHeight * row + this.sep * (row + 1);
$(this.contain).height(maxY)
}
},
//创建old占位div
createOldPlaceholderElement: function(rect, index) {
var tempDiv = document.createElement("div");
$(tempDiv).attr('class', 'active')
$(tempDiv).attr('id', 'old')
var x = rect.x;
var y = rect.y;
$(tempDiv).css("left", x);
$(tempDiv).css("top", y);
$(tempDiv).width(rect.width);
$(tempDiv).height(rect.height);
$(tempDiv).attr("rect", JSON.stringify(rect))
$(tempDiv).attr("index", index);
$(this.contain).append(tempDiv);
},
//移动区间模块
moveInterval: function(oldElement, newElement) {
var oIndex = parseInt($(oldElement).attr("index"));
var nIndex = parseInt($(newElement).attr("index"));
//console.log('oIndex=' + oIndex + ',' + 'nIndex=' + nIndex);
var rect = $.parseJSON($(newElement).attr("rect"));
var oldRect = $.parseJSON($(oldElement).attr("rect"));
$(oldElement).css({
"left": rect.x,
"top": rect.y
});
var items = this.resort();
if (oIndex < nIndex) {
for (var i = nIndex; i > oIndex; i--) {
var item = items[i];
if (item) {
var tempRect = $.parseJSON($(items[i - 1]).attr("rect"))
var newRect = (i == oIndex + 1) ? oldRect : tempRect;
$(item).attr("rect", JSON.stringify(newRect));
var tempIndex = $(items[i - 1]).attr("index");
var index = (i == oIndex + 1) ? oIndex : $(items[i - 1]).attr("index");
$(item).attr("index", index);
this.animate(item, newRect);
}
}
} else {
for (var i = nIndex; i < oIndex; i++) {
var item = items[i];
if (item) {
var tempRect = $.parseJSON($(items[i + 1]).attr("rect"))
var newRect = (i == oIndex - 1) ? oldRect : tempRect;
$(item).attr("rect", JSON.stringify(newRect));
var tempIndex = $(items[i + 1]).attr("index");
var index = (i == oIndex - 1) ? oIndex : $(items[i + 1]).attr("index");
$(item).attr("index", index);
this.animate(item, newRect);
}
}
}
$(oldElement).attr("rect", JSON.stringify(rect))
$(oldElement).attr("index", nIndex);
var that = this;
$(that.currentOptionElement).attr("rect", JSON.stringify(rect))
$(that.currentOptionElement).attr("index", nIndex);
setTimeout(function() {
that.resetParentRect();
}, that.duran + 10);
},
//重新排序
resort: function() {
var itemsOld = document.getElementsByClassName("menu");
var dic = {};
for (var i = 0; i < itemsOld.length; i++) {
var item = itemsOld[i];
dic[$(item).attr("index")] = item;
}
var items = [];
Object.keys(dic).sort().forEach(function(key) {
items.push(dic[key]);
});
return items;
}
}
dragTouchEven.js
$(function() {
var action = false; //定义一个全局变量来判断鼠标动作,默认为false
var mouseTapX = 0;
var mouseTapY = 0;
var timer = null;
var isLongPress = false;
var currentTime = 0;
var longpressTime = 500;
var animateTime = 500;
var currentSelectItem = null;
$(document).on("mousedown", ".menu", function(event) { //鼠标按下事件
var that = this;
currentSelectItem = that;
isLongPress = true;
drag.currentOptionElement = that;
currentTime = Date.parse(new Date());
timer = setTimeout(function() {
if (isLongPress) {
action = true;
if ($(".onclick").length < 1) {
var left = $(that).offset().left - $(".wrap").offset().left; //获取在wrap内的偏移量
var top = $(that).offset().top - $(".wrap").offset().top;
mouseTapX = event.pageX - $(that).offset().left;
mouseTapY = event.pageY - $(that).offset().top;
var rect = $.parseJSON($(that).attr("rect"));
var index = $(that).attr("index");
drag.createOldPlaceholderElement(rect, index);
//$(that).before("<div class='active' id='old'></div>"); //鼠标按下时在原位置创建一个活动的空div
$(that).css({
"left": left,
"top": top,
});
}
}
}, longpressTime);
})
$(document).on("mousemove", ".wrap", function(event) { //wrap上的鼠标移动事件,menu 移动
if (action == true) {
var x = event.pageX - $(".wrap").offset().left; //获取鼠标在wrap的偏移量
var y = event.pageY - $(".wrap").offset().top;
$(currentSelectItem).css({
"left": x - mouseTapX,
"top": y - mouseTapY
}); //补充内边距
judgeInsertLeftOrRight(x, y);
}
})
$(document).on("mouseup", function() { //鼠标弹起时将移动的menu 放入新的接受div里,并移除原div位置上的空div
var nowTime = Date.parse(new Date());
isLongPress = (nowTime - currentTime >= longpressTime);
if (!isLongPress) {
//单点
drag.deleteItem(currentSelectItem);
} else {
//长按
var oldElement = $("#old");
if ($(oldElement).attr("rect")) {
var rect = $.parseJSON($(oldElement).attr("rect"));
var oIndex = $(oldElement).attr("index");
$(currentSelectItem).attr("rect", JSON.stringify(rect))
$(currentSelectItem).attr("index", oIndex);
$(currentSelectItem).animate({
left: rect.x + 'px',
top: rect.y + 'px',
}, 200);
$("#old").remove();
}
}
action = false;
})
})
function deleteItem(currentSelectItem) {
if (currentSelectItem) {
drag.deleteItem(currentSelectItem);
}
}
//判断当前的鼠标点的位置在其他标签的位置
function judgeInsertLeftOrRight(mx, my) {
var items = document.getElementsByClassName("menu");
for (var i = 0; i < items.length; i++) {
var item = items[i];
var rect = $.parseJSON($(item).attr("rect"));
if (mx > rect.x && mx < rect.x + rect.width && my > rect.y && my < rect.y + rect.height) {
insertPlaceholderElement(item);
return;
}
}
}
//标签前后插入新的占位标签
function insertPlaceholderElement(item) {
drag.moveInterval($("#old"), item);
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!