Heim  >  Artikel  >  Web-Frontend  >  js仿QQ中对联系人向左滑动、滑出删除按钮的操作_javascript技巧

js仿QQ中对联系人向左滑动、滑出删除按钮的操作_javascript技巧

WBOY
WBOYOriginal
2016-05-16 15:06:201609Durchsuche

本文实例为大家分享实现类似QQ中对联系人的操作:向左滑动,滑出删除按钮。滑动超过一半时松开则自动滑到底,不到一半时松开则返回原处。

纯js实现
使用了h5的touchmove等事件,以及用js动态改变css3的translate属性来达到动画效果:

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" id="viewport" content="width=device-width, initial-scale=1">
 <title>html5向左滑动删除特效</title>
 <style>
 * {
  padding: 0;
  margin: 0;
  list-style: none;
 }
 
 header {
  background: #f7483b;
  border-bottom: 1px solid #ccc
 }
 
 header h2 {
  text-align: center;
  line-height: 54px;
  font-size: 16px;
  color: #fff
 }
 
 .list-ul {
  overflow: hidden
 }
 
 .list-li {
  line-height: 60px;
  border-bottom: 1px solid #fcfcfc;
  position: relative;
  padding: 0 12px;
  color: #666;
  background: #f2f2f2;
  -webkit-transform: translateX(0px);
 }
 
 .btn {
  position: absolute;
  top: 0;
  right: -80px;
  text-align: center;
  background: #ffcb20;
  color: #fff;
  width: 80px
 }
 </style>
 <script>
 /*
  * 描述:html5苹果手机向左滑动删除特效
  */
 window.addEventListener('load', function() {
  var initX; //触摸位置
  var moveX; //滑动时的位置
  var X = 0; //移动距离
  var objX = 0; //目标对象位置
  window.addEventListener('touchstart', function(event) {
   event.preventDefault();
   var obj = event.target.parentNode;
   if (obj.className == "list-li") {
    initX = event.targetTouches[0].pageX;
    objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
   }
   if (objX == 0) {
    window.addEventListener('touchmove', function(event) {
     event.preventDefault();
     var obj = event.target.parentNode;
     if (obj.className == "list-li") {
      moveX = event.targetTouches[0].pageX;
      X = moveX - initX;
      if (X >= 0) {
       obj.style.WebkitTransform = "translateX(" + 0 + "px)";
      } else if (X < 0) {
       var l = Math.abs(X);
       obj.style.WebkitTransform = "translateX(" + -l + "px)";
       if (l > 80) {
        l = 80;
        obj.style.WebkitTransform = "translateX(" + -l + "px)";
       }
      }
     }
    });
   } else if (objX < 0) {
    window.addEventListener('touchmove', function(event) {
     event.preventDefault();
     var obj = event.target.parentNode;
     if (obj.className == "list-li") {
      moveX = event.targetTouches[0].pageX;
      X = moveX - initX;
      if (X >= 0) {
       var r = -80 + Math.abs(X);
       obj.style.WebkitTransform = "translateX(" + r + "px)";
       if (r > 0) {
        r = 0;
        obj.style.WebkitTransform = "translateX(" + r + "px)";
       }
      } else { //向左滑动
       obj.style.WebkitTransform = "translateX(" + -80 + "px)";
      }
     }
    });
   }

  })
  window.addEventListener('touchend', function(event) {
   event.preventDefault();
   var obj = event.target.parentNode;
   if (obj.className == "list-li") {
    objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
    if (objX > -40) {
     obj.style.WebkitTransform = "translateX(" + 0 + "px)";
     objX = 0;
    } else {
     obj.style.WebkitTransform = "translateX(" + -80 + "px)";
     objX = -80;
    }
   }
  })
 })
 </script>
</head>

<body>
 <header>
  <h2>消息列表</h2>
 </header>
 <section class="list">
  <ul class="list-ul">
   <li id="li" class="list-li">
    <div class="con">
     你的快递到了,请到楼下签收
    </div>
    <div class="btn">删除</div>
   </li>
   <li class="list-li">
    <div class="con">
     哇,你在干嘛,快点来啊就等你了
    </div>
    <div class="btn">删除</div>
   </li>
  </ul>
 </section>
</body>

</html>

做成zepto插件
实际项目中,我们可能有很多个地方会用到这个功能。现在我们将这个功能做成zepto插件,方便后面使用。

这个插件,我们仅实现这个功能,然后传入参数(删除按钮的样式名),让程序在js中计算所需要滑动的距离,方便复用。

zepto.touchWipe.js

/**
 * zepto插件:向左滑动删除动效
 * 使用方法:$('.itemWipe').touchWipe({itemDelete: '.item-delete'});
 * 参数:itemDelete 删除按钮的样式名
 */
