簡體   English   中英

使用 Vue.js 滾動到 div 的底部

[英]Scroll to bottom of div with Vue.js

我有一個 Vue.js 組件,其中包含多個元素。 當調用組件中的方法時,我想自動滾動到該元素的底部。

基本上,做同樣的事情 但是,我還沒有找到一種方法來獲取組件中的元素並修改scrollTop

我目前正在使用 Vue.js 2.0.8。

2022 簡單、易讀、流暢的滾動能力,而且不會傷害你的大腦……使用el.scrollIntoView()

scrollIntoView()有一些選項,您可以像scrollIntoView({behavior: 'smooth'})一樣傳遞它來獲得開箱即用的平滑滾動,並且不需要任何外部庫。

這是一個小提琴

methods: {
  scrollToElement() {
    const el = this.$refs.scrollToMe;

    if (el) {
      // Use el.scrollIntoView() to instantly scroll to the element
      el.scrollIntoView({behavior: 'smooth'});
    }
  }
}

然后,如果你想在頁面加載時滾動到這個元素,你可以這樣調用這個方法:

mounted() {
  this.scrollToElement();
}

否則,如果您想通過單擊按鈕或其他操作滾動到它,您可以用相同的方式調用它:

<button @click="scrollToElement">scroll to me</button>

滾動一直有效到 IE 8。平滑滾動效果在 IE 或 Safari 中無法開箱即用。 如果需要,這里有一個可用的polyfill,正如評論中提到的@mostafaznv。

據我了解,您想要的效果是在發生某些事情時(例如:將項目添加到列表中)滾動到列表的末尾(或可滾動的div )。 如果是這樣,您可以僅使用純 JavaScript 和 VueJS 選擇器滾動到容器元素的末尾(甚至是它本身的頁面)。

var container = this.$el.querySelector("#container");
container.scrollTop = container.scrollHeight;

我在這個 fiddle中提供了一個工作示例。

每次將項目添加到列表時,列表都會滾動到末尾以顯示新項目。

希望這對您有所幫助。

我嘗試了接受的解決方案,但它對我不起作用。 我使用瀏覽器調試器並發現應該使用的實際高度是clientHeight您必須將其放入updated()掛鈎才能使整個解決方案正常工作。

