Rails使用Turbo事件,如何将页面滚动到底部?
聊天应用里面的,最新消息在最下面显示的时候,如果将当前窗口移动到scroll到底部最新消息的位置呢?
使用javascript可以通过
使用javascript可以通过
<%= turbo_stream_from @conversation %> <div class="chat-room" id="chat-room-container"> <%= turbo_frame_tag "conversation" do %> ................. <% end %> <div class="convo-comments-container-<%= @conversation.id %>" id="conversation_comments"> <%= render @conversation.conversation_comments %> </div> </div> <div class="chat-box"> <%= turbo_frame_tag 'new_conversation_conversation_comment', src: new_conversation_conversation_comment_path(@conversation), target: "_top" %> </div>
$('#conversation_comments').animate({scrollTop: 20000000}, "slow"); const msgs = document.getElementById('conversation_comments'); function getMessages() { // Prior to getting your messages. shouldScroll = msgs.scrollTop + msgs.clientHeight === msgs.scrollHeight; // After getting your messages. if (!shouldScroll) { scrollToBottom(); } } function scrollToBottom() { msgs.scrollTop = msgs.scrollHeight; } scrollToBottom(); // setInterval(getMessages, 2000); document.addEventListener("turbo:render", function (){ getMessages(); }); </script>
但是现在页面并未刷新,上面的js并不能执行。
The Stimulus docs are fairly good on this: Stimulus Reference: Lifecycle Callbacks 43
I found the solution. Stimulus example: smart scroll · GitHub 217
<div data-controller="smart-scroll" data-action="smart-scroll:added->smart-scroll#handleAdded resize->smart-scroll#handleAdded scroll->smart-scroll#handleScroll"> <div data-controller="smart-scroll-item"> aya: an an </div> <div data-controller="smart-scroll-item"> hatate: ni hao </div> <!-- add more smart-scroll-item dynamically... --> </div>
import { Controller } from 'stimulus' import Rails from 'rails-ujs' const observer = new ResizeObserver(entries => { for (let entry of entries) { Rails.fire(entry.target, 'resize') } }) export default class extends Controller { connect() { observer.observe(this.element) this.shouldScroll = true this.scrollToBottom() } disconnect() { observer.unobserve(this.element) } scrollToBottom() { const { scrollHeight, clientHeight, offsetHeight } = this.element if (scrollHeight >= clientHeight) { this.element.scrollTop = scrollHeight - clientHeight } } handleAdded() { const { scrollHeight, clientHeight } = this.element if (clientHeight >= scrollHeight) { this.shouldScroll = true } if (this.shouldScroll) { this.scrollToBottom() } } handleScroll() { const { scrollTop, scrollHeight, clientHeight, offsetHeight } = this.element if (clientHeight >= scrollHeight) { this.shouldScroll = true } else { this.shouldScroll = Math.abs((scrollTop + offsetHeight) - scrollHeight) < 1 } } } smart_scroll_item_controller.js import { Controller } from 'stimulus' import { getParentController } from 'stimulus_utils' import Rails from 'rails-ujs' export default class extends Controller { connect() { const parent = getParentController(this, 'smart-scroll') Rails.fire(parent.element, 'smart-scroll:added') } } stimulus_utils.js export function getParentController(controller, identifier) { const application = controller.application let element = controller.element do { let foundController = application.getControllerForElementAndIdentifier(element, identifier) if (foundController) { return foundController } } while (element = element.parentElement) }
阅读量: 944
发布于:
修改于:
发布于:
修改于: