| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- <template>
- <div class="nut-hor-scroll" rel="wrapper">
- <div class="nut-hor-list" ref="list">
- <slot name="list"></slot>
- <div class="nut-hor-control" v-if="$slots.more && isShowLoadMore">
- <slot name="more"></slot>
- </div>
- <slot name="arrow" v-if="$slots.arrow"></slot>
- </div>
- </div>
- </template>
- <script>
- export default {
- name:'nut-hor-scroll',
- props: {
- stretch: {
- type: Number,
- default: 40
- }
- },
- data() {
- return {
- touchParams: {
- startX: 0,
- endX: 0,
- startY: 0,
- endY: 0,
- startTime: 0,
- endTime: 0
- },
- transformX: 0,
- scrollDistance: 0,
- timer: null,
- isShowLoadMore: false,
- isFirstShow: false
- }
- },
- methods: {
- isShow() {
- let wrapH = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
- let listH = this.$refs.list.offsetWidth;
- if (wrapH <= listH) {
- this.isShowLoadMore = true;
- } else {
- this.isShowLoadMore = false;
- }
- },
-
- setTransform(translateX = 0, type, time = 500, unit = 'px') {
- this.scrollDistance = translateX;
- translateX = translateX + unit;
- if (type === 'end') {
- this.$refs.list.style.webkitTransition = `transform ${time}ms cubic-bezier(0.19, 1, 0.22, 1)`;
- } else {
- this.$refs.list.style.webkitTransition = '';
- }
- this.$refs.list.style.webkitTransform = `translate3d(${translateX}, 0, 0)`;
-
- },
- setMove(move, type, time) {
- let updateMove = move + this.transformX;
- let w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
- let offsetWidth = this.$refs.list.offsetWidth;
- if (type === 'end') {
- if (updateMove > 0) {
- updateMove = 0;
- } else if (updateMove < -offsetWidth + w) {
- if (-offsetWidth + w <= 0) {
- updateMove = -offsetWidth + w;
- } else {
- updateMove = 0;
- }
- }
- this.setTransform(updateMove, type, time)
- } else {
- let maxMove = -offsetWidth + w;
- if (updateMove > 0 && updateMove > this.stretch) {
- updateMove = this.stretch;
- } else if (updateMove < maxMove - this.stretch) {
- if (maxMove <= 0) {
- updateMove = maxMove - this.stretch;
- } else {
- updateMove = updateMove < -this.stretch ? -this.stretch : updateMove;
- }
- }
- this.setTransform(updateMove, null, null);
- }
- },
-
- touchStart(event) {
- // event.preventDefault();
- let changedTouches = event.changedTouches[0];
- this.touchParams.startX = changedTouches.pageX;
- this.touchParams.startY = changedTouches.pageY;
- this.touchParams.startTime = event.timestamp || Date.now();
- this.transformX = this.scrollDistance;
- },
- touchEvent(changedTouches, callback) {
- this.touchParams.lastX = changedTouches.pageX;
- this.touchParams.lastY = changedTouches.pageY;
- let moveY = this.touchParams.lastY - this.touchParams.startY;
- let move = this.touchParams.lastX - this.touchParams.startX;
- if (!(Math.abs(move) > 20 && Math.abs(move) > Math.abs(moveY))) {
- return false;
- } else {
- let w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
- let maxMove = -this.$refs.list.offsetWidth + w;
- callback && callback(move, maxMove, moveY);
- }
- },
- touchMove(event) {
- event.preventDefault();
- let changedTouches = event.changedTouches[0];
- this.touchParams.lastTime = event.timestamp || Date.now();
- let moveTime = this.touchParams.lastTime - this.touchParams.startTime;
- this.touchEvent(changedTouches, (move, maxMove, moveY) => {
- if (move > 0 && this.isFirstShow) {
- this.isFirstShow = false;
- }
- this.setMove(move);
- });
- },
- touchEnd(event) {
- let changedTouches = event.changedTouches[0];
- this.touchParams.lastTime = event.timestamp || Date.now();
- let moveTime = this.touchParams.lastTime - this.touchParams.startTime;
- this.touchEvent(changedTouches, (move, maxMove) => {
- //if (moveTime <= 300) {
- if (Math.abs(move) > 100) {
- move = move * 2;
- }
- // 释放跳转之类
- if (move < 0 && (move + this.transformX) < maxMove - 20 && this.isFirstShow) {
- this.$emit('jump');
- }
- if (!this.isFirstShow && move < 0 && move + this.transformX < maxMove && this.$slots.more) {
- this.isFirstShow = true;
- //move = maxMove - this.transformX;
- }
- if (moveTime <= 300 ) {
- moveTime = moveTime + 500;
- this.setMove(move, 'end', moveTime);
- } else {
- this.setMove(move, 'end');
- }
- });
- }
- },
- mounted() {
- this.$nextTick(() => {
- this.isShow();
- // 监听
- this.$el.addEventListener('touchstart', this.touchStart);
- this.$el.addEventListener('touchmove', this.touchMove);
- this.$el.addEventListener('touchend', this.touchEnd);
- });
- },
- beforeDestroy() {
- // 移除监听
- this.$el.removeEventListener('touchstart', this.touchStart);
- this.$el.removeEventListener('touchmove', this.touchMove);
- this.$el.removeEventListener('touchend', this.touchEnd);
- clearTimeout(this.timer);
- }
- }
- </script>
|