Skip to content

Commit 893e8ec

Browse files
author
chenxuan
committedDec 17, 2017
☀️ 添加对移动端touch事件滚动列表支持 npm 1.0.4
·
v1.1.12v1.0.14
1 parent e7b0352 commit 893e8ec

File tree

8 files changed

+304
-36
lines changed

8 files changed

+304
-36
lines changed
 

‎README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
<a href="https://lets-blade.com"><img src="https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1513438288&di=7501d9cbb876dbf8e189d846e72dc1f0&src=http://easyread.ph.126.net/e09BC9VNjw0fmSDrvpjVog==/7916749801802782271.jpg" width="550"/></a>
1010
</p>
1111

12+
13+
## Browser support(mobile.pc)
14+
> 支持移动端touch事件滚动循环列表
15+
1216
## Demo
1317

1418
[https://github.com/chenxuan0000/vue-seamless-scroll/index.html](https://chenxuan0000.github.io/vue-seamless-scroll/)

‎dist/vue-seamless-scroll.js

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ exports.default = {
311311
data: function data() {
312312
return {
313313
yPos: 0,
314+
delay: 0,
314315
reqFrame: null
315316
};
316317
},
@@ -327,7 +328,7 @@ exports.default = {
327328
},
328329
computed: {
329330
pos: function pos() {
330-
return { transform: 'translate(0,' + this.yPos + 'px)' };
331+
return { transform: 'translate(0,' + this.yPos + 'px)', transition: 'all ease-in ' + this.delay + 'ms' };
331332
},
332333
defaultOption: function defaultOption() {
333334
return {
@@ -347,6 +348,58 @@ exports.default = {
347348
}
348349
},
349350
methods: {
351+
touchStart: function touchStart(e) {
352+
var _this = this;
353+
354+
if (!this.options.openWatch) return;
355+
var timer = void 0;
356+
var touch = e.targetTouches[0];
357+
this.startPos = {
358+
x: touch.pageX,
359+
y: touch.pageY
360+
};
361+
this.startPosY = this.yPos;
362+
if (!!this.options.singleHeight) {
363+
if (timer) clearTimeout(timer);
364+
timer = setTimeout(function () {
365+
cancelAnimationFrame(_this.reqFrame);
366+
}, this.options.waitTime + 20);
367+
} else {
368+
cancelAnimationFrame(this.reqFrame);
369+
}
370+
},
371+
touchMove: function touchMove(e) {
372+
if (!this.options.openWatch || e.targetTouches.length > 1 || e.scale && e.scale !== 1) return;
373+
var touch = e.targetTouches[0];
374+
this.endPos = {
375+
x: touch.pageX - this.startPos.x,
376+
y: touch.pageY - this.startPos.y
377+
};
378+
var direction = Math.abs(this.endPos.x) < Math.abs(this.endPos.y) ? 1 : 0;
379+
if (direction === 1) {
380+
event.preventDefault();
381+
this.yPos = this.startPosY + this.endPos.y;
382+
}
383+
},
384+
touchEnd: function touchEnd() {
385+
var _this2 = this;
386+
387+
if (!this.options.openWatch) return;
388+
var timer = void 0;
389+
var direction = this.options.direction;
390+
this.delay = 50;
391+
if (direction === 1) {
392+
if (this.yPos > 0) this.yPos = 0;
393+
} else {
394+
var h = this.$refs.wrapper.offsetHeight / 2 * -1;
395+
if (this.yPos < h) this.yPos = h;
396+
}
397+
if (timer) clearTimeout(timer);
398+
timer = setTimeout(function () {
399+
_this2.delay = 0;
400+
_this2._move();
401+
}, this.delay);
402+
},
350403
enter: function enter() {
351404
if (!this.options.openWatch || !!this.options.singleHeight || !this.options.hoverStop || this.moveSwitch) return;
352405
cancelAnimationFrame(this.reqFrame);
@@ -356,38 +409,38 @@ exports.default = {
356409
this._move();
357410
},
358411
_move: function _move() {
359-
var _this = this;
412+
var _this3 = this;
360413

361414
this.reqFrame = requestAnimationFrame(function () {
362415
var timer = void 0;
363-
var h = _this.$refs.wrapper.offsetHeight / 2;
364-
var direction = _this.options.direction;
416+
var h = _this3.$refs.wrapper.offsetHeight / 2;
417+
var direction = _this3.options.direction;
365418
if (direction === 1) {
366-
if (Math.abs(_this.yPos) >= h) _this.yPos = 0;
419+
if (Math.abs(_this3.yPos) >= h) _this3.yPos = 0;
367420
} else {
368-
if (_this.yPos >= 0) _this.yPos = h * -1;
421+
if (_this3.yPos >= 0) _this3.yPos = h * -1;
369422
}
370423
if (direction === 1) {
371-
_this.yPos -= _this.options.step;
424+
_this3.yPos -= _this3.options.step;
372425
} else {
373-
_this.yPos += _this.options.step;
426+
_this3.yPos += _this3.options.step;
374427
}
375-
if (!!_this.options.singleHeight) {
376-
if (Math.abs(_this.yPos) % _this.options.singleHeight === 0) {
428+
if (!!_this3.options.singleHeight) {
429+
if (Math.abs(_this3.yPos) % _this3.options.singleHeight === 0) {
377430
if (timer) clearTimeout(timer);
378431
timer = setTimeout(function () {
379-
_this._move();
380-
}, _this.options.waitTime);
432+
_this3._move();
433+
}, _this3.options.waitTime);
381434
} else {
382-
_this._move();
435+
_this3._move();
383436
}
384437
} else {
385-
_this._move();
438+
_this3._move();
386439
}
387440
});
388441
},
389442
_initMove: function _initMove() {
390-
var _this2 = this;
443+
var _this4 = this;
391444

392445
if (this.moveSwitch) {
393446
cancelAnimationFrame(this.reqFrame);
@@ -396,7 +449,7 @@ exports.default = {
396449
this.$emit('copy-data');
397450
if (this.options.direction !== 1) {
398451
setTimeout(function () {
399-
_this2.yPos = _this2.$refs.wrapper.offsetHeight / 2 * -1;
452+
_this4.yPos = _this4.$refs.wrapper.offsetHeight / 2 * -1;
400453
}, 20);
401454
}
402455
this._move();
@@ -917,7 +970,10 @@ module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c
917970
return _c('div', {
918971
on: {
919972
"mouseenter": _vm.enter,
920-
"mouseleave": _vm.leave
973+
"mouseleave": _vm.leave,
974+
"touchstart": _vm.touchStart,
975+
"touchmove": _vm.touchMove,
976+
"touchend": _vm.touchEnd
921977
}
922978
}, [_c('div', {
923979
ref: "wrapper",

‎dist/vue-seamless-scroll.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples-src/App.vue

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<template>
22
<div id="app">
33
<div class="fixed top-0 w-100 z-1 flex-none flex flex-row items-center pv3 ph4 bg-blue white">
4-
<div class="flex-fill"><a href="https://github.com/chenxuan0000/vue-seamless-scroll"
5-
class="white no-underline underline-hover">vue-seamless-scroll</a></div>
64
<div class="flex-none"><a href="https://github.com/chenxuan0000/vue-seamless-scroll" rel="noopener"
75
target="_blank" title="View on Github">
86
<svg xmlns="http://www.w3.org/2000/svg" fill="white" width="32" height="32" viewBox="0 0 16 16">
97
<path d="M8 .198c-4.418 0-8 3.582-8 8 0 3.535 2.292 6.533 5.47 7.59.4.075.548-.173.548-.384 0-.19-.008-.82-.01-1.49-2.227.485-2.696-.943-2.696-.943-.364-.924-.888-1.17-.888-1.17-.726-.497.055-.486.055-.486.802.056 1.225.824 1.225.824.714 1.223 1.872.87 2.328.665.072-.517.28-.87.508-1.07-1.776-.202-3.644-.888-3.644-3.954 0-.874.313-1.588.824-2.148-.083-.202-.357-1.015.077-2.117 0 0 .672-.215 2.2.82.64-.177 1.323-.266 2.003-.27.68.004 1.365.093 2.004.27 1.527-1.035 2.198-.82 2.198-.82.435 1.102.162 1.916.08 2.117.512.56.822 1.274.822 2.147 0 3.072-1.872 3.748-3.653 3.946.288.248.544.735.544 1.48 0 1.07-.01 1.933-.01 2.196 0 .213.145.462.55.384 3.178-1.06 5.467-4.057 5.467-7.59 0-4.418-3.58-8-8-8z"></path>
108
</svg>
119
</a>
1210
</div>
11+
<div class="flex-none" style="margin-left: 10px;"><a href="https://github.com/chenxuan0000/vue-seamless-scroll"
12+
class="white no-underline underline-hover">vue-seamless-scroll</a></div>
1313
</div>
1414
<p class="pt5 f2" style="text-align: center;">无缝滚动demo</p>
1515
<div class="flex wd800">
@@ -23,7 +23,8 @@
2323
<my-class :data="listData" :class-option="classOption" @copy-data="listData = listData.concat(listData)"
2424
class="warp">
2525
<ul class="item">
26-
<li v-for="item in listData"><span class="title" v-text="item.title"></span><span class="date" v-text="item.date"></span>
26+
<li v-for="item in listData"><span class="title" v-text="item.title"></span><span class="date"
27+
v-text="item.date"></span>
2728
</li>
2829
</ul>
2930
</my-class>
@@ -36,7 +37,8 @@
3637
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;limitMoveNum: 7<br/>
3738
}
3839
</div>
39-
<my-class :data="listData1" :class-option="classOption1" @copy-data="listData1 = listData1.concat(listData1)"
40+
<my-class :data="listData1" :class-option="classOption1"
41+
@copy-data="listData1 = listData1.concat(listData1)"
4042
class="warp">
4143
<ul class="item">
4244
<li v-for="item in listData1"><span class="title" v-text="item.title"></span><span
@@ -53,7 +55,8 @@
5355
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;openWatch: false<br/>
5456
}
5557
</div>
56-
<my-class :data="listData2" :class-option="classOption2" @copy-data="listData2 = listData2.concat(listData2)"
58+
<my-class :data="listData2" :class-option="classOption2"
59+
@copy-data="listData2 = listData2.concat(listData2)"
5760
class="warp">
5861
<ul class="item">
5962
<li v-for="item in listData2"><span class="title" v-text="item.title"></span><span
@@ -70,7 +73,8 @@
7073
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hoverStop: false,<br/>
7174
}
7275
</div>
73-
<my-class :data="listData3" :class-option="classOption3" @copy-data="listData3 = listData3.concat(listData3)"
76+
<my-class :data="listData3" :class-option="classOption3"
77+
@copy-data="listData3 = listData3.concat(listData3)"
7478
class="warp">
7579
<ul class="item">
7680
<li v-for="item in listData3"><span class="title" v-text="item.title"></span><span
@@ -88,10 +92,12 @@
8892
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;waitTime: 1000<br/>
8993
}
9094
</div>
91-
<my-class :data="listData4" :class-option="classOption4" @copy-data="listData4 = listData4.concat(listData4)"
95+
<my-class :data="listData4" :class-option="classOption4"
96+
@copy-data="listData4 = listData4.concat(listData4)"
9297
class="warp">
9398
<ul class="item">
94-
<li v-for="item in listData4"><span class="title" v-text="item.title"></span><span class="date" v-text="item.date"></span>
99+
<li v-for="item in listData4"><span class="title" v-text="item.title"></span><span class="date"
100+
v-text="item.date"></span>
95101
</li>
96102
</ul>
97103
</my-class>
@@ -345,4 +351,24 @@
345351
}
346352
}
347353
}
354+
355+
@media screen and (max-width: 770px) {
356+
body {
357+
background-color: lightblue;
358+
}
359+
.wd800 {
360+
width: 100%;
361+
margin: 30px auto;
362+
}
363+
.flex.wd800 {
364+
display: block;
365+
}
366+
.options {
367+
padding-left: 25px;
368+
margin-bottom:30px;
369+
p {
370+
margin-bottom:0;
371+
}
372+
}
373+
}
348374
</style>

‎examples/examples.bundle.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-seamless-scroll",
3-
"version": "1.0.3",
3+
"version": "1.0.4",
44
"description": "A simple, Seamless scrolling for Vue.js",
55
"main": "dist/vue-seamless-scroll.min.js",
66
"scripts": {

‎src/components/myClass.vue

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div @mouseenter="enter" @mouseleave="leave">
2+
<div @mouseenter="enter" @mouseleave="leave" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
33
<div ref="wrapper" :style="pos">
44
<slot></slot>
55
</div>
@@ -12,6 +12,7 @@
1212
data () {
1313
return {
1414
yPos: 0,
15+
delay: 0,
1516
reqFrame: null
1617
}
1718
},
@@ -27,7 +28,7 @@
2728
},
2829
computed: {
2930
pos () {
30-
return {transform: `translate(0,${this.yPos}px)`}
31+
return {transform: `translate(0,${this.yPos}px)`, transition: `all ease-in ${this.delay}ms`}
3132
},
3233
defaultOption () {
3334
return {
@@ -42,19 +43,67 @@
4243
},
4344
options () {
4445
return Object.assign({}, this.defaultOption, this.classOption)
45-
}
46-
,
46+
},
4747
moveSwitch () {
4848
return this.data.length < this.options.limitMoveNum
4949
}
5050
},
5151
methods: {
52+
touchStart (e) {
53+
if (!this.options.openWatch) return
54+
let timer
55+
let touch = e.targetTouches[0] //touches数组对象获得屏幕上所有的touch,取第一个touch
56+
this.startPos = {
57+
x: touch.pageX,
58+
y: touch.pageY
59+
} //取第一个touch的坐标值
60+
this.startPosY = this.yPos //记录touchStart时候的posY
61+
if (!!this.options.singleHeight) {
62+
if (timer) clearTimeout(timer)
63+
timer = setTimeout(() => {
64+
cancelAnimationFrame(this.reqFrame)
65+
}, this.options.waitTime + 20)
66+
} else {
67+
cancelAnimationFrame(this.reqFrame)
68+
}
69+
},
70+
touchMove (e) {
71+
//当屏幕有多个touch或者页面被缩放过,就不执行move操作
72+
if (!this.options.openWatch || e.targetTouches.length > 1 || e.scale && e.scale !== 1) return
73+
let touch = e.targetTouches[0]
74+
this.endPos = {
75+
x: touch.pageX - this.startPos.x,
76+
y: touch.pageY - this.startPos.y
77+
}
78+
let direction = Math.abs(this.endPos.x) < Math.abs(this.endPos.y) ? 1 : 0 //direction,1表示纵向滑动,0为横向滑动
79+
if (direction === 1) {
80+
event.preventDefault(); //阻止触摸事件的默认行为,即阻止滚屏
81+
this.yPos = this.startPosY + this.endPos.y
82+
}
83+
},
84+
touchEnd () {
85+
if (!this.options.openWatch) return
86+
let timer
87+
let direction = this.options.direction
88+
this.delay = 50
89+
if (direction === 1) {
90+
if (this.yPos > 0) this.yPos = 0
91+
} else {
92+
let h = this.$refs.wrapper.offsetHeight / 2 * -1
93+
if (this.yPos < h) this.yPos = h
94+
}
95+
if (timer) clearTimeout(timer)
96+
timer = setTimeout(() => {
97+
this.delay = 0
98+
this._move()
99+
}, this.delay)
100+
},
52101
enter () {
53-
if (!this.options.openWatch || !!this.options.singleHeight ||!this.options.hoverStop || this.moveSwitch) return
102+
if (!this.options.openWatch || !!this.options.singleHeight || !this.options.hoverStop || this.moveSwitch) return
54103
cancelAnimationFrame(this.reqFrame)
55104
},
56105
leave () {
57-
if (!this.options.openWatch || !!this.options.singleHeight ||!this.options.hoverStop || this.moveSwitch) return
106+
if (!this.options.openWatch || !!this.options.singleHeight || !this.options.hoverStop || this.moveSwitch) return
58107
this._move()
59108
},
60109
_move () {
@@ -82,7 +131,7 @@
82131
} else {
83132
this._move()
84133
}
85-
}else {
134+
} else {
86135
this._move()
87136
}
88137
}

‎test/mobile-page.html

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport"
7+
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
8+
<meta name="format-detection" content="telephone=no"/>
9+
<title>wap=test</title>
10+
<style>
11+
.warp {
12+
height: 300px;
13+
overflow: hidden;
14+
}
15+
16+
.warp ul {
17+
list-style: none;
18+
padding: 0;
19+
margin: 0 auto;
20+
}
21+
22+
.warp li {
23+
height: 30px;
24+
line-height: 30px;
25+
display: flex;
26+
justify-content: space-between;
27+
font-size: 15px;
28+
}
29+
</style>
30+
</head>
31+
<body>
32+
<div id="app">
33+
<vue-seamless-scroll :data="listData" :class-option="classOption"
34+
@copy-data="listData = listData.concat(listData)"
35+
class="warp">
36+
<ul class="item">
37+
<li v-for="item in listData"><span class="title" v-text="item.title"></span><span class="date"
38+
v-text="item.date"></span>
39+
</li>
40+
</ul>
41+
</vue-seamless-scroll>
42+
<vue-seamless-scroll :data="listData3" :class-option="classOption3"
43+
@copy-data="listData3 = listData3.concat(listData3)"
44+
class="warp" style="margin-top: 80px;">
45+
<ul class="item">
46+
<li v-for="item in listData3"><span class="title" v-text="item.title"></span><span
47+
class="date" v-text="item.date"></span></li>
48+
</ul>
49+
</vue-seamless-scroll>
50+
</div>
51+
<script src="https://cdn.bootcss.com/vue/2.5.9/vue.js"></script>
52+
<script src="../dist/vue-seamless-scroll.min.js"></script>
53+
<script>
54+
new Vue({
55+
el: '#app',
56+
data: {
57+
listData: [{
58+
'title': '无缝滚动第一行无缝滚动第一行',
59+
'date': '2017-12-16'
60+
}, {
61+
'title': '无缝滚动第二行无缝滚动第二行',
62+
'date': '2017-12-16'
63+
}, {
64+
'title': '无缝滚动第三行无缝滚动第三行',
65+
'date': '2017-12-16'
66+
}, {
67+
'title': '无缝滚动第四行无缝滚动第四行',
68+
'date': '2017-12-16'
69+
}, {
70+
'title': '无缝滚动第五行无缝滚动第五行',
71+
'date': '2017-12-16'
72+
}, {
73+
'title': '无缝滚动第六行无缝滚动第六行',
74+
'date': '2017-12-16'
75+
}, {
76+
'title': '无缝滚动第七行无缝滚动第七行',
77+
'date': '2017-12-16'
78+
}, {
79+
'title': '无缝滚动第八行无缝滚动第八行',
80+
'date': '2017-12-16'
81+
}, {
82+
'title': '无缝滚动第九行无缝滚动第九行',
83+
'date': '2017-12-16'
84+
}],
85+
listData3: [{
86+
'title': '无缝滚动第一行无缝滚动第一行',
87+
'date': '2017-12-16'
88+
}, {
89+
'title': '无缝滚动第二行无缝滚动第二行',
90+
'date': '2017-12-16'
91+
}, {
92+
'title': '无缝滚动第三行无缝滚动第三行',
93+
'date': '2017-12-16'
94+
}, {
95+
'title': '无缝滚动第四行无缝滚动第四行',
96+
'date': '2017-12-16'
97+
}, {
98+
'title': '无缝滚动第五行无缝滚动第五行',
99+
'date': '2017-12-16'
100+
}, {
101+
'title': '无缝滚动第六行无缝滚动第六行',
102+
'date': '2017-12-16'
103+
}, {
104+
'title': '无缝滚动第七行无缝滚动第七行',
105+
'date': '2017-12-16'
106+
}, {
107+
'title': '无缝滚动第八行无缝滚动第八行',
108+
'date': '2017-12-16'
109+
}, {
110+
'title': '无缝滚动第九行无缝滚动第九行',
111+
'date': '2017-12-16'
112+
}]
113+
},
114+
computed: {
115+
classOption: function () {
116+
return {
117+
step: 0.5,
118+
limitMoveNum: 5
119+
}
120+
},
121+
classOption3: function () {
122+
return {
123+
limitMoveNum: 5,
124+
direction: 0,
125+
hoverStop: false
126+
}
127+
}
128+
}
129+
})
130+
</script>
131+
</body>
132+
133+
</html>

0 commit comments

Comments
 (0)
Please sign in to comment.