9

大家好,小弟是刚接触vue的小菜鸟,在使用过程中发现一个问题,就是在一个组件上监听scroll事件无效,有滚动操作也没有触发。
监听scroll事件尝试使用了v-on和window addEventListener方法,都不行(同样方法监听touchmove就可以成功),使用方法如下:
通过v-on操作
<template>
<div class="table-container" @scroll=handleScroll>

<div class="headcol">
    <table>
        <thead>
            <tr >
                <td v-for="c in list.header">
                    {{c}}
                </td>
            </tr>
        </thead>
        <tbody>
            <tr  v-for="r in list.rows">
                <td v-for="c in r">
                    {{c}}
                </td>
            </tr>
        </tbody>
    </table>
</div>

</div>
</template>

通过eventlistener操作:

    created() {
        window.addEventListener('scroll', this.handleScroll);
    },

还有一个问题,就是同样在这个组件里注册的touchmove事件handler里读取到的scrollTop一直为0。
另外,就是offsetHeight用document.documentElement.offsetHeight和document.body.offsetHeight一直都获取不到。不知道是什么原因。

通过touchmove事件获取scroTop等相关数值的操作:

        handleTouchMove(e) {
            let scrollTop = document.body.scrollTop;
            let clientHeight = document.body.clientHeight;

            console.log("shoplist scrollTop %d, clientHeight %d“, 
                        scrollTop, clientHeight);
        },

以上两个问题查找了很多文章都没有什么帮助,所以还请大家多指教。感谢感谢。

2017-04-19 提问
12 个回答
19

给后面的人多一个解决方案,第三个参数加上true,能成功监听。window.addEventListener('scroll', this.handleScroll, true);

2

v-on为什么绑定不了滚动事件?
答:可能table-container盒子里面并没有滚动条。
至于addEventListener试试把它写在mounted钩子里看一下,我也不清楚

1

说一下思路

<!--添加ref-->
<div class="headcol" ref="viewBox">
    <table>
        <thead>
            <tr >
                <td v-for="c in list.header">
                    {{c}}
                </td>
            </tr>
        </thead>
        <tbody>
            <tr  v-for="r in list.rows">
                <td v-for="c in r">
                    {{c}}
                </td>
            </tr>
        </tbody>
    </table>
</div>
// 首先通过$refs获取dom元素
this.box = this.$refs.viewBox
// 监听这个dom的scroll事件
this.box.addEventListener('scroll', () => {
  console.log(this.$refs.viewBox.scrollTop)
}, false)
1

vue监听滚动事件要使用@scroll.native="",直接使用@scroll无效,查了很久发现网上的全是利用原生事件监听的,真是坑爹。

0

我也遇到一样的问题了。的确@scroll监听不到。
我按照你说的去监听了touchmove。scrollTop的值也一直是0.
你可以试试window.pageYOffset,我用这个能获取值

0
created() {
        window.addEventListener('scroll', this.handleScroll);
    },
        
        
  这里的this指向window了。
  写成
        created() {
        let _this = this,
        window.addEventListener('scroll', _this.handleScroll);
    },
0

用原生事件就可以监听啊,
<child @scroll.native="scrollHandler"></child>

methods: {

scrollHandler (el) {
    console.log(el)
}

}

0

抄一些前面的代码,需要加nextTick到渲染完成才可以添加

created(){
this.$nextTick(function(){
let box = this.$refs.viewBox
// 监听这个dom的scroll事件
let _this = this
box.addEventListener('scroll', () => {
console.log(this.$refs.viewBox.scrollTop)
this.$refs.viewBox.addEventListener('scroll', _this.handleScroll)
}, false)
}

0

兼容性问题,如果这样,let tpScrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop,打印出来就不是0了。

0

早上也遇到了这个问题 提供一下解决方案吧。
mounted(){

window.addEventListener('scroll',this.loadMore,true);

},
methods:{

loadMore(){
    clearTimeout(this.timer);
    this.timer=setTimeout(()=>{
        var clientHeight=document.documentElement.clientHeight; //document.documentElement获取数据
        var scrollTop=document.documentElement.scrollTop; //document.documentElement获取数据
        var scrollHeight=document.documentElement.scrollHeight;//document.documentElement获取数据
        if(clientHeight+scrollTop+20>=scrollHeight){
            this.pageIndex++;
            this.getBooks();
        }
    },13);

},
数据能完美获取到

0

有一种情况,created()需要在keep-alive包裹之后才会执行,所以查看app.vue中keep-alivevia标签是否有exclude,排除了这个组件对应的路由,去掉这个就可以执行created(),从而会执行scroll事件

0

今天我也刚好遇到这个问题,把它做成了 vue 组件,带滚动动画完美解决,以下是完整代码:

export default {
  name: 'ScrollTop',
  data() {
    return {
      // 定义滚动条默认位置
      scrollTop: null,

      // 定义按钮默认状态
      isScrollTop: false
    }
  },
  props: {
    el: String
  },
  mounted() {
    // 监听滚动事件
    window.addEventListener('scroll', () => {
      this.scrollTop = document.documentElement.scrollTop ||
                        window.pageYOffset ||
                        document.body.scrollTop ||
                        document.querySelector(this.el).scrollTop;

      // 控制滚动按钮的隐藏或显示
      if (this.scrollTop > 150) {
        this.isScrollTop = true;
      } else {
        this.isScrollTop = false;
      }
    }, true);
  },
  methods: {
    /**
     * 滚动到顶部
     */
    scrollToTop() {
      let $this = this;

      // 返回顶部动画特效
      setTimeout(function animation() {
        if ($this.scrollTop > 0) {
          setTimeout(() => {

            // 步进速度
            $this.scrollTop = $this.scrollTop - 30;

            // 返回顶部
            if(document.documentElement.scrollTop > 0) {
              document.documentElement.scrollTop = $this.scrollTop - 30;
            } else if (window.pageYOffset > 0) {
              window.pageYOffset = $this.scrollTop - 30;
            } else if (document.body.scrollTop > 0) {
              document.body.scrollTop = $this.scrollTop - 30;
            } else if (document.querySelector($this.el).scrollTop) {
              document.querySelector($this.el).scrollTop = $this.scrollTop - 30;
            }

            animation();
          }, 1);
        }
      }, 1);
    }
  }
};

撰写答案

你可能感兴趣的

推广链接