scroll inst上的固定标题在角度应用程序

时间:2018-05-21 14:53:10

标签: html angular

我正在尝试在我的角度应用程序中对我的页面应用固定标题,并且无法让它完全正常工作。因此,当前如果用户在页面上展开手风琴并向下滚动,则标题会得到修复,但是当页面折叠或向上滚动时,标题应该是正常的。所以我编写的代码逻辑在一个时间点工作,但是当所有的手风琴都被打开时失败了。我觉得this.stickyTabsOffset值没有正确设置存在问题。

因此,当用户向下滚动标签标题时,div(标签下方的黑色部分)应在到达窗口顶部时固定。在ngAfterViewInit方法中,我调用getelementById和两个元素:strategyTabs(标签的div id)和stragegyDetails(黑色部分的div id),然后设置this.stickyTabsOffset = this.stickyTabs.offsetTop;我也试过以下

this.stickyTabsOffset = this.stickyTabs.offsetHeight + this.strategyDetails.offsetHeight;
this.stickyTabsOffset = this.stickyTabs.offsetTop + this.strategyDetails.offsetTop;

当手风琴处于关闭状态时的屏幕截图。

enter image description here

import { Component, OnInit , AfterViewInit, HostListener } from '@angular/core';

 export class ResultsComponent extends Base.ReactiveComponent implements OnInit, AfterViewInit {

    @HostListener('window:scroll', [])
        onWindowScroll() {
            if (window.pageYOffset >= this.stickyTabsOffset) {
                this.stickyTabs.classList.add('sticky');
                this.strategyDetails.classList.add('fix-Container');
            } else {
                this.stickyTabs.classList.remove('sticky');
                this.strategyDetails.classList.remove('fix-Container');
            }
        }

        ngAfterViewInit() {
            const interval = setInterval(() => {
                this.stickyTabs = document.getElementById('strategyTabs') as any;
                this.strategyDetails = document.getElementById('strategyDetails') as any;
                if (this.stickyTabs && this.stickyTabs !== 'undefined' ) {
                    this.stickyTabsOffset = this.stickyTabs.offsetTop;
                    clearInterval(interval);
                }
            }, 500);
        }
}

CSS

.sticky {
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 999999;
  }

  .fix-Container {
    position: fixed;
    top: 75px;
    z-index: 1;
  }

5 个答案:

答案 0 :(得分:5)

对于这类东西,我使用这样的东西:

T
// component.ts

navFixed: boolean = false;
private scrollOffset: number = 70;

@HostListener('window:scroll')
onWindowScroll() {
  this.navFixed = (window.pageYOffset 
    || document.documentElement.scrollTop 
    || document.body.scrollTop || 0
  ) > this.scrollOffset;
}
<!-- component.html -->

<header [class.fixed]="navFixed">
  <!-- Header content -->
</header>
<main>
  <router-outlet></router-outlet>
</main>

希望这有点帮助:)

答案 1 :(得分:0)

如果您不需要支持IE,可以在CSS中使用position: sticky

这是一个例子: https://www.w3schools.com/cssref/tryit.asp?filename=trycss_position_sticky

答案 2 :(得分:0)

将标题组件放入 app.component 之后,添加路由器插座

<div>
  <div>
    <app-header></app-header>
   </div>
   <div>
  <router-outlet></router-outlet>
   </div>
</div>

希望这会对你有所帮助。

答案 3 :(得分:0)

前段时间,我决定停止依靠固定职位并创建自己的职位。这实际上在Angular中非常有用。

诀窍是创建一个带有隐藏溢出的容器,它会占用你的所有页面,并在其中创建可能溢出的其他容器。

您可以使用弹性布局或计算布局。方法如下:

/* LAYOUT STYLE (SIDE BY SIDE) */

.main-container {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  width: 100%;
  height: 100%;
}

/* FLEX LAYOUT (LEFT SIDE) */

.flex-layout {
  background: bisque;
  flex: 0 0 50%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
}

.flex-layout header {
  flex: 0 0 50px;
}

.flex-layout content {
  flex: 1 0 auto;
  height: 0px;
}

.flex-layout footer {
  flex: 0 0 50px;
}

/* OLD LAYOUT (RIGHT SIDE) */

.old-layout {
  background: aliceblue;
  flex: 0 0 50%;
  position: relative;
}

.old-layout header {
  height: 50px;
  position: absolute;
  top: 0;
  width: 100%;
}

.old-layout content {
  position: absolute;
  top: 50px;
  bottom: 50px;
  width: 100%;
}

.old-layout footer {
  height: 50px;
  position: absolute;
  bottom: 0;
  width: 100%;
}

/* COMMON STYLING CODE */

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
}

* { box-sizing: border-box; font-family: Helvetica; font-weight: bold; text-transform: uppercase; }

header {
  display: flex;
  justify-content: center;
  align-items: center;
  border-bottom: 1px solid #ddd;
}

content {
  background: white;
  opacity: 0.75;
  border-bottom: 1px solid #ddd;
  overflow-y: auto;
}

footer {
  background: black;
  opacity: 0.20;
  
}

.content {
  height: 300%;
}
<div class="main-container">
 <div class="flex-layout">
   <header>Flex layout</header>
   <content><div class="content"></div></content>
   <footer></footer>
 </div>
 <div class="old-layout">
   <header>Old layout</header>
   <content><div class="content"></div></content>
   <footer></footer>
 </div>
</div>

正如你在这个(非常小的)片段中看到的那样,固定位置是模拟的,但仍然表现得像它应该的那样。

(滚动条设置为自动,如果内容未占用所有空间,则会隐藏它们)

答案 4 :(得分:0)

您应该在滚动事件中定位元素,而不是间隔。当滚动事件触发时,无法保证间隔将获得当前元素定位,这意味着元素定位将是错误的。

该行

if (window.pageYOffset >= this.stickyTabsOffset)

应该是

if (window.pageYOffset > this.stickyTabsOffset)

因为如果你修改标签,它们的偏移量就会变为0,如果你滚动到页面顶部,pageYOffset也会变为零,这意味着else永远无法激活以重置元素的位置。

我抓住你的代码并将其转换成一些简单的,普通的JS和HTML。

<body>
    <div style="position: static; top:30px; height: 300px; width: 300px; background-color:green"></div>
    <div id="test" style="position: static; top:0px; height: 300px; width: 300px; background-color:red"></div>
    <div style="position: static; top:30px; height: 300px; width: 300px; background-color:purple"></div>
    <div style="position: static; top:30px; height: 300px; width: 300px; background-color:yellow"></div>
    <div style="position: static; top:30px; height: 300px; width: 300px; background-color:gray"></div>
    <div style="position: static; top:30px; height: 300px; width: 300px; background-color:blue"></div>
</body>

这是JS。我复制了尽可能多的代码。

<script>
    window.onscroll = function() {
        if ( window.pageYOffset > document.getElementById("test").offsetTop ) {
            document.getElementById("test").style.position = "fixed";
        } else {
            document.getElementById("test").style.position = "static";
        }
    }
</script>

你不应该修复两个元素。将两个元素包装到一个元素中然后修复该元素。另外 - 你可能会在其他地方照顾这个,但我提到它是为了任何流浪的人的启发 - 当你用position:fixed从文档流中删除一个元素时,它的先前空间不再被占用,这意味着页面的内容将经历一个不稳定的回流。将要修复的元素放置在具有 not 固定的设置高度的父元素中。这可以防止页面回流。

同样,我不确定你是否在其他地方这样做,但我认为值得一提的是直接访问文档是不好的做法。你应该改为injecting the Angular DOCUMENT token