Angular 7水平滚动时固定列

时间:2019-04-22 12:54:40

标签: html css angular

我有此响应表,希望在左右滚动时该列保持不变。我尝试使用纯CSS来做到这一点,但是没有用。我的CSS使用的是普通的引导程序(4),并且:

.descriptions td,
.product-row td {
    padding: 20px 20px 10px 20px;

    p {
        /* 40px is from the td padding and 30px is from the container padding */
        max-width: calc(100vw - 40px - 30px);
    }
}

.table-product {
    tr:not(.product-row):not(.descriptions) {
        position: relative;
        padding-left: 164px;
    }

    [scope=row] {
        position: absolute;
        left: 0;
        z-index: 10;
    }

    [scope=row],
    td {
        width: 160px;

        .btn-lg {
            padding-right: 20px;
            padding-bottom: 0;
        }

        &.table-product-cell,
        &.table-blank-cell {
            height: 164px;
        }
    }
}

.product {
    .product-title h4 {
        text-align: left;
    }
    .price {
        text-align: right;
        a {
            display: inline-block !important;
        }
    }
}

.btn-group {
    margin: 17px 0 0 5px;

    .btn {
        padding: 0 3px;
    }
}

这是我组件的一部分。我也有一个 _tables.scss 文件,该文件为:

@import '../variables';
@import './mixins';

.table-responsive {
  margin-bottom: 50px;
}

.table .btn {
  white-space: inherit;
}

.table-product {
  @include make-text-sizes($bold-sizes);
  background-color: $white-sky;
  text-align: center;
  font-family: $roboto-slab;
  font-weight: 500;
  color: $silver;
  margin-bottom: 0;

  [scope=row] {
    text-align: left;
    color: $midnight;
    background-color: white;
    display: flex;
    min-width: 160px;

    .btn {
      position: relative;
      padding-right: 40px;
      padding-left: 0;

      span {
        text-align: left;
      }

      .fab,
      .far,
      .fas,
      .ng-fa-icon {
        @include make-text-sizes($h2-sizes);
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        right: 0;
      }
    }
  }

  th,
  td {
    margin: 2px;
    border-top: 0;
    background-color: $clouds;
    min-width: 120px; // TODO: variable maybe?
    min-height: 80px; // TODO: variable maybe?
    flex-shrink: 1;
    padding: 0 0.75rem;

    >div {
      width: 100%;
    }

    &:first-child {
      margin-left: 0;
    }

    &:last-child {
      margin-right: 0;
    }
  }

  .table-active-primary {
    color: white;
    font-weight: 700;
    background-color: $cyan;
  }

  .table-active-secondary {
    color: white;
    background-color: $midnight;
  }

  .table-active-tertiary {
    color: white;
    background-color: $slate;
  }

  .table-blank-cell {
    background-color: $white-sky;
  }

  .table-product-cell {
    background-color: white;
    padding: 0.75rem;

    a {
      display: inline-block;
    }

    &.table-disabled-cell {
      background-color: $white-sky;
      opacity: 0.5;
      .btn {
        opacity: 0;
      }
    }
  }

  .table-disabled-cell {
    opacity: 0.3;
  }

  .descriptions>td,
  .product-row>td {
    color: $midnight;
    display: block;
    background-color: white;
    text-align: left;
  }
}

然后我的组件看起来像这样:

