javascript - 使用 div 动态显示列,第一列固定,其余列使用水平滚动条

标签 javascript css angular5

我需要你的帮助。

我正在创建一个包含动态列的 N 级嵌套表

所以我想做的是,我想根据用户选择创建一个列数可变的表,为此我创建了一个简单的下拉框,根据下拉选择,那些选定的列将出现在表中

我想要的是表格的第一列应该始终固定,而其他列可以水平滚动,并且这些列的宽度应该根据列显示或隐藏进行调整

我不想使用任何外部库。我创建了一个基于 div 和网格 CSS 的自定义表格

下面是我到目前为止所做的事情的截图

enter image description here

引用代码如下:

HTML:

<ng-container *ngFor="let rData of reportData; let i = index; last as isLast" >
  <div class="myTr report-row">
    <div class="myTd">
        <button 
           class="btn report-btn-sm" 
           *ngIf="checkIfHaveMoreSplits(this.splitOpt[0].id) !== 0 && rData.isCollapsed == true"
           (click)="splitData(rowWiseFilterObj(rData,this.splitOpt[0].id),this.splitOpt[0].id,sFilters,splitOpt,i,rData,selectedDate)"
           row="rData">+</button>
        <button 
           class="btn report-btn-sm" 
           *ngIf="checkIfHaveMoreSplits(this.splitOpt[0].id) !== 0 && rData.isCollapsed == false" 
           (click)="removeDynamicComponent(rData,i)"
           >-</button>
           <span *ngIf="this.splitOpt[0].id == 'campid'">{{rData['campaign_name']}}</span>

          <span *ngIf="this.splitOpt[0].id !== '__time' && this.splitOpt[0].id !== 'campid'">{{rData[this.splitOpt[0].id]}}</span>
          <span *ngIf="this.splitOpt[0].id === '__time'">{{ rData[this.splitOpt[0].id]  | date:'dd-MM-yyyy HH:mm:ss Z'}}</span>


    </div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">{{convertToDecimals(rData.impressions,2)}}</div>
      <div class="myTd">{{convertToDecimals(rData.conversions,2)}}</div>
      <div class="myTd">{{convertToDecimals(rData.bids,2)}}</div>
      <div class="myTd">{{convertToDecimals(rData.wins,2)}}</div>
      <div class="myTd">$ {{convertToDecimals(rData.spend,2)}}</div>
      <div class="myTd">
        <button class="btn btn-secondary m-btn m-btn--label-danger m-btn--label-danger m-btn--bolder m-btn--uppercase btn-sm" *ngIf="this.splitOpt[0].id=='campid'" (click)="excludeReport(rowWiseFilterObj(rData,this.splitOpt[0].id))"> <i class="la la-close"></i> </button>
        <button class="btn btn-secondary m-btn m-btn--label-danger m-btn--bolder m-btn--uppercase btn-sm" disabled="disabled" *ngIf="this.splitOpt[0].id!='campid'"> <i class="la la-ban"></i> </button>

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

  <div *ngIf="isLast" class="text-right col-12">{{altrows("#ffffff","#f5f5f5")}}

            <a href="javascript:void(0)" class="m-link" (click)="loadmore()" style="    margin: 10px -30px 15px 10px;
    background: #5ccdde;
    color: #fff;
    padding: 2px 10px;
    font-size: 12px;" *ngIf="reportData.length > 19"> Load more </a>
        </div>
    <ng-template #dynamic ></ng-template>

    </ng-container>
  <div class="myTr" style="margin-top:20px;">
    <div class="myTd"></div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd"></div>
    </div></div>
  </div>
</div>

JS:

getReport() {
        this.hidePopup();
        if(this.splitOpt.length === 0) {
            // this.updateGraph(this.currentGraphSelection);
            return false;
        } 


        var apiFilters: any = [{}];
        for (var i = 0; i < this.sFilters.length; i++) {
            if (this.sFilters[i].values.length > 0) {
                var k;
                k = this.sFilters[i].id
                apiFilters[0][k] = this.sFilters[i].values
            }
        }

        var split = this.splitOpt[0].id;
        this.reportData=[];
        this.reportLoading = true;
        this._apis.getReportData(split, apiFilters[0],this.selectedDate,1,20).subscribe(response => {
            if (response.status == 1200) {
                this.reportData = response.data.split_by_data;
                this.reportData.map(function(obj) {
                  obj.isCollapsed = true;
                  return obj;
               });
            this.totalImpressions=response.data.totalCount[0].impressions;
            this.totalConversions=response.data.totalCount[0].conversions;
            this.totalBids=response.data.totalCount[0].bids;
            this.totalWins=response.data.totalCount[0].wins;
            this.totalSpend=response.data.totalCount[0].spend;
               this.reportLoading = false;
               var contentGroups = document.querySelectorAll('.myTr:not(:last-child) .myTdGroupBox');
var ctrlGroup = document.querySelector('.myTr:last-child .myTdGroupBox');
ctrlGroup.addEventListener('scroll', (ev)=> {
    contentGroups.forEach((g)=> g.scrollTo(ctrlGroup.scrollLeft, 0) );
});
               this.cd.detectChanges();

            }
        });
    }

