@kyfe/fms-vue2-components 0.0.2-beta.0

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.
Files changed (62) hide show
  1. package/dist/assets/css/fms-ks-decrypt.css +1 -0
  2. package/dist/fms-copy-box/index.js +69 -0
  3. package/dist/fms-copy-box/style.css +1 -0
  4. package/dist/fms-empty/index.js +42 -0
  5. package/dist/fms-empty/style.css +1 -0
  6. package/dist/fms-ks-decrypt/index.js +9 -0
  7. package/dist/fms-ks-decrypt.bcc12f44.js +335 -0
  8. package/dist/fms-ks-file-upload/index.js +148 -0
  9. package/dist/fms-ks-file-upload/style.css +1 -0
  10. package/dist/fms-ks-file-view/index.js +286 -0
  11. package/dist/fms-ks-file-view/style.css +1 -0
  12. package/dist/fms-scroll-list/index.js +241 -0
  13. package/dist/fms-scroll-list/style.css +1 -0
  14. package/dist/index.js +37 -0
  15. package/dist/plugin-vue2_normalizer.ed7092a9.js +30 -0
  16. package/package.json +31 -0
  17. package/src/assets/images/code.png +0 -0
  18. package/src/assets/images/copy-icon.png +0 -0
  19. package/src/assets/images/tag-gkbk.png +0 -0
  20. package/src/assets/style/common.less +62 -0
  21. package/src/components/fms-copy-box/fms-copy-box.vue +97 -0
  22. package/src/components/fms-copy-box/index.js +7 -0
  23. package/src/components/fms-copy-box//345/244/215/345/210/266.md +0 -0
  24. package/src/components/fms-empty/assets/default.png +0 -0
  25. package/src/components/fms-empty/assets/search.png +0 -0
  26. package/src/components/fms-empty/fms-empty.vue +57 -0
  27. package/src/components/fms-empty/index.js +7 -0
  28. package/src/components/fms-ks-decrypt/component/call/index.vue +283 -0
  29. package/src/components/fms-ks-decrypt/component/call/mixin.less +50 -0
  30. package/src/components/fms-ks-decrypt/component/custom-call/index.vue +50 -0
  31. package/src/components/fms-ks-decrypt/fms-ks-decrypt.vue +257 -0
  32. package/src/components/fms-ks-decrypt/index.js +7 -0
  33. package/src/components/fms-ks-decrypt/phone.svg +24 -0
  34. package/src/components/fms-ks-decrypt//346/225/217/346/204/237/347/233/221/346/216/247/347/273/204/344/273/266.md +140 -0
  35. package/src/components/fms-ks-file-upload/assets/icon_close.png +0 -0
  36. package/src/components/fms-ks-file-upload/fms-ks-file-upload.vue +254 -0
  37. package/src/components/fms-ks-file-upload/index.js +7 -0
  38. package/src/components/fms-ks-file-upload//344/270/212/344/274/240/347/273/204/344/273/266.md +0 -0
  39. package/src/components/fms-ks-file-view/assets/icon_default.svg +23 -0
  40. package/src/components/fms-ks-file-view/assets/icon_default_new.png +0 -0
  41. package/src/components/fms-ks-file-view/assets/icon_excel.svg +20 -0
  42. package/src/components/fms-ks-file-view/assets/icon_excel_new.png +0 -0
  43. package/src/components/fms-ks-file-view/assets/icon_file.png +0 -0
  44. package/src/components/fms-ks-file-view/assets/icon_pdf_new.png +0 -0
  45. package/src/components/fms-ks-file-view/assets/icon_ppt.svg +20 -0
  46. package/src/components/fms-ks-file-view/assets/icon_ppt_new.png +0 -0
  47. package/src/components/fms-ks-file-view/assets/icon_preview_file.png +0 -0
  48. package/src/components/fms-ks-file-view/assets/icon_txt.png +0 -0
  49. package/src/components/fms-ks-file-view/assets/icon_word.svg +19 -0
  50. package/src/components/fms-ks-file-view/assets/icon_word_new.png +0 -0
  51. package/src/components/fms-ks-file-view/assets/icon_xmind.png +0 -0
  52. package/src/components/fms-ks-file-view/components/attachment.vue +343 -0
  53. package/src/components/fms-ks-file-view/fms-ks-file-view.vue +165 -0
  54. package/src/components/fms-ks-file-view/index.js +7 -0
  55. package/src/components/fms-ks-file-view/utils/index.js +27 -0
  56. package/src/components/fms-ks-file-view//346/226/207/344/273/266/351/242/204/350/247/210.md +23 -0
  57. package/src/components/fms-scroll-list/Waterfall.js +91 -0
  58. package/src/components/fms-scroll-list/fms-scroll-list.vue +294 -0
  59. package/src/components/fms-scroll-list/index.js +7 -0
  60. package/src/components/fms-scroll-list//346/273/232/345/212/250.md +0 -0
  61. package/src/index.js +37 -0
  62. package/vite.config.js +82 -0
@@ -0,0 +1,343 @@
1
+ <script lang="jsx">
2
+ // 附件展示(只展示不上传)
3
+ import IconWord from '../assets/icon_word_new.png'
4
+ import IconPpt from '../assets/icon_ppt_new.png'
5
+ import IconExcel from '../assets/icon_excel_new.png'
6
+ import IconDefault from '../assets/icon_default_new.png'
7
+ import IconFile from '../assets/icon_file.png'
8
+ import IconPdf from '../assets/icon_pdf_new.png'
9
+ import IconXmind from '../assets/icon_xmind.png'
10
+ import IconTxt from '../assets/icon_txt.png'
11
+ import IconPreviewFile from '../assets/icon_preview_file.png'
12
+ // 转换显示文件大小
13
+ import { changeFileSize } from '../utils/index'
14
+
15
+ const { ImagePreview } = window.vant
16
+ const ks = window.ks
17
+ const IconMap = new Map()
18
+ // word
19
+ IconMap.set('doc', IconWord)
20
+ IconMap.set('docx', IconWord)
21
+ // ppt
22
+ IconMap.set('ppt', IconPpt)
23
+ IconMap.set('pptx', IconPpt)
24
+ IconMap.set('pps', IconPpt)
25
+ IconMap.set('ppsx', IconPpt)
26
+ // excel
27
+ IconMap.set('xls', IconExcel)
28
+ IconMap.set('xlsx', IconExcel)
29
+ // pdf
30
+ IconMap.set('pdf', IconPdf)
31
+ // xmind
32
+ IconMap.set('xmind', IconXmind)
33
+ // txt
34
+ IconMap.set('txt', IconTxt)
35
+
36
+ export default {
37
+ name: 'attachment-view',
38
+ props: {
39
+ // 文件数组
40
+ fileList: {
41
+ type: Array,
42
+ default: () => [],
43
+ },
44
+ // 是否开启循环播放,默认:true
45
+ loop: {
46
+ type: Boolean,
47
+ default: true,
48
+ },
49
+ // 标题
50
+ titleName: {
51
+ type: String,
52
+ default: '附件',
53
+ },
54
+ },
55
+ computed: {
56
+ imgList: function () {
57
+ const { fileList } = this
58
+ let imgs = (fileList || []).filter((f) => this.isImageType(f.extendName))
59
+ if (!imgs || !imgs.length) return []
60
+ let left = 5 - (imgs.length % 5) // 一行5个,算出剩余几个
61
+ // 填充,为了更灵活的justify-content: space-between;样式
62
+ while (left) {
63
+ imgs.push(null)
64
+ left--
65
+ }
66
+ return imgs
67
+ },
68
+ otherFileList: function () {
69
+ const { fileList } = this
70
+ return (fileList || []).filter((f) => !this.isImageType(f.extendName))
71
+ },
72
+ fileCount: function () {
73
+ const { fileList } = this
74
+ return fileList.length
75
+ },
76
+ },
77
+ methods: {
78
+ // 文件扩展名是否是图片
79
+ // 图片直接展示
80
+ isImageType(extend) {
81
+ return /^(jpe?g)|(png)|(gif)$/i.test(extend)
82
+ },
83
+ // 受支持的文件类型(有对应icon)
84
+ // 目前只有word,excel,ppt
85
+ isSupportFileType(extend) {
86
+ return /^$/i.test(extend)
87
+ },
88
+ // 其他文件类型
89
+ otherFileType(extend) {
90
+ return !this.isImageType(extend) && !this.isSupportFileType(extend)
91
+ },
92
+ // 文件名去除后缀名
93
+ splitFileName(name) {
94
+ return name.substr(0, name.lastIndexOf('.'))
95
+ },
96
+ // 文件图标
97
+ getFileIcon(extend) {
98
+ const iconUrl = IconMap.get(extend)
99
+ return iconUrl || IconDefault
100
+ },
101
+ // renders
102
+ // head
103
+ renderHead() {
104
+ const { fileCount, titleName } = this
105
+ return (
106
+ <div class="att-head">
107
+ <img src={IconFile} class="file-icon" />
108
+ <div class="att-title">
109
+ {titleName}({fileCount})
110
+ </div>
111
+ </div>
112
+ )
113
+ },
114
+ // img list
115
+ renderImages() {
116
+ const { imgList } = this
117
+ return imgList && imgList.length ? (
118
+ <div class="att-imgs">
119
+ <div class="att-img-content">
120
+ {imgList.map((img, index) => {
121
+ return img ? (
122
+ <div
123
+ class="att-img"
124
+ onClick={() => this.previewAssets(index, imgList)}
125
+ style={{ backgroundImage: `url(${img.url})` }}
126
+ ></div>
127
+ ) : (
128
+ <div class="att-img-hidden"></div>
129
+ )
130
+ })}
131
+ </div>
132
+ </div>
133
+ ) : null
134
+ },
135
+ // 其他文件
136
+ renderOtherFiles() {
137
+ const { otherFileList } = this
138
+ return otherFileList && otherFileList.length ? (
139
+ <div class="att-files">
140
+ {otherFileList.map((f) => {
141
+ return (
142
+ <div class="att-file" onClick={() => this.previewFile(f)}>
143
+ <div class="att-file-icon">
144
+ <img src={this.getFileIcon(f.extendName)} width="32" height="32" />
145
+ </div>
146
+ <div class="att-file-info-wrap">
147
+ <div class="att-file-fullname">
148
+ <div class="att-file-name">{this.splitFileName(f.name)}</div>
149
+ {f.extendName ? (
150
+ <div class="att-file-extend">.{f.extendName}</div>
151
+ ) : null}
152
+ </div>
153
+ <div class="att-file-size">{changeFileSize(f.size)}</div>
154
+ </div>
155
+ <div class="preview-icon-wrap">
156
+ <img width="16" height="16" src={IconPreviewFile} />
157
+ </div>
158
+ </div>
159
+ )
160
+ })}
161
+ </div>
162
+ ) : null
163
+ },
164
+ /**
165
+ * @description: 预览图片
166
+ * @param {*} index 序号
167
+ * @param {*} list 图片列表
168
+ * @return {*}
169
+ */
170
+ previewAssets(index, list) {
171
+ let filePaths = list
172
+ .map((item) => item && item['url'] && item.url)
173
+ .filter((f) => !!f)
174
+ // PC跨声环境,用ks方法
175
+ if (window.isKsPcMiniProgram) {
176
+ // NOTE: 此处原代码为 this.$store.commit('setPreviewFile', true)
177
+ this.$emit('preview', list[index])
178
+ window.ks.previewAssets({
179
+ index, // 默认从第几个资源开始浏览 index不能大于assetsPaths的长度
180
+ filePaths, // 接口返回的文件系统路径,或者本地路径
181
+ })
182
+ } else {
183
+ // 默认使用vant的图片预览,不存在的情况下才使用ks的
184
+ if (ImagePreview) {
185
+ window.ks.setCloseButton({ isShow: false })
186
+ ImagePreview({
187
+ images: filePaths,
188
+ startPosition: index,
189
+ loop: this.loop,
190
+ onClose() {
191
+ window.ks.setCloseButton({ isShow: true })
192
+ },
193
+ })
194
+ } else {
195
+ ks.previewAssets({
196
+ index, // 默认从第几个资源开始浏览 index不能大于assetsPaths的长度
197
+ filePaths, // 接口返回的文件系统路径,或者本地路径
198
+ })
199
+ }
200
+ }
201
+ },
202
+ // 预览文档
203
+ previewFile(file) {
204
+ // NOTE: 此处原代码为 this.$store.commit('setPreviewFile', true)
205
+ this.$emit('preview', file)
206
+ window.ks.callFunc({
207
+ method: 'previewFile',
208
+ params: {
209
+ filePath: file.url,
210
+ fileName: file.name,
211
+ fileSize: String(file.size), // 跨声原生方法预览文件,fileSize转string类型,否则iPhone预览不了
212
+ },
213
+ })
214
+ },
215
+ },
216
+ render() {
217
+ return (
218
+ <div class="att-view">
219
+ {this.$slots.header ? this.$slots.header : this.renderHead()}
220
+ {this.renderImages()}
221
+ {this.renderOtherFiles()}
222
+ </div>
223
+ )
224
+ },
225
+ }
226
+ </script>
227
+
228
+ <style lang="less" scoped>
229
+ .att-view {
230
+ position: relative;
231
+ padding: 12px 16px 0 16px;
232
+ font-size: 14px;
233
+ color: #333;
234
+ &::after {
235
+ position: absolute;
236
+ content: ' ';
237
+ pointer-events: none;
238
+ right: 0;
239
+ top: 0;
240
+ left: 16px;
241
+ right: 16px;
242
+ border-bottom: 1px solid #f2f2f2;
243
+ -webkit-transform: scaleY(0.5);
244
+ transform: scaleY(0.5);
245
+ }
246
+ .att-head {
247
+ display: flex;
248
+ align-items: center;
249
+ margin-bottom: 12px;
250
+ .file-icon {
251
+ width: 14px;
252
+ height: 14px;
253
+ }
254
+ .att-title {
255
+ font-size: 14px;
256
+ text-align: left;
257
+ color: #6e6d72;
258
+ margin-left: 4px;
259
+ }
260
+ .att-head-tips {
261
+ font-size: 12px;
262
+ color: #999;
263
+ }
264
+ }
265
+ .att-imgs {
266
+ margin-top: 12px;
267
+ .att-img-content {
268
+ position: relative;
269
+ display: flex;
270
+ flex-wrap: wrap;
271
+ flex-direction: row;
272
+ .att-img {
273
+ margin: 0 12px 10px 0;
274
+ width: 52px;
275
+ height: 52px;
276
+ border: 0.5px solid #cacaca;
277
+ border-radius: 4px;
278
+ background-position: center;
279
+ background-size: cover;
280
+ }
281
+ .att-img-hidden {
282
+ width: 60px;
283
+ height: 0;
284
+ }
285
+ }
286
+ }
287
+ .att-files {
288
+ .att-file {
289
+ display: flex;
290
+ width: 100%;
291
+ height: 52px;
292
+ background: #f7f8fa;
293
+ border: 0.5px solid #ebedf5;
294
+ border-radius: 4px;
295
+ margin-bottom: 10px;
296
+ &:first-child {
297
+ .att-file-fullname {
298
+ &::before {
299
+ display: none;
300
+ }
301
+ }
302
+ }
303
+ &:last-child {
304
+ margin-bottom: 0;
305
+ }
306
+ .att-file-icon {
307
+ padding: 10px 0 10px 10px;
308
+ width: 42px;
309
+ height: 100%;
310
+ background-position: center;
311
+ background-size: cover;
312
+ }
313
+ .att-file-info-wrap {
314
+ padding: 6px 0 6px 10px;
315
+ width: calc(100% - 90px);
316
+ .att-file-fullname {
317
+ display: flex;
318
+ position: relative;
319
+ width: 100%;
320
+ font-size: 14px;
321
+ color: #03050d;
322
+ line-height: 20px;
323
+ .att-file-name {
324
+ overflow: hidden; //超出的文本隐藏
325
+ text-overflow: ellipsis; //溢出用省略号显示
326
+ white-space: nowrap;
327
+ }
328
+ }
329
+ .att-file-size {
330
+ font-size: 12px;
331
+ color: #858793;
332
+ line-height: 18px;
333
+ }
334
+ }
335
+ .preview-icon-wrap {
336
+ padding: 18px 16px 18px 16px;
337
+ width: 48px;
338
+ height: 100%;
339
+ }
340
+ }
341
+ }
342
+ }
343
+ </style>
@@ -0,0 +1,165 @@
1
+ <!--
2
+ * @Description: 附件预览通用组件
3
+ -->
4
+ <template>
5
+ <div class="flow-fms-file-view" @preview="(fileInfo) => $emit('preview', fileInfo)">
6
+ <van-collapse v-model="activeNames">
7
+ <van-collapse-item name="1" class="collapse-title--expend_border-bottom-hidden">
8
+ <template #title v-if="$slots.title">
9
+ <slot name="title" />
10
+ </template>
11
+ <template #title v-else>
12
+ <div>
13
+ <strong>附件</strong>
14
+ </div>
15
+ </template>
16
+ <div class="file-wrap" v-if="fileList.length > 0">
17
+ <!-- 使用公共的附件预览组件 -->
18
+ <attachment-view :fileList="fileList" :onPreview="onPreview"></attachment-view>
19
+ </div>
20
+ <div v-else class="no-file">暂无附件</div>
21
+ </van-collapse-item>
22
+ </van-collapse>
23
+ </div>
24
+ </template>
25
+ <script>
26
+ import AttachmentView from './components/attachment.vue'
27
+
28
+ export default {
29
+ name: 'FmsKsFileView',
30
+ components: {
31
+ AttachmentView: {
32
+ extends: AttachmentView,
33
+ props: {
34
+ onPreview: Function,
35
+ },
36
+ methods: {
37
+ // 覆盖公共的方法,添加权限
38
+ previewAssets(index, list) {
39
+ // onPreview方法校验是否可以预览,返回true时终止预览
40
+ const flag = this.onPreview?.(list[index])
41
+ if (flag) return
42
+ AttachmentView.methods.previewAssets.call(this, index, list)
43
+ },
44
+ // 预览文档
45
+ previewFile(file) {
46
+ // onPreview方法校验是否可以预览,返回true时终止预览
47
+ const flag = this.onPreview?.(file)
48
+ if (flag) return
49
+ AttachmentView.methods.previewFile.call(this, file)
50
+ },
51
+ },
52
+ },
53
+ },
54
+ props: {
55
+ // 例:[
56
+ // {
57
+ // extendName: '文件后缀',
58
+ // name: '文件名',
59
+ // bizId: 'bizId',
60
+ // bizCode: 'bizCode',
61
+ // id: '文件id',
62
+ // }
63
+ // ]
64
+ fileList: {
65
+ type: Array,
66
+ default: () => [],
67
+ },
68
+ showToggleAll: {
69
+ type: Boolean,
70
+ default: true,
71
+ },
72
+ // 点击预览前拦截事件,方法返回true时终止预览操作,入参为当前预览的图片,透传至组件AttachmentView
73
+ onPreview: Function,
74
+ },
75
+ data() {
76
+ return {
77
+ activeNames: ['1'],
78
+ }
79
+ },
80
+ watch: {
81
+ showToggleAll: {
82
+ immediate: true,
83
+ handler(val) {
84
+ this.activeNames = [val ? '1' : '0']
85
+ },
86
+ },
87
+ fileList: {
88
+ immediate: true,
89
+ handler(val) {
90
+ if (val.length > 0) {
91
+ this.activeNames = ['1']
92
+ }
93
+ },
94
+ },
95
+ },
96
+ }
97
+ </script>
98
+ <style lang="less" scoped>
99
+ @import '@/assets/style/common.less';
100
+ .flow-fms-file-view {
101
+ border-radius: 6px;
102
+ overflow: hidden;
103
+ /deep/ .van-hairline--top-bottom:after {
104
+ border: none;
105
+ }
106
+ /deep/ .van-collapse-item__content {
107
+ // padding: 16px;
108
+ background-color: #fff;
109
+ }
110
+ .file-wrap {
111
+ .att-view {
112
+ padding: 0;
113
+ width: 100%;
114
+ /deep/ .att-head {
115
+ display: none;
116
+ }
117
+ /deep/ .att-imgs {
118
+ margin-top: 0;
119
+ }
120
+ &::after {
121
+ border-bottom: none;
122
+ }
123
+ }
124
+ // padding: 0 23px 0 24px;
125
+ /* 以下为废弃的旧样式 */
126
+ display: flex;
127
+ flex-wrap: wrap;
128
+ background: #fff;
129
+ .file-item {
130
+ height: 40px;
131
+ width: 50vw;
132
+ padding-left: 12px;
133
+ position: relative;
134
+ display: flex;
135
+ align-items: center;
136
+ .file-icon {
137
+ width: 21px;
138
+ height: 21px;
139
+ margin-right: 6px;
140
+ }
141
+ .file-name {
142
+ width: 0;
143
+ flex: 1;
144
+ color: #03050d;
145
+ font-size: 14px;
146
+ display: flex;
147
+ align-items: center;
148
+ .name {
149
+ max-width: calc(100% - 40px);
150
+ white-space: nowrap;
151
+ text-overflow: ellipsis;
152
+ overflow: hidden;
153
+ }
154
+ }
155
+ }
156
+ }
157
+ .no-file {
158
+ // height: 44px;
159
+ padding: 0 16px;
160
+ // line-height: 44px;
161
+ text-align: center;
162
+ // background-color: #fff;
163
+ }
164
+ }
165
+ </style>
@@ -0,0 +1,7 @@
1
+ import FmsKsFileView from './fms-ks-file-view.vue'
2
+
3
+ FmsKsFileView.install = function(Vue) {
4
+ Vue.component(FmsKsFileView.name, FmsKsFileView)
5
+ }
6
+
7
+ export default FmsKsFileView
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @description: 转换显示文件大小
3
+ * @param {*} limit 文件大小,单位:b
4
+ * @return {*}
5
+ */
6
+ export function changeFileSize (limit) {
7
+ var size = ''
8
+ if (!limit) {
9
+ return size
10
+ }
11
+ if (limit < 0.1 * 1024) { //小于0.1KB,则转化成B
12
+ size = limit.toFixed(2) + "B"
13
+ } else if (limit < 0.1 * 1024 * 1024) { //小于0.1MB,则转化成KB
14
+ size = (limit / 1024).toFixed(2) + "KB"
15
+ } else if (limit < 0.1 * 1024 * 1024 * 1024) { //小于0.1GB,则转化成MB
16
+ size = (limit / (1024 * 1024)).toFixed(2) + "MB"
17
+ } else { //其他转化成GB
18
+ size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB"
19
+ }
20
+ var sizeStr = size + ""; //转成字符串
21
+ var index = sizeStr.indexOf("."); //获取小数点处的索引
22
+ var dou = sizeStr.substr(index + 1, 2) //获取小数点后两位的值
23
+ if (dou == "00") { //判断后两位是否为00,如果是则删除00
24
+ return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)
25
+ }
26
+ return size;
27
+ }
@@ -0,0 +1,23 @@
1
+ # 附件预览通用组件
2
+ 附件与van-collapse组件合体
3
+
4
+ ## 参数说明
5
+ 1、 **<font size=4>fileList</font>** <font color='#999'>附件集合,每一个对象必须包含extendName、name、bizCode、bizId、id字段。</font><font color='red'>必须</font>
6
+ ```js
7
+ 示例:[
8
+ {
9
+ extendName: '文件后缀',
10
+ name: '文件名',
11
+ bizId: 'bizId',
12
+ bizCode: 'bizCode',
13
+ id: '文件id',
14
+ },
15
+ ...
16
+ ]
17
+ ```
18
+
19
+ ## 参考案例
20
+
21
+ ```js
22
+ <FmsFileView :fileList="fileList" />
23
+ ```
@@ -0,0 +1,91 @@
1
+
2
+ class WaterFall {
3
+ constructor({gap} = {}) {
4
+ this.observer = null
5
+ this.intersectionObserver = null
6
+ this.container = null
7
+ this.refScroll = null
8
+ this.leftHeight = 0
9
+ this.rightHeight = 0
10
+ this.intersectionRatio = 0
11
+ this.gap = gap || [0, 0]
12
+ this.init()
13
+ }
14
+ get containerHeight() {
15
+ return Math.max(this.leftHeight, this.rightHeight)
16
+ }
17
+ init() {
18
+ this.initMutationObserver()
19
+ this.initIntersectionObserver()
20
+ }
21
+ observe(refScroll, container) {
22
+ this.refScroll = refScroll
23
+ this.container = container
24
+ this.observer.observe(container, {
25
+ childList: true
26
+ })
27
+ this.intersectionObserver.observe(this.refScroll)
28
+ container.defaultCssText = container.defaultCssTex || container.style.cssText
29
+ }
30
+ dispose() {
31
+ this.observer.disconnect()
32
+ this.intersectionObserver.disconnect()
33
+ this.container.style.cssText = this.container.defaultCssText
34
+ delete this.container.defaultCssText
35
+ Array.from(this.container.children).forEach(node => {
36
+ node.style.cssText = node.defaultCssText
37
+ delete node.defaultCssText
38
+ delete node.nodeHeight
39
+ })
40
+ }
41
+ initMutationObserver() {
42
+ const observer = new MutationObserver(() => {
43
+ if (this.intersectionRatio === 0) {
44
+ return
45
+ }
46
+ this.handleNode()
47
+ })
48
+ this.observer = observer
49
+ }
50
+ initIntersectionObserver() {
51
+ const intersectionObserver = new IntersectionObserver((entries) => {
52
+ // 如果 intersectionRatio 为 0,则目标在视野外,
53
+ // 我们不需要做任何事情。
54
+ this.intersectionRatio = entries[0].intersectionRatio
55
+ if (entries[0].intersectionRatio <= 0) return;
56
+ this.handleNode()
57
+ });
58
+ this.intersectionObserver = intersectionObserver
59
+ }
60
+
61
+ handleNode() {
62
+ const nodes = Array.from(this.container.children)
63
+ this.leftHeight = 0
64
+ this.rightHeight = 0
65
+ const [gapRow, gapColumn] = this.gap
66
+ nodes.forEach(node => {
67
+ const nodeHeight = node.nodeHeight || node.offsetHeight
68
+ node.nodeHeight = nodeHeight
69
+ const isLeftNode = this.leftHeight <= this.rightHeight
70
+ if (!('defaultCssText' in node)) {
71
+ node.defaultCssText = node.style.cssText
72
+ node.style.cssText = `
73
+ position: absolute;
74
+ width: calc(50% - ${gapColumn / 2}px);
75
+ top: ${isLeftNode ? this.leftHeight : this.rightHeight}px;
76
+ ${isLeftNode ? 'left: 0' : 'right: 0'};
77
+ `
78
+ }
79
+ if (isLeftNode) {
80
+ this.leftHeight += nodeHeight + gapRow
81
+ } else {
82
+ this.rightHeight += nodeHeight + gapRow
83
+ }
84
+ })
85
+ this.container.style.height = this.containerHeight + 'px'
86
+ }
87
+ }
88
+
89
+ export {
90
+ WaterFall
91
+ }