;
(function($) {
 $.fn.touchWipe = function(option) {
  var defaults = {
   itemDelete: '.item-delete', //删除元素
  };
  var opts = $.extend({}, defaults, option); //配置选项

  var delWidth = $(opts.itemDelete).width();

  var initX; //触摸位置
  var moveX; //滑动时的位置
  var X = 0; //移动距离
  var objX = 0; //目标对象位置
  $(this).on('touchstart', function(event) {
   event.preventDefault();
   var obj = this;
   initX = event.targetTouches[0].pageX;
   objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
   if (objX == 0) {
    $(this).on('touchmove', function(event) {
     event.preventDefault();
     var obj = this;
     moveX = event.targetTouches[0].pageX;
     X = moveX - initX;
     if (X >= 0) {
      obj.style.WebkitTransform = "translateX(" + 0 + "px)";
     } else if (X < 0) {
      var l = Math.abs(X);
      obj.style.WebkitTransform = "translateX(" + -l + "px)";
      if (l > delWidth) {
       l = delWidth;
       obj.style.WebkitTransform = "translateX(" + -l + "px)";
      }
     }
    });
   } else if (objX < 0) {
    $(this).on('touchmove', function(event) {
     event.preventDefault();
     var obj = this;
     moveX = event.targetTouches[0].pageX;
     X = moveX - initX;
     if (X >= 0) {
      var r = -delWidth + Math.abs(X);
      obj.style.WebkitTransform = "translateX(" + r + "px)";
      if (r > 0) {
       r = 0;
       obj.style.WebkitTransform = "translateX(" + r + "px)";
      }
     } else { //向左滑动
      obj.style.WebkitTransform = "translateX(" + -delWidth + "px)";
     }
    });
   }

  })
  $(this).on('touchend', function(event) {
   event.preventDefault();
   var obj = this;
   objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
   if (objX > -delWidth / 2) {
    obj.style.transition = "all 0.2s";
    obj.style.WebkitTransform = "translateX(" + 0 + "px)";
    obj.style.transition = "all 0";
    objX = 0;
   } else {
    obj.style.transition = "all 0.2s";
    obj.style.WebkitTransform = "translateX(" + -delWidth + "px)";
    obj.style.transition = "all 0";
    objX = -delWidth;
   }
  })

  //链式返回
  return this;
 };

})(Zepto);

touchWipe.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" id="viewport" content="width=device-width, initial-scale=1">
<title>html5向左滑动删除特效</title>

<style>
  *{ padding:0; margin:0; list-style: none;}
  header{ background: #f7483b; border-bottom: 1px solid #ccc}
  header h2{ text-align: center; line-height: 54px; font-size: 16px; color: #fff}
  .list-ul{ overflow: hidden}
  .list-li{ line-height: 60px; border-bottom: 1px solid #fcfcfc; position:relative;padding: 0 12px; color: #666;
    background: #f2f2f2;
    -webkit-transform: translateX(0px);
  }
  .btn{ position: absolute; top: 0; right: -80px; text-align: center; background: #ffcb20; color: #fff; width: 80px}
</style>

</head>
<body>
<header>
  <h2>消息列表</h2>
</header>
<section class="list">
  <ul class="list-ul">
    <li id="li" class="list-li">
      <div class="con">
        你的快递到了,请到楼下签收
      </div>
      <div class="btn">删除</div>
    </li>
    <li class="list-li">
      <div class="con">
        哇,你在干嘛,快点来啊就等你了
      </div>
      <div class="btn">删除</div>
    </li>
  </ul>
</section>

<p>X: <span id="X"></span></p>
<p>objX: <span id="objX"></span></p>
<p>initX: <span id="initX"></span></p>
<p>moveX: <span id="moveX"></span></p>

<script type="text/javascript" src="http://apps.bdimg.com/libs/zepto/1.1.4/zepto.min.js"></script>
<script type="text/javascript" src="zepto.touchWipe.js"></script>
<script type="text/javascript">
  $(function() {
  $('.list-li').touchWipe({itemDelete: '.btn'});
  });

</script>
</body>
</html>

效果:

 

实际项目中的应用效果:

消除BUG
到上面一步,基本实现了我们所需要的功能。但是有几个问题

1. 右边的删除按钮点击失灵,因为span无法冒泡到大按钮上;

2. 非常严重的问题,我们给div添加了touchmove事件同时用preventDefault()屏蔽了原始的浏览器事件,导致上下滑动div的时候 页面无法滚动了!

 第一个问题比较容易解决,我们把span直接去掉,将“删除”写到css中的:before里,像这样:

.itemWipe .item-delete:before {
  content: '删除';
  color: #fff;
}

对于第二个问题,网上说用iscroll来解决。我们这里参考手机QQ中对联系人的滑动操作。

大致原理:在滑动最开始的时候,判断是Y轴的移动多 还是 X轴的移动多。 如果是X轴移动大,则判断为滑动删除操作,我们再使用preventDefault();

以上就是本文的全部内容,希望对大家的学习有所帮助。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn