exposure.vue 2.45 KB
<template>
    <div class="exposure" ref="exposure">
        <slot></slot>
    </div>
</template>
<script>
    import _ from 'lodash';
    import yoho from 'yoho';
    import util from 'common/util';

    export default {
        name: 'Exposure',
        props: {
            topClassName: {
                type: String,
                default: 'top-filter'
            }
        },
        data() {
            return {
                viewArea: {
                    top: 0,
                    bottom: 0
                }
            };
        },
        watch: {
        },
        methods: {
            checkReport() {
                // 顶部区域可能切换显示和隐藏所以动态获取
                const topRect = document.querySelector(`.${this.topClassName}`).getBoundingClientRect();

                // 可见区域顶部距离视口的上边的距离
                this.viewArea.top = topRect.bottom;

                // 可见区域底部距离视口的上边的距离
                this.viewArea.bottom = window.screen.height;

                let children = _.filter(this.$children, child => {
                    return child.$options.name === 'ExposureItem'
                });

                _.each(children, child => {
                    return child.record(this.isVisible(child.$el))
                });
            },
            isVisible($el) {
                const rect = $el.getBoundingClientRect();

                return ((rect.top > this.viewArea.top && rect.top < this.viewArea.bottom) ||
                rect.bottom > this.viewArea.top && rect.bottom < this.viewArea.bottom)
            }
        },
        created() {
        },
        mounted() {
            let timer = setInterval(() => {
                this.$scrollEl = window;
                this.scrollEvent = util.throttle(50, this.checkReport);
                if (this.$scrollEl) {
                    this.$scrollEl.addEventListener('scroll', this.scrollEvent);
                }

                if (this.$children.length) {
                    clearInterval(timer);
                    this.checkReport(void 0, true);
                }
            }, 500);

            let reportTimer = setInterval(() => {
                if (!this.$children.length) { return clearInterval(reportTimer); }
                _.each(_.filter(this.$children, child => child.$options.name === 'ExposureItem'), child => child.report());
            }, 3000);
        }
    };
</script>
<style>
</style>