[英]Best approach to hide an absolutely positioned <div> when horizontally scrolling?
我有一个关于我目前工作的例子: https : //jsfiddle.net/pv5xroLc/
我的问题是,当我的示例中的表完全滚动到右侧时,即使无法进一步滚动,淡入渐变仍然覆盖了我的表的一部分,因此它使得最后一列更难以阅读。 我想知道隐藏这个渐变的最佳解决方案是什么,同时仍然清楚表明该表可以水平滚动(这将出现在移动设备上)。
目前,我的html结构如下:
<div class="fader">
<div class="scrollable">
*content*
</div>
</div>
.fader
元素有一个::after
伪元素,其上包含“fader”,它是一个绝对定位的元素,我用它来表示元素可以水平滚动。 .scrollable
元素是一个水平滚动元素,用于保存我的表。
我目前有两个我考虑过的解决方案:
.scrollable
元素添加填充和边距,但它不会在表后添加任何额外的空格。 如果有人对他们认为我应该做的事情提出建议,我们将不胜感激。
如果我需要实现这个功能,我会创建一个Vue组件,它将接收slot
中的表内容(或任何内容),然后监听.scrollable
div的scroll事件,添加或删除faded ::after
内容如果div一直向右滚动。
这是一个例子:
Vue.component('fader', {
template: `
<div class="fader" :class="{ 'scrolled-right': isScrolledRight }">
<div class="scrollable" ref="scrollable">
<slot></slot>
</div>
</div>
`,
data() {
return {
isScrolledRight: false,
}
},
methods: {
onScroll(event) {
this.updateIsScrolledRight(event.target);
},
updateIsScrolledRight({ scrollLeft, offsetWidth, scrollWidth }) {
this.isScrolledRight = (scrollLeft + offsetWidth) === scrollWidth;
}
},
mounted() {
this.$refs.scrollable.addEventListener('scroll', this.onScroll);
this.updateIsScrolledRight(this.$refs.scrollable);
},
destroyed() {
this.$refs.scrollable.removeEventListeneer('scroll', this.onScroll);
}
})
.fader.scrolled-right::after {
opacity: 0;
}
以下是组件的工作原理:
ref
属性被添加到.scrollable
div中,以便可以在组件的脚本中轻松引用它。 mounted
时, onScroll
方法附加到scrollable
ref的scroll事件,并在组件被destroyed
时被移除。 onScroll
方法调用updateIsScrolledRight
方法, updateIsScrolledRight
传递scroll事件的target
( .scrollable
div)。 updateIsScrolledRight
方法查看作为参数传递的元素的scrollLeft
, offsetWidth
和scrollWidth
属性,以确定元素是否一直向右滚动,如果是,则将isScrolledRight
属性设置为true
否则设置为false
。 :class
属性,如果isScrolledRight
值为true
,它将向div添加scrolled-right
类。 .scrolled-right
类将div的::after
内容设置为opacity: 0;
。 updateIsScrolledRight
方法也在mounted
钩子中调用,这样,如果<slot>
的内容不够宽,不需要滚动条,那么在这种情况下也将删除淡入淡出。 这是一个完整的工作示例:
Vue.component('fader', { template: ` <div class="fader" :class="{ 'scrolled-right': isScrolledRight }"> <div class="scrollable" ref="scrollable"> <slot></slot> </div> </div> `, data() { return { isScrolledRight: false, } }, methods: { onScroll(event) { this.updateIsScrolledRight(event.target); }, updateIsScrolledRight({ scrollLeft, offsetWidth, scrollWidth }) { this.isScrolledRight = (scrollLeft + offsetWidth) === scrollWidth; } }, mounted() { this.$refs.scrollable.addEventListener('scroll', this.onScroll); this.updateIsScrolledRight(this.$refs.scrollable); }, destroyed() { this.$refs.scrollable.removeEventListeneer('scroll', this.onScroll); } }) new Vue({ el: "#app", })
.fader { position: relative; width: 90%; margin-left: 46px; } .fader::after { content: ""; position: absolute; z-index: 1; top: 0; right: -1px; bottom: 15px; pointer-events: none; background: linear-gradient(to right, rgba(255, 255, 255, 0.1), white); width: 10%; opacity: 1; transition: opacity .2s ease-out; } .fader .scrollable { white-space: nowrap; overflow-x: scroll; position: relative; } .fader.scrolled-right::after { opacity: 0; } .breakdown-title { font-size: 14px; font-weight: 700; text-align: center; margin: 8px auto; } table { font-size: 12px; margin: auto; color: #000; width: 100%; table-layout: fixed; } table thead { color: #fff; background-color: #da291c; } table thead th { width: 75px; text-align: right; } table thead th:first-of-type { width: 120px; padding-left: 4px; } table thead th:last-of-type { width: 80px; padding-right: 4px; } table tbody tr:nth-of-type(odd) { background-color: #fce9e8; } table tbody td { width: 75px; text-align: right; } table tbody td:first-of-type { width: 120px; text-align: left; padding-left: 4px; } table tbody td:last-of-type { width: 80px; padding-right: 4px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <fader> <div class="breakdown-title">Total Revenue Bonus</div> <table> <thead> <tr> <th></th> <th>Oct</th> <th>Nov</th> <th>Dec</th> <th>Jan</th> <th>Feb</th> <th>Mar</th> <th>Apr</th> <th>May</th> <th>Jun</th> <th>Jul</th> <th>Aug</th> <th>Sep</th> <th>Year End</th> </tr> </thead> <tbody> <tr> <td>YTD Target</td> <td>$1,325,705</td> <td>$2,651,410</td> <td>$3,977,115</td> <td>$5,302,821</td> <td>$6,628,526</td> <td>$7,954,231</td> <td>$9,279,936</td> <td>$10,605,642</td> <td>$11,931,347</td> <td>$13,257,052</td> <td>$14,582,757</td> <td>$15,908,463</td> <td>$15,908,463</td> </tr> <tr> <td>YTD Actual</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> <td>$19,956</td> </tr> <tr> <td>% to Target</td> <td>2%</td> <td>1%</td> <td>1%</td> <td>0%</td> <td>0%</td> <td>0%</td> <td>0%</td> <td>0%</td> <td>0%</td> <td>0%</td> <td>0%</td> <td>0%</td> <td>0%</td> </tr> </tbody> </table> </fader> </div>
(我宁愿评论OP而非回答,但它不会让我发表评论,因为我太新了,所以道歉。)
我以前处理过类似这样的事情,而且我的快速黑客遵循你上面的#2解决方案的想法是在<th>Year End</th>
之后添加另一个<th>
<th>Year End</th>
,然后用适当的宽度来匹配渐变淡化。 然后你可以决定是否在它下面放入空白<td>
。
我还注意到你的白色渐变在它开始时有一条非常纯的白线(正好在“9美元”之上) - 你可以通过添加更多的参考点来平滑你的SCSS第15/16行(我花了一些时间来计算这个在当天回来,只是包括以防它有用):
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.2), white);
width: 30%;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.