backup.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <template>
  2. <div class="nut-leftslip">
  3. <div class="nut-leftslip-item" ref="slipItem" :style="deleteSlider">
  4. <div class="nut-leftslip-item-main" @touchstart="touchStart($event)" @touchmove="touchMove($event)"
  5. @touchend="touchEnd($event)">
  6. <slot name="slip-main"></slot>
  7. </div>
  8. <div class="nut-leftslip-item-btn">
  9. <!-- <a @click.prevent="onlyDelClick($event)">删除</a> -->
  10. <slot name="slipbtns">
  11. <a class="nut-delet-btn" @click.prevent="onlyDelClick($event)" v-if="onlyDelBtn">删除</a>
  12. </slot>
  13. </div>
  14. </div>
  15. </div>
  16. </template>
  17. <script>
  18. export default {
  19. name: 'nut-leftslip',
  20. props: {
  21. onlyDelBtn: {
  22. type: Boolean,
  23. default: false
  24. },
  25. btnSlipDel: {
  26. type: Boolean,
  27. default: false
  28. }
  29. },
  30. data() {
  31. return {
  32. startX: 0,
  33. startY: 0,
  34. moveX: 0,
  35. moveY: 0,
  36. left: 0,
  37. buttonWidth: 0,
  38. disX: 0, //移动距离
  39. deleteSlider: '', //滑动时的效果,使用v-bind:style="deleteSlider"
  40. delBtnStyle: '' //单个删除键拖拽删除效果
  41. };
  42. },
  43. mounted() {
  44. this.$nextTick(() => {
  45. if (this.onlyDelBtn) {
  46. return;
  47. }
  48. for (var slot of this.$slots.slipbtns) {
  49. this.buttonWidth = this.buttonWidth + slot.elm.offsetWidth;
  50. }
  51. });
  52. window.addEventListener('scroll', this.handleScroll, true);
  53. },
  54. beforeDestroy() {
  55. // 移除监听
  56. window.removeEventListener('scroll', this.handleScroll, true);
  57. },
  58. methods: {
  59. handleScroll() {
  60. if (this.disX) {
  61. this.restSlide();
  62. }
  63. },
  64. handleClick() {
  65. this.restSlide();
  66. },
  67. onlyDelClick() {
  68. //一键删除模式点击删除
  69. this.$emit('oneDelete', this.$refs.slipItem);
  70. this.restSlide();
  71. },
  72. touchStart(e) {
  73. this.restSlide();
  74. e = e || event;
  75. //等于1时表示此时有只有一只手指在触摸屏幕
  76. if (e.touches.length == 1) {
  77. this.startX = e.touches[0].clientX;
  78. this.startY = e.touches[0].clientY;
  79. }
  80. },
  81. touchMove(e) {
  82. e = e || event;
  83. //获取当前滑动对象
  84. let parentElement = e.currentTarget.parentElement;
  85. //获取删除按钮的宽度,此宽度为滑块左滑的最大距离
  86. let itemWd = this.$refs.slipItem.offsetWidth;
  87. let wd = this.onlyDelBtn ? 40 : this.buttonWidth;
  88. if (e.touches.length == 1) {
  89. // 滑动时距离浏览器左侧实时距离
  90. this.moveY = e.touches[0].clientY;
  91. this.moveX = e.touches[0].clientX;
  92. if (Math.abs(this.moveY - this.startY) < 40) {
  93. //起始位置减去 实时的滑动的距离,得到手指实时偏移距离
  94. this.disX = this.startX - this.moveX;
  95. // console.log(this.disX);
  96. if (this.onlyDelBtn) {
  97. //单一删除,左滑一键删除
  98. if (this.disX < 0 || this.disX == 0) {
  99. this.deleteSlider = 'transform:translateX(0px)';
  100. }
  101. this.deleteSlider = 'transform:translateX(-' + this.disX + 'px)';
  102. this.delBtnStyle = 'width:' + this.disX + 'px';
  103. parentElement.dataset.type = 1; //设置滑动展开隐藏标志位,左滑展开为1,右滑或复位为0
  104. } else {
  105. // 如果是向右滑动或者不滑动,不改变滑块的位置
  106. if (this.disX < wd / 4 || this.disX == 0) {
  107. this.deleteSlider = 'transform:translateX(0px)';
  108. parentElement.dataset.type = 0;
  109. } else if (this.disX > wd / 4) {
  110. parentElement.dataset.type = 1;
  111. this.deleteSlider = 'transform:translateX(-' + this.disX + 'px)';
  112. // 最大也只能等于删除按钮宽度
  113. if (this.disX >= wd) {
  114. // parentElement.dataset.type = 1;
  115. if (wd >= itemWd) {
  116. this.deleteSlider = 'transform:translateX(-' + (itemWd - 40) + 'px)';
  117. } else {
  118. this.deleteSlider = 'transform:translateX(-' + wd + 'px)';
  119. }
  120. }
  121. }
  122. }
  123. }
  124. }
  125. },
  126. touchEnd(e) {
  127. e = e || event;
  128. let parentElement = e.currentTarget.parentElement;
  129. let itemWd = this.$refs.slipItem.offsetWidth;
  130. let wd = this.onlyDelBtn ? 40 : this.buttonWidth;
  131. if (e.changedTouches.length == 1) {
  132. let endY = e.changedTouches[0].clientY;
  133. if (Math.abs(this.startY - endY) < 40) {
  134. let endX = e.changedTouches[0].clientX;
  135. this.disX = this.startX - endX;
  136. // console.log('touchEndthis.disX:', this.disX);
  137. if (this.onlyDelBtn) {
  138. //单一按钮,左滑一键删除
  139. if (this.disX < 0 || this.disX == 0) {
  140. this.deleteSlider = 'transform:translateX(0px)';
  141. parentElement.dataset.type = 0;
  142. } else if (this.disX < itemWd - 20) {
  143. parentElement.dataset.type = 1;
  144. this.deleteSlider = 'transform:translateX(-50px);';
  145. this.delBtnStyle = ' width:0px;';
  146. } else {
  147. this.deleteSlider = 'transform:translateX(-' + itemWd + 'px);';
  148. this.delBtnStyle = ' width:' + itemWd + 'px;';
  149. parentElement.dataset.type = 1;
  150. this.onlyDelClick();
  151. }
  152. } else {
  153. //如果距离小于删除按钮的四分之一,强行回到起点
  154. if (this.disX < wd / 4) {
  155. parentElement.dataset.type = 0;
  156. this.deleteSlider = 'transform:translateX(0px)';
  157. } else {
  158. //大于一半 滑动到最大值
  159. parentElement.dataset.type = 1;
  160. if (wd >= itemWd) {
  161. //按钮数不可超出整行宽度
  162. this.deleteSlider = 'transform:translateX(-' + (itemWd - 40) + 'px)';
  163. } else {
  164. this.deleteSlider = 'transform:translateX(-' + wd + 'px)';
  165. }
  166. }
  167. }
  168. // console.log('touchEnd:dataset', parentElement.dataset.type);
  169. }
  170. }
  171. },
  172. restSlide() {
  173. let listItems = document.querySelectorAll('.nut-leftslip-item');
  174. // 复位
  175. for (let i = 0; i < listItems.length; i++) {
  176. listItems[i].style = 'transform:translateX(0' + 'px)';
  177. listItems[i].dataset.type = 0; //是否展开标志位默认0,左滑展开为1,右滑隐藏为0
  178. }
  179. if (this.onlyDelBtn) {
  180. let delBtns = document.querySelectorAll('.delbtn .trans');
  181. for (let j = 0; j < delBtns.length; j++) {
  182. delBtns[j].style = '';
  183. }
  184. }
  185. }
  186. }
  187. };
  188. </script>