[英]Have a horizontal scrollbar on the top and bottom of a v-data-table (Vuetify)
what happens is that I have a v-data-table, by default I have a horizontal scrollbar at the bottom, but I want this scrollbar both below and above the table.发生的事情是我有一个 v-data-table,默认情况下我在底部有一个水平滚动条,但我希望这个滚动条在表格下方和上方都有。
I tried to research in several forums and articles but there is no information about this when it comes to a v-data-table.我尝试在几个论坛和文章中进行研究,但是在涉及 v-data-table 时没有关于此的信息。
Technically, a div cannot have more than one scrollbar on the same direction.从技术上讲,一个 div 在同一方向上不能有多个滚动条。
What we can do is create a second element, with dummy content of the same size as the content of the element we want to scroll, and then link the scrolling functions between the two elements.我们可以做的是创建第二个元素,其虚拟内容与我们要滚动的元素的内容大小相同,然后链接两个元素之间的滚动功能。 Simply put, when we scroll one, we also scroll the other.
简单地说,当我们滚动一个时,我们也滚动另一个。
Here's a vanilla implementation, demonstrating the principle:这是一个普通的实现,展示了原理:
window.addEventListener("DOMContentLoaded", () => { const updateScrollers = () => { dummy.style.width = _b.scrollWidth + "px"; }; updateScrollers(); window.addEventListener("resize", updateScrollers); const linkScroller = (a, b) => { a.addEventListener("scroll", (e) => { b.scrollLeft = e.target.scrollLeft; }); }; [ [_a, _b], [_b, _a], ].forEach((args) => linkScroller(...args)); });
#_a, #_b { overflow-x: auto; }.content { height: 100px; width: 200vw; } #_a > div { height: 1px; } #_b.content { background: repeating-linear-gradient( 45deg, #fff, #fff 50px, #f5f5f5 50px, #f5f5f5 80px ); }
<div id="_a"> <div id="dummy"></div> </div> <div id="_b"> <div class="content"></div> </div>
If you need help implementing it in your project, you'll have to create a runnable minimal, reproducible example first.如果您需要帮助在您的项目中实现它,您必须首先创建一个可运行的最小、可重现的示例。
With Vue, all we need to do is update the model value ( onScroll
) and let Vue handle the DOM updates (eg: :scroll-left.camel="scrollLeft"
).使用 Vue,我们需要做的就是更新 model 值(
onScroll
)并让 Vue 处理 DOM 更新(例如: :scroll-left.camel="scrollLeft"
)。
const { createApp, onMounted, onBeforeUnmount, reactive, toRefs } = Vue; createApp({ setup: () => { const state = reactive({ scrolled: null, dummy: null, scrollLeft: 0, onScroll: (e) => (state.scrollLeft = e.target.scrollLeft), }); const updateScroller = () => { state.dummy.style.width = state.scrolled.scrollWidth + "px"; }; onMounted(() => { window.addEventListener("resize", updateScroller); updateScroller(); }); onBeforeUnmount(() => { window.removeEventListener("resize", updateScroller); }); return toRefs(state); }, }).mount("#app");
.scroller, .scrolled { overflow-x: auto; }.scroller > div { height: 1px; }.scrolled span { height: 100px; display: inline-block; width: 200vw; background: repeating-linear-gradient( 45deg, #fff, #fff 50px, #f5f5f5 50px, #f5f5f5 80px ); }
<script src="https://unpkg.com/vue/dist/vue.global.prod.js"></script> <div id="app"> <div class="scroller" @scroll.passive="onScroll":scroll-left.camel="scrollLeft" > <div ref="dummy"></div> </div> <div ref="scrolled" class="scrolled" @scroll.passive="onScroll":scroll-left.camel="scrollLeft" > <span /> </div> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.