繁体   English   中英

隐藏绝对定位的最佳方法 <div> 什么时候水平滚动?

[英]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元素是一个水平滚动元素,用于保存我的表。


我目前有两个我考虑过的解决方案:

  1. 添加一个侦听器以检查滚动条何时到达右侧(如此示例) ,然后隐藏或淡出渐变。 这个问题是我在页面上有多个这些褪色的表格,我不确定设置这些聆听者的最有效方法是什么。 我正在使用Vue.js,所以我不确定这是否/应该是一个指令,或者只是在页面上为每个表设置一个监听器。
  2. 在表格的右侧添加一些空白区域,这样您可以滚动一点点超过实际表格的末尾,渐变只会混合到背景中。 我已经尝试向表和.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方法查看作为参数传递的元素的scrollLeftoffsetWidthscrollWidth属性,以确定元素是否一直向右滚动,如果是,则将isScrolledRight属性设置为true否则设置为false
  • 组件的根div有一个bound :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%;


  1. 目前强硬到白:

目前有强硬派

  1. 更柔和地过渡到白色:

更柔和的过渡线

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM