【问题标题】:Angular 8 scroll to a fragment, doesn't bring the fragment to the top of the pageAngular 8滚动到片段,不会将片段带到页面顶部
【发布时间】:2019-09-16 17:53:11
【问题描述】:

我有一个链接,通过单击该链接,我想滚动到页面底部的一个片段。当我单击该链接时,该片段正在工作,但它没有将其带到页面顶部。

我尝试使用带有 id 的 div 和 section 来创建片段。但是,它不会将 div 或部分带到页面顶部。

我的应用路由模块中的代码是:

 imports: [
    RouterModule.forRoot(routes, {
    //useHash: true,
    scrollPositionRestoration: 'enabled',
    onSameUrlNavigation: 'reload',
    anchorScrolling: 'enabled'
  })]

我的链接和片段的组件代码:

<a [routerLink]="['/proposal']" fragment="dcn">{{ dcn }}</a>

<section id="dcn">
Some other html here
</section>

注意,我尝试过使用useHash:true,但它似乎不起作用。我希望没有useHash 的解决方案是正确的。

【问题讨论】:

  • 如果片段位于页面底部,并且其下方没有空白,则不会将其带到页面顶部。如果您不能使用鼠标滚轮或滚动条将其置于顶部,JavaScript 将无法做到。
  • 是的,版块里面有内容。实际上,该部分内有一个表格,我可以滚动到该表格。但是,由于表头部分重叠,表头不会显示。我想实现 angular api 站点中的功能:angular.io/api/common/CommonModule#pipes
  • 我已将其作为一个不同的问题提出。链接为:stackoverflow.com/questions/57978281/…

标签: angular typescript angular-router


【解决方案1】:

我使用这样的代码滚动到元素:

HTML:

<button (click)="scroll(target)"></button>
<div #target>Your target</div>

TS:

scroll(el: HTMLElement) {
    el.scrollIntoView();
}

也许这对你有帮助。

记住:要页面滚动到元素,页面必须有足够的内容才生成滚动条/滚动条,否则没有内容可以滚动。

【讨论】:

  • 完全相同的代码不起作用,但我从你的代码中得到了一个想法:)。谢谢。
【解决方案2】:

我遇到了同样的情况,这就是我所做的:

这是我的菜单组件上的链接:

<a class="dropdown-item" routerLink="/products" fragment="product-one">Product One</a>

这就是它在我的 Product 组件上的声明方式... product.component.html

  <div class="anchor">
    <a name="product-one"></a>
    <h2 >Product One</h2><br>
  </div>

product.component.css

.anchor a {
    position: absolute;
    left: 0px;
    top: -10em;
  }
.anchor {
    position: relative;
  }

product.component.ts:

  //TODO: Needs to verify if is necessary to declare Router and ActivatedRoute
  constructor( router: Router,
    private route:ActivatedRoute,) {
   }

考虑到 CSS 的 top 属性相当于菜单的大小。这样,当滚动发生时,它应该在菜单 div 下方显示锚定元素。

希望对你有帮助……

【讨论】:

    【解决方案3】:

    我通过实现自定义滚动恢复行为解决了这个问题。

    这个行为的原因是页面还没有渲染并且scrollToPosition没有效果。

    没有一个很好的超时技巧,但它有效。

    export class AppModule {
      constructor(router: Router, viewportScroller: ViewportScroller) {
        router.events.pipe(
          filter((e): e is Scroll => e instanceof Scroll)
        ).subscribe(e => {
          if (e.position) {
            // backward navigation
            setTimeout(() => {viewportScroller.scrollToPosition(e.position); }, 0);
          } else if (e.anchor) {
            // anchor navigation
            setTimeout(() => {viewportScroller.scrollToAnchor(e.anchor); }, 0);
          } else {
            // forward navigation
            setTimeout(() => {viewportScroller.scrollToPosition([0, 0]); }, 0);
          }
        });
      }
    }
    

    【讨论】:

    • 这对我有用。由于某种原因,我无法弄清楚,页面一直滚动到底部,远远超过了我所针对的片段。这是阻止这种情况的诀窍。谢谢!
    【解决方案4】:

    我的情况略有不同,但我也在寻找与 useHash: true 类似的解决方案。

    我采取了指令的方法,下面是代码。

    指令

    @Directive({
      selector: '[ScrollIntoViewOnClick]'
    })
    export class ScrollIntoViewOnClickDirective {
      constructor(private _elementRef: ElementRef) { }
    
      @HostListener('click', ['$event.target'])
      scrollIntoView() {
        setTimeout(() => {
          document.getElementById(this._elementRef.nativeElement.dataset.sectionId).scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });
        }, 200)
      }
    
      scroll(el: HTMLElement) {
        el.scrollIntoView();
      }
    }
    

    HTML

    <!-- click on here -->
    <a href="javascript:void(0)"
       [attr.data-sectionId]="sectionId"
       ScrollIntoViewOnClick>
      Link
    </a>
    
    <!-- section to scroll -->
    <section #{{sectionId}}
             [id]="sectionId">
      content
    </section>
    
    

    希望这会有所帮助:)

    编码愉快...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多