data(){
return {
  conversation: [
    {
    }
  ]
 },
mounted(){
 EventBus.$on('msg-ctr--push-msg-in-conversation', textMsg => {
  this.conversation.push(textMsg)
  // Didn't work doing scroll here
 })
},
updated(){              <=== PUT IT HERE !!
  var elem = this.$el
  elem.scrollTop = elem.clientHeight;
},
  1. 使用 DOM 元素上的ref屬性進行引用
<div class="content scrollable" ref="msgContainer">
    <!-- content -->
</div>
  1. 您需要設置一個 WATCH
  data() {
    return {
      count: 5
    };
  },
  watch: {
    count: function() {
      this.$nextTick(function() {
        var container = this.$refs.msgContainer;
        container.scrollTop = container.scrollHeight + 120;
      });
    }
  }
  1. 確保您使用正確的 CSS
.scrollable {
  overflow: hidden;
  overflow-y: scroll;
  height: calc(100vh - 20px);
}

這是一個使用ref滾動到div底部的簡單示例。

 /* Defined somewhere: var vueContent = new Vue({ el: '#vue-content', ... */ var messageDisplay = vueContent.$refs.messageDisplay; messageDisplay.scrollTop = messageDisplay.scrollHeight;
 <div id='vue-content'> <div ref='messageDisplay' id='messages'> <div v-for="message in messages"> {{ message }} </div> </div> </div>

請注意,通過將ref='messageDisplay'放在 HTML 中,您可以通過vueContent.$refs.messageDisplay訪問該元素

如果需要支持 IE11 和(舊)Edge,可以使用:

scrollToBottom() {
    let element = document.getElementById("yourID");
    element.scrollIntoView(false);
}

如果您不需要支持 IE11,以下將起作用(更清晰的代碼):

scrollToBottom() {
    let element = document.getElementById("yourID");
    element.scrollIntoView({behavior: "smooth", block: "end"});
}

嘗試vue-chat-scroll

通過 npm 安裝: npm install --save vue-chat-scroll

進口:

import Vue from 'vue'
import VueChatScroll from 'vue-chat-scroll'
Vue.use(VueChatScroll)

app.js之后window.Vue = require('vue').default;

然后使用它:

<ul class="messages" v-chat-scroll>
  // your message/chat code...
</ul>

對於那些沒有在上面找到可行解決方案的人,我相信我有一個可行的解決方案。 我的具體用例是每當有新消息添加到數組時,我想滾動到特定 div 的底部——在我的例子中是一個聊天框。

const container = this.$el.querySelector('#messagesCardContent');
        this.$nextTick(() => {
          // DOM updated
          container.scrollTop = container.scrollHeight;
        });

我必須使用 nextTick 因為我們需要等待 dom 從數據更改中更新,然后再進行滾動!

我只是將上面的代碼放在消息數組的觀察器中,如下所示:

messages: {
      handler() {
        // this scrolls the messages to the bottom on loading data
        const container = this.$el.querySelector('#messagesCard');
        this.$nextTick(() => {
          // DOM updated
          container.scrollTop = container.scrollHeight;
        });
      },
      deep: true,
    }, 

在您發布的相關問題中,我們已經有一種方法可以在純 javascript 中實現這一點,因此我們只需要獲取對要滾動的 dom 節點的 js 引用。

ref屬性可用於聲明對 html 元素的引用,以使它們在 vue 的組件方法中可用。

或者,如果method in the component是某個 UI 事件的處理程序,並且目標與您要在空間中滾動的 div 相關,您可以簡單地將事件對象連同您想要的參數一起傳遞,然后像這樣進行滾動scroll(event.target.nextSibling)

我的應用程序有同樣的需求(具有復雜的嵌套組件結構),但不幸的是我沒有成功使它工作。

最后我使用了vue-scrollto效果很好!

該解決方案對我不起作用,但以下代碼對我有用。 我正在處理帶有message-box類的動態項目。

scrollToEnd() {
            setTimeout(() => {
                this.$el
                    .getElementsByClassName("message-box")
                    [
                        this.$el.getElementsByClassName("message-box").length -
                            1
                    ].scrollIntoView();
            }, 50);
        }

請記住將方法放在mounted()中而不是created()中,並將類message-box添加到動態項中。

setTimeout()對此工作至關重要。 您可以參考https://forum.vuejs.org/t/getelementsbyclassname-and-htmlcollection-within-a-watcher/26478了解更多信息。

這對我有用

this.$nextTick(() => {
   let scrollHeight = this.$refs.messages.scrollHeight
   window.scrollTo(0, scrollHeight)
})

沒有模塊的解決方案:

模板

<div class="scrollable-content" ref="conversations" />

腳本

scrollToBottom() {
  const container = this.$refs.conversations;
  container.scrollTop = container.scrollHeight;
},
scrollToBottom() {
    this.$nextTick(function () {
        let BoxEl = document.querySelector('#Box');
        if(BoxEl)
            BoxEl.scrollTop = BoxEl.scrollHeight;
    });
}

同意盧雷恩·佩雷拉

只是想添加額外的信息

watch: {
    arrayName: {
      handler() {
        const container = this.$el.querySelector("#idName");
        this.$nextTick(() => {
          container.scrollTop = container.scrollHeight;
        });
      },
      deep: true,
    },
  },

然而:

arrayName = 數組名稱

idName = id 屬性必須添加到您希望滾動條在 arrayName 長度增加時自動向下滾動的 div 中。

  scrollToElement() {
    const element = this.$refs.abc; // here abc is the ref of the element

    if (element) {
      el.scrollIntoView({behavior: 'smooth'});
    }
  }
}

在這里,您需要將 ref 用於要在滾動時顯示的特定 div 或元素。

如果你有一張桌子,並且你想找到桌子的最后一行,那么你必須使用 -

element.lastElementChild.scrollIntoView({behaviour:'smooth'})

這並不是說如果您將元素異步添加到表中,那么您必須處理它。 您可以使用 setTimeout 對其進行測試,如果這有什么不同的話。

例如

    const element = this.$refs.abc;
    if (element) {
      setTimeout(() => {
        element.lastElementChild.scrollIntoView({behaviour:'smooth'})
      }, 1000);

    }
  }

用您自己的異步邏輯替換設置超時。

使用組合 API 和 TypeScript


我將參數scrollTop設置為scrollHeight API 中的HTMLDivElment

<template>
 <div id="container" ref="comments">
  Content ...
 </div>
</template>
<script lang="ts>
import { defineComponent, ref, Ref, watchEffect } from 'vue'

export default defineComponent({
 setup() {
  const comments: Ref<null | HTMLDivElement> = ref(null)

  watchEffect(() => {
   if(comments.value) {
    comments.value.scrollTop = comments.value.scrollHeight
   }
  })

  return {
   comments
  }
 }
})
</script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM