1 | <template>
|
2 | <div ref="container">
|
3 | <slot v-if="loaded"></slot>
|
4 | </div>
|
5 | </template>
|
6 |
|
7 | <script>
|
8 | export default {
|
9 | data() {
|
10 | return {
|
11 | loaded: false
|
12 | }
|
13 | },
|
14 | mounted() {
|
15 | if (!this.loaded) {
|
16 | if (this.shouldLoad())
|
17 | this.load();
|
18 | else
|
19 | this.bindScrollListener();
|
20 | }
|
21 | },
|
22 | beforeDestroy() {
|
23 | this.unbindScrollListener();
|
24 | },
|
25 | methods: {
|
26 | bindScrollListener() {
|
27 | this.documentScrollListener = () => {
|
28 | if (this.shouldLoad()) {
|
29 | this.load();
|
30 | this.unbindScrollListener();
|
31 | }
|
32 | };
|
33 |
|
34 | window.addEventListener('scroll', this.documentScrollListener);
|
35 | },
|
36 | unbindScrollListener() {
|
37 | if (this.documentScrollListener) {
|
38 | window.removeEventListener('scroll', this.documentScrollListener);
|
39 | this.documentScrollListener = null;
|
40 | }
|
41 | },
|
42 | shouldLoad() {
|
43 | if (this.loaded) {
|
44 | return false;
|
45 | }
|
46 | else {
|
47 | const rect = this.$refs.container.getBoundingClientRect();
|
48 | const docElement = document.documentElement;
|
49 | const winHeight = docElement.clientHeight;
|
50 |
|
51 | return (winHeight >= rect.top);
|
52 | }
|
53 | },
|
54 | load() {
|
55 | this.loaded = true;
|
56 | this.$emit('load', event);
|
57 | }
|
58 | }
|
59 | }
|
60 | </script>
|
61 |
|
62 |
|
63 |
|
64 | componentWillUnmount() {
|
65 | this.unbindScrollListener();
|
66 | } |
\ | No newline at end of file |