mpother.js 5.3 KB

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