<div class="container">
  <div class="row">
    <div class="col">
      <h1 class="float-left">How they compare</h1>
      <div class="btn-group" role="group" aria-label="Basic example">
        <button class="btn btn-link btn-lg" (mousedown)="scrollLeft()" (mouseup)="mouseup()" (mouseleave)="mouseup()">
          <fa-icon [icon]="['far', 'caret-square-left']"></fa-icon>
        </button>
        <button class="btn btn-link btn-lg" (mousedown)="scrollRight()" (mouseup)="mouseup()" (mouseleave)="mouseup()">
          <fa-icon [icon]=" ['far', 'caret-square-right' ]"></fa-icon>
        </button>
      </div>
    </div>
  </div>

  <section class="row" id="criteria">
    <div class="col">

      <div class="table-responsive" (scroll)="onScroll()" *ngIf="rows" #productTable>
        <table class="table table-borderliness table-product w-auto">
          <tbody>
            <ng-container>
              <tr class="d-flex">
                <td class="d-flex align-items-center justify-content-center col table-blank-cell" scope="row" #cell>
                </td>
                <td class="d-flex align-items-center justify-content-center flex-column col table-product-cell"
                  [class.table-disabled-cell]="index > -1 && index !== i"
                  *ngFor="let product of products; let i = index" #cell>
                  <div>
                    <a href="#" (click)="showProduct(i, $event)">
                      <img class="img-fluid" [src]="product.image" [alt]="product.shortTitle" />
                    </a>
                  </div>
                  <div>
                    <button class="btn btn-link btn-lg" (click)="showProduct(i)">
                      <fa-icon [icon]="['far', 'plus-square']" *ngIf="!active || active.gtin !== product.gtin">
                      </fa-icon>
                      <fa-icon [icon]="['far', 'minus-square']" *ngIf="active && active.gtin === product.gtin">
                      </fa-icon>
                    </button>
                  </div>
                </td>
              </tr>
              <tr class="d-flex product-row" [@animateRow]="state">
                <td class="col" #description>
                  <div class="row" *ngIf="active">
                    <div class="col-md-7 product-title">
                      <h3>{{ active.shortTitle }}</h3>
                      <h4>{{ active.description }}</h4>
                    </div>
                    <div class="col-md-5 price">
                      <p><b class="bold">{{ active.formattedPrice }}</b></p>
                      <pyb-price-button [product]="active"></pyb-price-button>
                    </div>
                  </div>
                </td>
              </tr>
            </ng-container>

            <ng-container *ngFor="let row of rows">
              <tr class="d-flex">
                <td class="d-flex align-items-center justify-content-center col"
                  [class.table-disabled-cell]="index > -1 && index !== (i - 1) && i > 0" [ngClass]="column.class"
                  *ngFor="let column of row.columns; let i = index" [scope]="i ? '' : 'row'" #cell>
                  <div [ngSwitch]="row.description.length && !i">
                    <span *ngSwitchCase="0">{{ column.name }}</span>
                    <span *ngSwitchDefault>
                      <button class="btn btn-link btn-block" (click)="showDescription(column.name, row)">
                        <span class="float-left">{{ column.name }}</span>
                        <fa-icon class="float-right" [icon]="['far', 'plus-square']" *ngIf="row.state === 'out'">
                        </fa-icon>
                        <fa-icon class="float-right" [icon]="['far', 'minus-square']" *ngIf="row.state === 'in'">
                        </fa-icon>
                      </button>
                    </span>
                  </div>
                </td>
              </tr>
              <tr class="d-flex descriptions" [@animateRow]="row.state">
                <td class="col" #description>
                  <div [innerHtml]="row.description"
                    *ngIf="row.description && descriptions.indexOf(row.columns[0].name) > -1"></div>
                </td>
              </tr>
            </ng-container>
          </tbody>
        </table>
      </div>

    </div>
  </section>
</div>

我在单元格上使用了绝对定位,并使表行相对。然后使用(scroll)="onScroll()"来设置表格单元格的位置,如下所示:

onScroll(): void {
  let container = this.productTableElement.nativeElement;
  let scrollLeft = container.scrollLeft;
  if (!scrollLeft) return;

  this.cellElements.forEach((element: ElementRef) => {
    let cell = element.nativeElement;
    if (!cell || !cell.scope) return;

    cell.style.left = `${scrollLeft}px`;
  });
}

我的表/单元格使用ViewChild/ViewChildren进行引用,如下所示:

@ViewChild('productTable') productTableElement: ElementRef
@ViewChildren('description') descriptionElements: QueryList<ElementRef> = new QueryList
@ViewChildren('cell') cellElements: QueryList<ElementRef> = new QueryList

我的问题是,滚动时似乎可以正常工作,但是如果我快速拖动,它并不会总是重置,并且第一列以有趣的位置(在屏幕中间)结束。同样,如果我滚动到起点,也不一定总能领悟到我的起点。

我希望有人做过类似的事情,也许能够帮助我使它更平滑,更坚固?

0 个答案:

没有答案