js高仿QQ消息列表左滑功能
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js高仿QQ消息列表左滑功能相关的知识,希望对你有一定的参考价值。
该组件,主要功能类似于QQ消息列表左滑出现删除、标为已读等按钮的功能;现在的版本用的是纯javascript编写;后续会跟进 angularJs 开发的类似组件以及jquery的;
下面,就让我们来认识下怎么使用该程序;
在该程序里,总共分为四个文件:
1 .css文件夹
2. img 图片文件夹
3. js文件
4. index.html 主页面;
稍后,你可以自行下载,打开运行观看效果;
二、代码讲解
1.此html结构,为不可修改结构
<ul class="list-ul">
<!--an-slide-li 此样式必须添加在li标签上,为js程序判断是否选中的是要操作的dom元素所用-->
<li class="list-li an-slide-li">
<!--z-index-up(z-index:层级最高,且覆盖整个li):对应的dom元素,是为了在触发touchStart事件事,可以选中整个li-->
<div class="z-index-up" onClick="change(‘新浪博客‘)"></div>
<div>
<div class="list-img">
<div>
<img src="img/Tulips.jpg" />
</div>
</div>
<div class="list-contant">
<div class="list-contant-title"><label>微博已开通</label></div>
<div class="list-contant-text"><label>第一个,我要发博客</label></div>
</div>
<div class="list-time-message">
<div class="list-time"><span>10:18</span></div>
<div class="list-message"></div>
</div>
</div>
<div class="btn" onClick="del(‘1‘)">
<div>
删除
</div>
</div>
</li>
</ul>
2. js代码讲解;
注:该程序主要使用js的三个事件touchstart(手指触摸事件)、startmove(手指移动)、startend(手指离开屏幕)
请认真阅读以下代码,你会对这三个事件有一个新的认识;让我们一起嗨起来吧!
//在全局运行此程序
window.addEventListener("load", autoLoad, false);
function autoLoad() {
var initX; //触摸位置
var initY;
var moveX; //滑动时的位置
var moveY;
var X = 0; //移动距离
var Y = 0; //y轴移动距离
var objX, sildeWidth = 0; //目标对象位置、功能按钮width(如删除)
//yesClick:是否可以点击列表进行下一步操作; xSilde,ySilde 默认xSilde都为true(做上下 , 左右滑动控制)
var yesClick, xSilde = true,
ySilde = true,
xThink = ‘1‘;
window.sessionStorage.setItem("xThink", xThink); //初始化xThink
//开始执行程序
window.addEventListener(‘touchstart‘, touchStart, false);
/*手指触屏时的方法*/
function touchStart(event) {
//通过设置的 an-z-index-up 对应dom(目的:可以选中整个li元素) ,获取父元素li ()
var obj = event.target.parentNode;
//获取所有的li元素
var mainLi = document.querySelectorAll(".an-slide-li");
/*当点击的是功能按钮的话,初始化xThink、anObjX*/
if (event.target.className.indexOf("an-function-button") != -1) {
window.sessionStorage.setItem("xThink", ‘1‘); //初始化xThink
window.sessionStorage.setItem("anObjX", ‘0‘);
}
/*
*btnStyle: 获取功能按钮,判断一共添加了几个按钮
*btnStyleLength: btnStyle 长度
*setWidth :btnStyle 按钮宽度
*/
var btnStyle, btnStyleLength, setWidth;
sildeWidth = 5;
//设置默认状态下点击列表可进行下一步
yesClick = true;
/*判断如果最终的值小于0 , 关闭已经出现的动画;禁止li点击事件(此值在end方法中会被重新赋值,再作判断)*/
var anObjX = window.sessionStorage.getItem("anObjX");
if (anObjX == null) {
anObjX = 0;
}
if (anObjX < 0) {
event.preventDefault();
for (var i = 0; i < mainLi.length; i++) {
mainLi[i].style.transition = "transform 0.1s"; //延缓动画效果
mainLi[i].style.transform = "translateX(0rem)";
mainLi[i].style.WebkitTition = "transform 0.1s"; //延缓动画效果
mainLi[i].style.WebkitTransform = "translateX(0rem)";
}
yesClick = false;
event.stopPropagation(); //事件冒泡,禁止上下滑动;
}
/*判断是否点中删除按钮*/
if (event.target.parentNode.className === "btn") {
event.target.parentNode.onclick();
}
/*判断手指所在的区域为指定li*/
if (obj.className.indexOf("an-slide-li") != -1) {
initX = event.targetTouches[0].pageX; //获取手指触摸x值
initY = event.targetTouches[0].pageY; //获取手指触摸y值
objX = (obj.style.WebkitTransform.replace(/translateX\\(/g, "").replace(/rem\\)/g, "")) * 1; //获取WebkitTransform 值;
//自动添加 动画样式
if (!objX) {
for (var i = 0; i < mainLi.length; i++) {
mainLi[i].style.transition = "transform 0.1s"; //延缓动画效果
mainLi[i].style.transform = "translateX(0rem)";
mainLi[i].style.WebkitTition = "transform 0.1s"; //延缓动画效果
mainLi[i].style.WebkitTransform = "translateX(0rem)";
objX = (obj.style.WebkitTransform.replace(/translateX\\(/g, "").replace(/rem\\)/g, "")) * 1; //获取WebkitTransform 值;
}
}
}
/*当=0时,执行touchMove命令*/
//console.log();
if (objX == 0) {
obj.addEventListener(‘touchmove‘, touchMove, false);
}
obj.addEventListener(‘touchend‘, touchEnd, false);
}
//手指滑动方法
function touchMove(event) {
//event.preventDefault();
/*xThink : 控制当出现动画时(X的最大值),点击其他任何地方动画消失,
*或继续向左滑动,xThink=‘0‘,禁止touchMove事件,
*触发end事件,则恢复原状xThink=‘1‘
*/
xThink = window.sessionStorage.getItem("xThink");
var obj = event.target.parentNode;
yesClick = false; //滑动时,点击li效果失效
//判断是否选中的是li
if (obj.className.indexOf("an-slide-li") != -1) { //&&xThink == ‘1‘
moveX = event.targetTouches[0].pageX; //获取移动后的最终X值
moveY = event.targetTouches[0].pageY; //获取移动后的最终Y值
X = (moveX - initX) / 100; //变化中的X值;
Y = (moveY - initY) / 100; //变化中的Y值;
//判断x轴是否可以滑动
if (xSilde) {
//如果X轴的变化值大于等于0,WebkitTransform = 0;不进行动画效果,否则,执行
if (X >= 0 || xThink == ‘0‘) {
obj.style.WebkitTransform = "translateX(" + 0 + "rem)";
} else if (X < 0) {
event.preventDefault(); //禁止默认滚动事件
var l = Math.abs(X); //取绝对值X
obj.style.WebkitTransform = "translateX(" + -l + "rem)"; //实现滑动效果,删除按钮出现
//判断是否已经超出设置值
if (l > sildeWidth) {
l = sildeWidth;
obj.style.WebkitTransform = "translateX(" + -l + "rem)";
}
}
//判断X值如果大于15 , 区分左右滑动还是上下滑动
if (Math.abs(X) >= 0.15) {
Y = 0; //禁止上下滑动
ySilde = false; //禁止上下滑动
//yThink = false;//禁止上下滑动
event.preventDefault(); //禁止上下滑动
}
}
/*如果出现向左滑动动画,则在手指离开屏幕之前,不可以上下滚动*/
if (ySilde) { //判断y轴是否可以滑动
if (Math.abs(Y) >= 0.15) {
X = 0; //禁止 左右 滑动
obj.style.WebkitTransform = "translateX(" + 0 + "rem)";
xSilde = false; //禁止 左右 滑动
//event.preventDefault();
}
}
}
}
/*手指离开屏幕方法*/
function touchEnd(event) {
event.preventDefault();
var obj = event.target.parentNode;
xSilde = true;
ySilde = true;
if (obj.className.indexOf("an-slide-li") != -1) {
objX = (obj.style.WebkitTransform.replace(/translateX\\(/g, "").replace(/rem\\)/g, "")) * 1;
//放开手时,判断objX最终值,如果大于按钮中间值,则使按钮恢复隐藏状态;反之;
if (objX > -(sildeWidth / 4)) {
obj.style.WebkitTransform = "translateX(" + 0 + "rem)";
objX = 0;
xThink = ‘1‘;
window.sessionStorage.setItem("xThink", xThink);
window.sessionStorage.setItem("anObjX", objX);
//yesClick = true;
} else {
obj.style.WebkitTransform = "translateX(" + -sildeWidth + "rem)";
objX = -sildeWidth;
window.sessionStorage.setItem("anObjX", objX);
yesClick = false; //禁止点击li事件
xThink = ‘0‘;
window.sessionStorage.setItem("xThink", xThink);
}
}
sildeWidth = 0;
//点击li后需要执行的方法
if (event.target.className === "an-z-index-up" && yesClick) {
// scope.goClick();
window.sessionStorage.setItem("anObjX", ‘0‘);
}
}
}
3.style / css
* { padding:0; margin:0; list-style:none; } body { background:#FFFFF0; } header { width:100%; background:#00CED1; border-bottom:1px solid #ccc; position:fixed; top:0; left:0; z-index:1; } header h2 { text-align:center; line-height:4rem; font-size:16px; color:#fff } .list { padding-top:4.1rem; } .list-ul { top:5px; overflow:hidden; } .list-li { height:3.8rem; /*width:100%; */ line-height:3.8rem; border-bottom:1px solid #dcd6d6; position:relative; padding:0 8px; color:#666; background:#FFFFF0; -webkit-transform:translateX(0px); transition:transform 0.2s; -webkit-transition:transform 0.2s; /*3d加速*/ webkit-transform:translate3d(0,0,0); -moz-transform:translate3d(0,0,0); -ms-transform:translate3d(0,0,0); -o-transform:translate3d(0,0,0); transform:translate3d(0,0,0); } .z-index-up { z-index:9999; width:100%; height:3.8rem; padding:0; position:absolute; /* background:red; */ } /* 头像 */ .list-li .list-img { float:left; width:15%; padding-top:.49rem; } .list-li .list-img div { width:2.8rem; height:2.8rem; padding-left:.2rem; /*background:url("../img/Tulips.jpg") no-repeat center; */ /*border:0; */ /*border-radius:50%; */ } .list-li .list-img div img { width:2.8rem; height:2.8rem; border-radius:50%; } /* 文字内容 */ .list-li .list-contant { float:left; width:65%; padding-top:0.25rem; padding-left:.4rem; } .list-li .list-contant .list-contant-title { height:1.7rem; line-height:2rem; } .list-li .list-contant .list-contant-title label { font-size:14px; font-weight:bold; } .list-li .list-contant .list-contant-text { height:1.7rem; line-height:1.3rem; } .list-li .list-contant .list-contant-text label { font-size:12px; } /* 时间 消息提醒 */ .list-time-message { float:left; width:16%; padding-top:0.25rem; padding-left:.46rem; } .list-time-message .list-time { float:left; height:1.7rem; width:100%; line-height:1.7rem; font-size:10px; text-align:right; } .list-time-message .list-time span { padding-right:.8rem; } .list-time-message .list-message { float:left; /* height:1.7rem; line-height:1.7rem; */ } /* 按钮 */ .btn { position:absolute; top:0; right:-80px; text-align:center; background:#FF0000; border-bottom:1px solid #FF0000; color:#fff; width:80px; height:3.8rem; line-height:3.8rem; } .btn div { /*padding-right:.6rem; */ } /* 提示框 */ .contant-prompt { width:100%; text-align:center; z-index:1; opacity:0.9; display:none; } .contant-prompt .prompt { position:absolute; bottom:0; left:0; right:0; height:2rem; text-align:center; font-size:12px; line-height:2rem; background:#777171; /* border-radius:8%; */ } .contant-prompt .prompt div { color:#fff; font-weight:700; padding-left:.3rem; padding-right:.3rem; }
最后,欢迎IT同事好友朋友们,互相指教,进步!
以上是关于js高仿QQ消息列表左滑功能的主要内容,如果未能解决你的问题,请参考以下文章
Android高级控件——自定义ListView高仿一个QQ可拖拽列表的实现