VueJS指令计算div是否滚动到底部

时间:2016-12-29 07:14:03

标签: javascript vue.js

我试图制作一个小指令,如果div当前滚动到底部,div将滚动到底部,但如果用户向上滚动则不会滚动到底部,但会继续向下滚动,如果滚动到底部,这是我到目前为止的代码

Vue.directive('scroller', {
  bind: function(el, bindings, vnode) {
  },
  componentUpdated: function(el, bindings, vnode) {
    console.log(el.scrollHeight - el.scrollTop, $(el).outerHeight())
    if (el.scrollHeight - el.scrollTop >= $(el).outerHeight()) {
      // scroll to bottom
    }

    // Leave the scroller alone
  }
});

这是我从控制台日志中获得的

bundle.js:8237 295 251.1875
bundle.js:8237 339 251.1875
bundle.js:8237 383 251.1875
bundle.js:8237 427 251.1875
bundle.js:8237 295 251.1875

如果我一直滚动到底部,我可以得到的最接近的是295,它从

开始

251 251.1875但是一旦溢出开始并且它开始滚动,它似乎保持在295是最接近我可以回到251。

我从

得到了计算结果

Detecting when user scrolls to bottom of div with jQuery

2 个答案:

答案 0 :(得分:0)

如果您想在Vue 2中更简单一些,请添加以下方法:

scrolledToBottom(event){
        var el = event.srcElement
        console.log(el.scrollTop + " " + el.scrollHeight + " " + el.clientHeight)
        if(!this.reachedBottom){
            if(el.scrollTop >= (el.scrollHeight - el.clientHeight)-100){
                this.reachedBottom = true
            }
        } 
    },

然后,在要滚动的元素上,添加一个事件侦听器:

<div @scroll="scrolledToBottom" style="overflow:scroll; max-height:500px;">
<!--content-->
</div>

答案 1 :(得分:-1)

我认为您拥有的delta是因为您必须将div容器高度计入您的计算中。

此外,我减去50可以更快地获得重新激活点。您可以调整此值。仅在那里用户不得完全滚动到最后。

请在下面或fiddle中找到有效的演示文稿。

&#13;
&#13;
Vue.directive('scroller', {
  bind: function(el, bindings, vnode) {
    this.manualScroll = false;
  },
  componentUpdated: function(el, bindings, vnode) {
    console.log('updated', el.scrollHeight - el.scrollTop); //$(el).outerHeight())
    if (el.scrollHeight - el.scrollTop >= el.clientHeight) {
      // scroll to bottom
      if (!this.manualScroll) {
        el.scrollTop = el.scrollHeight - el.clientHeight; // triggers scroll event
      }
    }
  },
  inserted: function(el) {
    el.scrollTop = el.scrollHeight - el.clientHeight;
    // console.log(el.scrollHeight)
    var self = this;
    el.addEventListener('scroll', function(evt) {
      console.log('evt', el.scrollTop);
      self.manualScroll = (el.scrollTop < el.scrollHeight - el.clientHeight - 50);
      console.log('manual scroll', self.manualScroll)
    })
  }
});

Vue.component('DynamicUpdates', {
  template: '<div class="dynamic-container" v-scroller><ul><li v-for="count in counter">{{count}}</li></ul></div>',
  props: {
    counter: Array
  },
  data: function() {
    return {
      updateInterval: null
    };
  },
  computed: {
    count: function() {
      return this.counter.length;
    }
  },
  mounted: function() {
    this.updateInterval = setInterval(this.update, 200);
  },
  methods: {
    update: function() {
      this.counter.push(this.count++);
    }
  },
  beforeDestroy() {
    clearInterval(this.updateInterval);
  }
})

new Vue({
  el: '#app',
  data: {
    counter: [],
    msg: 'hello world'
  }
})
&#13;
.dynamic-container {
  width: 500px;
  height: 150px;
  overflow-y: scroll
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.js"></script>
<div id="app">
  <!--{{msg}}-->
  <button @click="counter=[]">
    restart
  </button>
  <dynamic-updates :counter="counter"></dynamic-updates>
</div>
&#13;
&#13;
&#13;