最佳答案

您可以使用 <div> 重新制作表格具有 flex 布局。

我在下面写了一个完整的例子。您没有表格的所有灵 active ,但它非常强大。您还可以将列滚动条固定到页面上,并使其始终可见,即使表格大于页面高度也是如此。还有更多...

你会看到,我将所有可滚动列都设置为相同的宽度。您可以设置不同的宽度。我会使用列的类来执行此操作。

我相信代码很容易理解。如果您需要帮助,或者想使用更多 flex 布局的强大功能,您可以查看此页面:https://css-tricks.com/snippets/css/a-guide-to-flexbox/

使所有内容一起移动的 javascript 是这里最简单的事情。这个想法是获取滚动事件并在带有 overflow: hidden 的行应用相同的滚动。 .

要创建新列,就像在 <table> 上创建一样简单, 只是 crate <div>进入.myTdGroup元素。

<style>
  .myTable {
    font-family: sans-serif;
    font-size: 15px;
    width: 450px;
    border: 2px solid #BBB;
    position: relative;
  }
  .myTr {
    display: flex;
    align-items: center;
  }
  .myTr:nth-child(odd) { background: #DDD }
  .myTdGroupBox {
    overflow: hidden;
  }
  .myTdGroup {
    display: flex;
    align-items: center;
    width: 500px;
  }
  .myTr:last-child { background: #777 }
  .myTr:last-child .myTdGroupBox { overflow-x: scroll }
  .myTr:last-child .myTd { padding: .1px 0 0 0 }
  .myTd {
    margin: 0 1em;
    padding: .5em 0;
    flex-grow: 1;
    flex-basis: 50px;
    overflow-x: auto;
    white-space: nowrap;
  }
  .myTr > .myTd { flex-basis: 150px; }
</style>

<div class="myTable">
  <div class="myTr">
    <div class="myTd">Line A</div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">A1</div>
      <div class="myTd">A222</div>
      <div class="myTd">A333</div>
      <div class="myTd">A444</div>
      <div class="myTd">A555</div>
      <div class="myTd">A666</div>
    </div></div>
  </div>
  <div class="myTr">
    <div class="myTd">Line BBBBB</div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">B111</div>
      <div class="myTd">B2</div>
      <div class="myTd">B333</div>
      <div class="myTd">BX<br>444</div>
      <div class="myTd">B555</div>
      <div class="myTd">B666</div>
    </div></div>
  </div>
  <div class="myTr">
    <div class="myTd">Line<br>CCC<br>CCC</div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">C111</div>
      <div class="myTd">C222</div>
      <div class="myTd">C3</div>
      <div class="myTd">C 444 444 444 end</div>
      <div class="myTd">C555</div>
      <div class="myTd">C666</div>
    </div></div>
  </div>
  <div class="myTr">
    <div class="myTd">Line DDD</div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">D111</div>
      <div class="myTd">D222</div>
      <div class="myTd">D333</div>
      <div class="myTd">D444</div>
      <div class="myTd">D555</div>
      <div class="myTd">D666</div>
    </div></div>
  </div>
  <div class="myTr">
    <div class="myTd"></div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd"></div>
    </div></div>
  </div>
</div>

<script>
var contentGroups = document.querySelectorAll('.myTr:not(:last-child) .myTdGroupBox');
var ctrlGroup = document.querySelector('.myTr:last-child .myTdGroupBox');
ctrlGroup.addEventListener('scroll', (ev)=> {
    contentGroups.forEach((g)=> g.scrollTo(ctrlGroup.scrollLeft, 0) );
});
</script>

关于javascript - 使用 div 动态显示列,第一列固定,其余列使用水平滚动条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55631760/

相关文章:

javascript - 如何在 Angular 5 组件中有条件地加载 templateUrl html 文件

javascript - 具有包裹多个组的可选组的正则表达式对于未采用的分支返回未定义

html - 调整网站小部件的宽度和高度 CSS

html - 我的网站的响应问题

angular-material - 垫子表将垫子排序重置为初始状态

javascript - 在 Angular 5 中,如何在没有事件的情况下让组件监听并等待来自另一个组件的数据?

javascript - "return false"在某些浏览器中被忽略,因为链接使用 JavaScript 动态添加到 DOM

javascript - node.js 的 TLS 模块中 '' newSession '' and ' resumeSession' 事件的文档或示例

javascript - phonegap iPhone 应用程序缓存旧数据

javascript - 动态创建 "ul"和 "li"并配置 "radio button"的错误消息