jufubao-movie 1.0.39-beta1 → 1.0.39-beta11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/JfbMovieLineFilm/JfbMovieLineFilm.vue +11 -3
- package/src/components/JfbMovieLineLineSeat/Attr.js +11 -0
- package/src/components/JfbMovieLineLineSeat/JfbMovieLineLineSeat.vue +74 -11
- package/src/components/JfbMovieLineLineSeat/Mock.js +1 -0
- package/src/components/JfbMovieLineLineSeat/XdOnlineSeat.vue +48 -27
- package/src/components/JfbMovieLineLineSeat/XdOnlineSeatMove.vue +13 -9
- package/src/components/JfbMovieLineSchedule/JfbMovieLineSchedule.vue +1 -1
- package/src/components/JfbMovieTfkFilmList/Attr.js +5 -238
- package/src/components/JfbMovieTfkFilmList/ContentItem.vue +129 -76
- package/src/components/JfbMovieTfkFilmList/JfbMovieTfkFilmList.vue +284 -91
- package/src/components/JfbMovieTfkFilmList/PosterAttr.js +257 -0
- package/src/components/JfbMovieTfkFilmList/XdPoster.vue +160 -0
- package/src/components/JfbMovieTfkFilmList/XdQueryFilter.vue +1 -0
- package/src/components/JfbMovieTfkFilmRecommend/Attr.js +31 -3
- package/src/components/JfbMovieTfkFilmRecommend/JfbMovieTfkFilmRecommend.vue +30 -6
- package/src/lib/VirtualList.js +269 -0
- package/src/mixins/posterMixins.js +0 -59
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
export default class VirtualList {
|
|
4
|
+
virtualType='fixed';
|
|
5
|
+
virtualBufferHeight= 300;
|
|
6
|
+
virtualFixedItemHeight; //固定模式高度设置
|
|
7
|
+
//virtualVue; //当前组件vm实例(小程序不可用)
|
|
8
|
+
virtualTotalData=[]; //数组长度
|
|
9
|
+
virtualHeightObj = {}; //高度序列index: {max:xx,min:xx}
|
|
10
|
+
autoHeight = []; //保存动态高度高度值
|
|
11
|
+
$el= null; //开始点元素
|
|
12
|
+
offsetTop= null;//开始点元素的偏移量
|
|
13
|
+
eqMaxTimer = 0;//
|
|
14
|
+
marginTopAndBottom= 0; //上下边距
|
|
15
|
+
paddingTopAndBottom= 0; //上下边距
|
|
16
|
+
orgUpdateTop = 0; //开始点元素原点偏移量
|
|
17
|
+
isFirst = true;
|
|
18
|
+
startIndex= 0;
|
|
19
|
+
endIndex= 0;
|
|
20
|
+
screenHeight=0;//全屏高度
|
|
21
|
+
contentRefBottomMargin= 0 //计算偏移量容器与内容直接的边距
|
|
22
|
+
|
|
23
|
+
top=0;
|
|
24
|
+
bottom=0;
|
|
25
|
+
virtualCallback= ()=>{};
|
|
26
|
+
status= false;
|
|
27
|
+
options = null;
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @description 初始化或者重置对象
|
|
33
|
+
* @param $vm {Vue} vue对象
|
|
34
|
+
* @param $el {string}
|
|
35
|
+
* @param params {Object}
|
|
36
|
+
* @param params.type {string} 元素高度为固定或者非固定 其值:auto|fixed
|
|
37
|
+
* @param params.fixedHeight {number} 固定(rpx)(fixed)模式 (必选)
|
|
38
|
+
* @param params.marginTopAndBottom {Number} 上下边距 单位:rpx
|
|
39
|
+
* @param params.paddingTopAndBottom {Number} 上下填充 单位:rpx
|
|
40
|
+
* @param params.contentRefBottomMargin {Number} 计算偏移量容器与内容直接的边距 rpx
|
|
41
|
+
* @param params.bufferHeight {number} 缓冲高度(rpx)
|
|
42
|
+
* @param params.callback {Function} 回调方法
|
|
43
|
+
*/
|
|
44
|
+
constructor($vm ,$el, params ) {
|
|
45
|
+
this.options = params;
|
|
46
|
+
this.$pxNum = $vm.$pxNum
|
|
47
|
+
this.virtualBufferHeight = 300;
|
|
48
|
+
if(params.type && ['auto','fixed'].includes(params.type)) this.virtualType = params.type;
|
|
49
|
+
if(params.bufferHeight) this.virtualBufferHeight = params.bufferHeight * $vm.$rpxNum;
|
|
50
|
+
if(params.marginTopAndBottom) this.marginTopAndBottom = params.marginTopAndBottom * $vm.$rpxNum;
|
|
51
|
+
if(params.paddingTopAndBottom) this.paddingTopAndBottom = params.paddingTopAndBottom * $vm.$rpxNum;
|
|
52
|
+
if(params.contentRefBottomMargin) this.contentRefBottomMargin = params.contentRefBottomMargin * $vm.$rpxNum;
|
|
53
|
+
if(params.fixedHeight) this.virtualFixedItemHeight = params.fixedHeight * $vm.$rpxNum;
|
|
54
|
+
this.virtualTotalData = [];
|
|
55
|
+
this.$el = $el;
|
|
56
|
+
$vm.$nextTick(()=>{
|
|
57
|
+
this.checkOffsetTop();
|
|
58
|
+
});
|
|
59
|
+
this.screenHeight = uni.getSystemInfoSync().safeArea.height;
|
|
60
|
+
if(typeof params.callback !== 'function') {
|
|
61
|
+
throw new Error(`FixedHeight is require, got is ${params.fixedHeight}`);
|
|
62
|
+
}else this.virtualCallback = params.callback;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @description 获取原点的偏移量
|
|
67
|
+
*/
|
|
68
|
+
checkOffsetTop(){
|
|
69
|
+
|
|
70
|
+
//检查前后返回值相等并且大于5次就不在检查
|
|
71
|
+
if(this.eqMaxTimer >= 5) {
|
|
72
|
+
this.status = true;
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.options.getDom(this.$el).then(res=>{
|
|
77
|
+
let offsetTop = res.top
|
|
78
|
+
if(this.offsetTop === offsetTop) {
|
|
79
|
+
this.eqMaxTimer++;
|
|
80
|
+
}
|
|
81
|
+
else this.offsetTop = offsetTop;
|
|
82
|
+
this.orgUpdateTop = offsetTop + this.contentRefBottomMargin;
|
|
83
|
+
this.computedMinAndMaxFixed();
|
|
84
|
+
setTimeout(()=>{
|
|
85
|
+
this.checkOffsetTop();
|
|
86
|
+
}, 10)
|
|
87
|
+
}).catch(res=>{
|
|
88
|
+
setTimeout(()=>{
|
|
89
|
+
this.checkOffsetTop();
|
|
90
|
+
}, 10)
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
cloneDeep(data){
|
|
95
|
+
return JSON.parse(JSON.stringify(data));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @description 固定高度模式初始化列表记录范围
|
|
100
|
+
*/
|
|
101
|
+
computedMinAndMaxFixed(){
|
|
102
|
+
if(this.virtualType === 'fixed' &&
|
|
103
|
+
this.virtualFixedItemHeight === undefined
|
|
104
|
+
) throw new Error(`FixedHeight is require, got is ${this.virtualFixedItemHeight}`);
|
|
105
|
+
|
|
106
|
+
let itemHeight = this.virtualFixedItemHeight + this.marginTopAndBottom + this.paddingTopAndBottom;
|
|
107
|
+
let height = this.virtualFixedItemHeight;
|
|
108
|
+
|
|
109
|
+
this.virtualTotalData.map((item,index)=>{
|
|
110
|
+
if(this.virtualType === 'auto'){
|
|
111
|
+
itemHeight = this.autoHeight[index] + this.marginTopAndBottom + this.paddingTopAndBottom;
|
|
112
|
+
height = this.autoHeight[index];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if(index === 0) {
|
|
116
|
+
this.virtualHeightObj[index] = {
|
|
117
|
+
min: this.orgUpdateTop,
|
|
118
|
+
max: this.orgUpdateTop + itemHeight,
|
|
119
|
+
height: height * this.$pxNum ,
|
|
120
|
+
itemHeight
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
let prev = this.virtualHeightObj[index-1];
|
|
125
|
+
this.virtualHeightObj[index] = {
|
|
126
|
+
min: prev.max,
|
|
127
|
+
max: prev.max + itemHeight,
|
|
128
|
+
height: height * this.$pxNum ,
|
|
129
|
+
itemHeight
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
console.log(this.virtualHeightObj)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @description 新增数据时候调用此方法(对外)
|
|
139
|
+
* @param data {Array} 列表数据
|
|
140
|
+
* @param height {Array} 高度数组
|
|
141
|
+
*/
|
|
142
|
+
pushVirtualData(data, height){
|
|
143
|
+
if(this.status) {
|
|
144
|
+
//清空响应对象
|
|
145
|
+
if(this.virtualTotalData.length > 0) this.isFirst = false;
|
|
146
|
+
this.virtualTotalData = this.virtualTotalData.concat(this.cloneDeep(data));
|
|
147
|
+
|
|
148
|
+
//非固定模式
|
|
149
|
+
if(this.virtualType === 'auto') {
|
|
150
|
+
if(!height) throw new Error(`height is require, got is ${height}`);
|
|
151
|
+
this.autoHeight = this.autoHeight.concat(height)
|
|
152
|
+
this.computedMinAndMaxFixed();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//固定模式
|
|
156
|
+
if(this.virtualType === 'fixed') {
|
|
157
|
+
this.computedMinAndMaxFixed();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
//首次加载
|
|
161
|
+
if(this.isFirst) this.onScrollEvent(0);
|
|
162
|
+
this.isFirst = false
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
setTimeout(()=>{
|
|
166
|
+
this.pushVirtualData(data, height)
|
|
167
|
+
},100)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @description 滚动事件(对外)
|
|
173
|
+
* @param scrollTop
|
|
174
|
+
*/
|
|
175
|
+
onScrollEvent(scrollTop) {
|
|
176
|
+
|
|
177
|
+
if(!this.status || this.virtualTotalData.length === 0) {
|
|
178
|
+
/**@type Function **/
|
|
179
|
+
this.virtualCallback({
|
|
180
|
+
paddingTop:0,
|
|
181
|
+
paddingBottom: 0,
|
|
182
|
+
data: []
|
|
183
|
+
});
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
//非固定计算索引
|
|
188
|
+
//计算开始索引
|
|
189
|
+
Object.keys(this.virtualHeightObj).map((key,index)=>{
|
|
190
|
+
let top = scrollTop - this.virtualBufferHeight;
|
|
191
|
+
|
|
192
|
+
//滚动高度小于元素顶部与屏幕顶部偏移量直接取值0索引
|
|
193
|
+
if(top < this.orgUpdateTop) {
|
|
194
|
+
this.startIndex = 0;
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if(top >= this.virtualHeightObj[key].min && top < this.virtualHeightObj[key].max){
|
|
199
|
+
this.startIndex = Number(key);
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
//计算结束索引
|
|
204
|
+
this.endIndex = this.virtualTotalData.length;
|
|
205
|
+
Object.keys(this.virtualHeightObj).map((key,index)=>{
|
|
206
|
+
let top = scrollTop < this.orgUpdateTop ? this.orgUpdateTop : scrollTop
|
|
207
|
+
let endScrollTop = top + this.screenHeight + this.virtualBufferHeight;
|
|
208
|
+
|
|
209
|
+
////距离底部有1屏幕高度
|
|
210
|
+
let maxScroll = this.virtualHeightObj[this.virtualTotalData.length -1].max;
|
|
211
|
+
if(endScrollTop >= maxScroll) {
|
|
212
|
+
endScrollTop = maxScroll;
|
|
213
|
+
}
|
|
214
|
+
if(endScrollTop > this.virtualHeightObj[key].min && endScrollTop <= this.virtualHeightObj[key].max){
|
|
215
|
+
this.endIndex = Number(key);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
//计算数据是否显示
|
|
220
|
+
let data = this.cloneDeep(this.virtualTotalData).map((item,index)=>{
|
|
221
|
+
item['is_content_show'] = index >= this.startIndex && index <= this.endIndex;
|
|
222
|
+
item['is_content_height'] = this.virtualHeightObj[index].height
|
|
223
|
+
return item
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
console.log('onScrollEvent.index',this.endIndex - this.startIndex, this.startIndex,this.endIndex, scrollTop);
|
|
227
|
+
|
|
228
|
+
/**@type Function **/
|
|
229
|
+
this.virtualCallback({
|
|
230
|
+
data: data
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @description 切换Tab调用此方法(对外)
|
|
237
|
+
* @param virtualType {string} 类型 auto|fixed
|
|
238
|
+
* @param $vm {Vue} vue实例 (在自动高度模式必选)
|
|
239
|
+
* @param ref 元素对象 (在自动高度模式必选)
|
|
240
|
+
*/
|
|
241
|
+
onChangeTab($vm , ref , virtualType){
|
|
242
|
+
this.virtualTotalData = [];
|
|
243
|
+
this.isFirst = true;
|
|
244
|
+
this.autoHeight = [];
|
|
245
|
+
this.endIndex = 0;
|
|
246
|
+
this.startIndex = 0;
|
|
247
|
+
|
|
248
|
+
//改变顶部偏移量元素
|
|
249
|
+
if(['auto','fixed'].includes(virtualType) && virtualType !== this.virtualType) {
|
|
250
|
+
if(!$vm) throw new Error(`onChangeTab, $vm is require, got is ${$vm.$xdUniHelper.checkVarType($vm)},value is ${$vm}`);
|
|
251
|
+
if(!ref) throw new Error(`onChangeTab, ref is require, got is ${$vm.$xdUniHelper.checkVarType(ref)}, value is ${ref}`);
|
|
252
|
+
this.virtualType = virtualType;
|
|
253
|
+
this.orgUpdateTop = 0;
|
|
254
|
+
this.$el = ref;
|
|
255
|
+
this.status = false;
|
|
256
|
+
this.eqMaxTimer = 4;
|
|
257
|
+
$vm.$nextTick(()=>{
|
|
258
|
+
this.checkOffsetTop();
|
|
259
|
+
});
|
|
260
|
+
this.virtualCallback({
|
|
261
|
+
paddingTop: this.top,
|
|
262
|
+
paddingBottom: this.bottom,
|
|
263
|
+
data:null,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
|
|
@@ -61,65 +61,6 @@ export default {
|
|
|
61
61
|
}
|
|
62
62
|
return ''
|
|
63
63
|
},
|
|
64
|
-
|
|
65
|
-
handlePosterClick(item) {
|
|
66
|
-
if(!item.redirect_data) {
|
|
67
|
-
console.warn(`未配置链接地址: ${item.redirect_data}`);
|
|
68
|
-
console.error(`未配置链接地址: ${item.redirect_data}`);
|
|
69
|
-
return
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
//内部链接跳转地址
|
|
73
|
-
if (item.redirect_type === 'INN') {
|
|
74
|
-
try {
|
|
75
|
-
let url = JSON.parse(item.redirect_data);
|
|
76
|
-
let params = '';
|
|
77
|
-
if(url.page) {
|
|
78
|
-
if (item['redirect_params']) params = `?${item['redirect_params']}`;
|
|
79
|
-
this.$xdUniHelper.navigateTo({url: url.page + params})
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
console.error(`应用链接配置错误: ${url.page}`)
|
|
83
|
-
}
|
|
84
|
-
} catch (e) {
|
|
85
|
-
console.error(`应用链接配置错误: ${item.redirect_data}`)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
//外部链接
|
|
90
|
-
if (item.redirect_type === 'URL') {
|
|
91
|
-
let reg = /^(http:\/\/|https:\/\/|\/\/)+.+$/;
|
|
92
|
-
let spReg = /(-apiuri\/v)/;
|
|
93
|
-
//#ifdef MP-WEIXIN
|
|
94
|
-
try {
|
|
95
|
-
let url = JSON.parse(item.redirect_data);
|
|
96
|
-
if (reg.test(url.url) || spReg.test(url.url)) {
|
|
97
|
-
console.warn(`广告跳转外站: ${url.url}`)
|
|
98
|
-
this.$xdUniHelper.navigateTo(url);
|
|
99
|
-
} else {
|
|
100
|
-
console.error(`广告跳转外站配置错误: ${url.url}`)
|
|
101
|
-
}
|
|
102
|
-
} catch (e) {
|
|
103
|
-
console.error(`广告跳转外站配置错误: ${item.redirect_data}`)
|
|
104
|
-
}
|
|
105
|
-
//#endif
|
|
106
|
-
//#ifdef H5
|
|
107
|
-
try {
|
|
108
|
-
let url = JSON.parse(item.redirect_data);
|
|
109
|
-
console.warn(`广告跳转外站: ${url.url}`);
|
|
110
|
-
this.$xdUniHelper.redirectTo(url, false)
|
|
111
|
-
} catch (e) {
|
|
112
|
-
console.error(`广告跳转外站配置错误: ${item.redirect_data}`)
|
|
113
|
-
}
|
|
114
|
-
//#endif
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
//无跳转地址
|
|
119
|
-
if(item.redirect_type === 'EMP') {
|
|
120
|
-
console.warn(`无跳转地址`);
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
64
|
},
|
|
124
65
|
}
|
|
125
66
|
|