mpother.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. const MIN_DISTANCE = 10;
  2. export default {
  3. data() {
  4. return {
  5. uniShow: false,
  6. left: 0,
  7. buttonShow: 'none',
  8. ani: false,
  9. moveLeft:''
  10. }
  11. },
  12. watch: {
  13. show(newVal) {
  14. if (this.autoClose) return
  15. this.openState(newVal)
  16. },
  17. left(){
  18. this.moveLeft = `translateX(${this.left}px)`
  19. },
  20. buttonShow(newVal){
  21. if (this.autoClose) return
  22. this.openState(newVal)
  23. },
  24. leftOptions() {
  25. this.init()
  26. },
  27. rightOptions() {
  28. this.init()
  29. }
  30. },
  31. mounted() {
  32. this.swipeaction = this.getSwipeAction()
  33. // this.position = {}
  34. if (this.swipeaction.children !== undefined) {
  35. this.swipeaction.children.push(this)
  36. }
  37. this.init()
  38. },
  39. // beforeDestoy() {
  40. // this.swipeaction.children.forEach((item, index) => {
  41. // if (item === this) {
  42. // this.swipeaction.children.splice(index, 1)
  43. // }
  44. // })
  45. // },
  46. methods: {
  47. init(){
  48. clearTimeout(this.timer)
  49. this.timer = setTimeout(() => {
  50. this.getSelectorQuery()
  51. }, 100)
  52. // 移动距离
  53. this.left = 0
  54. this.x = 0
  55. },
  56. closeSwipe(e) {
  57. if (!this.autoClose) return
  58. this.swipeaction.closeOther(this)
  59. },
  60. appTouchStart(e) {
  61. const {
  62. clientX
  63. } = e.changedTouches[0]
  64. this.clientX = clientX
  65. this.timestamp = new Date().getTime()
  66. },
  67. appTouchEnd(e, index, item, position) {
  68. const {
  69. clientX
  70. } = e.changedTouches[0]
  71. // fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
  72. let diff = Math.abs(this.clientX - clientX)
  73. let time = (new Date().getTime()) - this.timestamp
  74. if (diff < 40 && time < 300) {
  75. this.$emit('click', {
  76. content: item,
  77. index,
  78. position
  79. })
  80. }
  81. },
  82. touchstart(e) {
  83. if (this.disabled) return
  84. this.ani = false
  85. this.x = this.left || 0
  86. this.stopTouchStart(e)
  87. this.autoClose && this.closeSwipe()
  88. },
  89. touchmove(e) {
  90. if (this.disabled) return
  91. // 是否可以滑动页面
  92. this.stopTouchMove(e);
  93. if (this.direction !== 'horizontal') {
  94. return;
  95. }
  96. this.move(this.x + this.deltaX)
  97. },
  98. touchend() {
  99. if (this.disabled) return
  100. this.moveDirection(this.left)
  101. },
  102. /**
  103. * 设置移动距离
  104. * @param {Object} value
  105. */
  106. move(value) {
  107. value = value || 0
  108. const leftWidth = this.leftWidth
  109. const rightWidth = this.rightWidth
  110. // 获取可滑动范围
  111. this.left = this.range(value, -rightWidth, leftWidth);
  112. },
  113. /**
  114. * 获取范围
  115. * @param {Object} num
  116. * @param {Object} min
  117. * @param {Object} max
  118. */
  119. range(num, min, max) {
  120. return Math.min(Math.max(num, min), max);
  121. },
  122. /**
  123. * 移动方向判断
  124. * @param {Object} left
  125. * @param {Object} value
  126. */
  127. moveDirection(left) {
  128. const threshold = this.threshold
  129. const isopen = this.isopen || 'none'
  130. const leftWidth = this.leftWidth
  131. const rightWidth = this.rightWidth
  132. if (this.deltaX === 0) {
  133. this.openState('none')
  134. return
  135. }
  136. if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 && rightWidth +
  137. left < threshold)) {
  138. // right
  139. this.openState('right')
  140. } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
  141. leftWidth - left < threshold)) {
  142. // left
  143. this.openState('left')
  144. } else {
  145. // default
  146. this.openState('none')
  147. }
  148. },
  149. /**
  150. * 开启状态
  151. * @param {Boolean} type
  152. */
  153. openState(type) {
  154. const leftWidth = this.leftWidth
  155. const rightWidth = this.rightWidth
  156. let left = ''
  157. this.isopen = this.isopen ? this.isopen : 'none'
  158. switch (type) {
  159. case "left":
  160. left = leftWidth
  161. break
  162. case "right":
  163. left = -rightWidth
  164. break
  165. default:
  166. left = 0
  167. }
  168. if (this.isopen !== type) {
  169. this.throttle = true
  170. this.$emit('change', type)
  171. }
  172. this.isopen = type
  173. // 添加动画类
  174. this.ani = true
  175. this.$nextTick(() => {
  176. this.move(left)
  177. })
  178. // 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
  179. },
  180. close() {
  181. this.openState('none')
  182. },
  183. getDirection(x, y) {
  184. if (x > y && x > MIN_DISTANCE) {
  185. return 'horizontal';
  186. }
  187. if (y > x && y > MIN_DISTANCE) {
  188. return 'vertical';
  189. }
  190. return '';
  191. },
  192. /**
  193. * 重置滑动状态
  194. * @param {Object} event
  195. */
  196. resetTouchStatus() {
  197. this.direction = '';
  198. this.deltaX = 0;
  199. this.deltaY = 0;
  200. this.offsetX = 0;
  201. this.offsetY = 0;
  202. },
  203. /**
  204. * 设置滑动开始位置
  205. * @param {Object} event
  206. */
  207. stopTouchStart(event) {
  208. this.resetTouchStatus();
  209. const touch = event.touches[0];
  210. this.startX = touch.clientX;
  211. this.startY = touch.clientY;
  212. },
  213. /**
  214. * 滑动中,是否禁止打开
  215. * @param {Object} event
  216. */
  217. stopTouchMove(event) {
  218. const touch = event.touches[0];
  219. this.deltaX = touch.clientX - this.startX;
  220. this.deltaY = touch.clientY - this.startY;
  221. this.offsetX = Math.abs(this.deltaX);
  222. this.offsetY = Math.abs(this.deltaY);
  223. this.direction = this.direction || this.getDirection(this.offsetX, this.offsetY);
  224. },
  225. getSelectorQuery() {
  226. const views = uni.createSelectorQuery().in(this)
  227. views
  228. .selectAll('.uni-swipe_button-group')
  229. .boundingClientRect(data => {
  230. let show = 'none'
  231. if (this.autoClose) {
  232. show = 'none'
  233. } else {
  234. show = this.show
  235. }
  236. this.leftWidth = data[0].width || 0
  237. this.rightWidth = data[1].width || 0
  238. this.buttonShow = show
  239. })
  240. .exec()
  241. }
  242. }
  243. }