在带有 <router outlet> 的 Angular 4 中 - 在主/详细容器滚动时,如何控制侧栏或左侧 div 的导航/滚动

Posted

技术标签:

【中文标题】在带有 <router outlet> 的 Angular 4 中 - 在主/详细容器滚动时,如何控制侧栏或左侧 div 的导航/滚动【英文标题】:In Angular4 with <routeroutlet> - On scroll of main/detail container, How to control navigation/scroll of side bar or left div 【发布时间】:2017-07-16 23:56:16 【问题描述】:

在滚动主/细节容器(div)时,如何控制侧边栏或左侧 div 的导航/滚动。虽然我在 Div 上没有单独的滚动条。我想在主窗口滚动而不是在 div 上控制此行为,因为我不想将任何滚动应用于 div。在下面找到详细信息-

    我尝试使用 Bootstrap "container-Fluid" 但无法获得任何预期结果。 比我使用 Angular 指令的 smth 滚动移动。但是,当我滚动窗口时我看不到滚动事件,但是当我滚动右侧 div 时触发了滚动事件,我当然不想使用它,因为我不想明确地使用带有滚动的 div 而不是我想要的使用主路由器出口滚动。

现在的问题是如何设置偏移量并决定我现在在哪个部分,并相应地移动左div的指针或滚动。 (请注意,在我的问题中,我使用了固定大小的 div,但在原始代码中,大小不是固定的。唯一的标识符是与左侧类别部分匹配的部分开头的 ID)。现在如何在指令上使用 DOCUMENT 组件并突出显示左侧类别菜单的相应元素。

角度指令 ->

import  Component, Inject, OnInit  from "@angular/core";
import  DOCUMENT  from '@angular/platform-browser';
import Directive, HostListener from '@angular/core';
@Directive(
    selector:'[scroller]'
)

export class ScrollingDirective
    public navIsFixed: boolean = false;
    constructor( @Inject(DOCUMENT) private document: Document)  
    @HostListener('scroll') scrolling() 
        console.log('Scrolled1...');
      
    

    @HostListener("window:scroll", [])
    onWindowScroll() 
        console.log('Scrolled2...');
    

enter image description herehtml 页面 ->

<style>
    .full-width
    width: 100%;
    height: 50%;


    .double-width
    width:100%;
    height: 50%;
   
    #section1 
        color: #fff;
        background-color: #1E88E5;
    

    #section2 
        color: #fff;
        background-color: #673ab7;
    

    #section3 
        color: #fff;
        background-color: #ff9800;
    

    #section41 
        color: #fff;
        background-color: #00bcd4;
    

    #section42 
        color: #fff;
        background-color: #009688;
    

    @media screen and (max-width: 810px) 
        #section1, #section2, #section3, #section41, #section42 
            margin-left: 150px;
        
    
</style>
<div class="full-width" scroller>
    <div class="double-width">
    <div data-spy="scroll" data-target="#myScrollspy" data-offset="20" scroller>
    <div class="container" scroller>
        <div class="row">
            <nav class="col-sm-3" id="myScrollspy">
                <ul class="nav nav-pills nav-stacked" scroller>
                    <li class="active"><a href="#section1">Section 1</a></li>
                    <li><a href="#section2">Section 2</a></li>
                    <li><a href="#section3">Section 3</a></li>
                    <li class="dropdown">
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">Section 4 <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#section41">Section 4-1</a></li>
                            <li><a href="#section42">Section 4-2</a></li>
                        </ul>
                    </li>
                </ul>
            </nav>
            <div class="col-sm-9">
                <div id="section1">
                    <h1>Section 1</h1>
                    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
                </div>
                <div id="section2">
                    <h1>Section 2</h1>
                    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
                </div>
                <div id="section3">
                    <h1>Section 3</h1>
                    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
                </div>
                <div id="section41">
                    <h1>Section 4-1</h1>
                    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
                </div>
                <div id="section42">
                    <h1>Section 4-2</h1>
                    <p>Try to scroll this section and look at the navigation   
                             list while scrolling!</p>
                </div>
            </div>
        </div>
    </div>
</div>    
</div>
</div>

【问题讨论】:

【参考方案1】:

在对我决定的方法进行了一些试验和错误之后,我找到了解决方案,并且它在所有浏览器上都运行得非常好。 Chrome 和 Edge 对“javascript For 循环”有不同的实现。但是识别行为并修复它也很棒......请找到以下步骤以在 Angular“”中实现自定义滚动。 1. 在子屏幕上的父 div 上应用指令选择器(即滚动条),它必须使用此滚动。 2. 将类“scrlSpy”应用于侧导航栏链接或项目的所有元素,并为sidenav 容器提供id“sidenav”。 3. 同样将“contentSpy”类应用到右侧主容器的每个部分。并将 id 应用于容器,即“contentCol”。 4. html 页面就是这样。 5. 现在只需复制以下指令代码并通过引用您的组件或共享组件开始使用它。 注意:-确保您已通过“活动”类装饰将您的第一个元素标记为活动。否则,如果类名不同,请扭曲您的代码。

import Directive, HostListener, Inject from '@angular/core';
import  DOCUMENT  from '@angular/platform-browser';

@Directive(
    selector: '[scroller]'
)

export class ScrollingDirective 
    allEle: any;
    allContent: any;
    i: number;
    activeEle: number;
    constructor( @Inject(DOCUMENT) private document: Document) 

    
    ngOnInit() 
        this.allEle = this.document.getElementsByClassName('scrlSpy');
        this.allContent = this.document.getElementsByClassName('contentSpy');
        this.i = 0;
    

    @HostListener("window:scroll", ['$event'])
    onWindowScroll(event) 
        let sideNav = this.document.getElementById('sidenav');
        let contentCol = this.document.getElementById('contentCol');
        let scrollOffset = this.document.body.scrollTop;
        let j: number = 0;
        let contentCollection: any[];
        this.activeEle = 0;
        if (scrollOffset > 100) 
            sideNav.classList.add("sideNaveMargintop");
            contentCol.classList.add("fltRight");
        
        else 
            contentCol.classList.remove("fltRight");
            sideNav.classList.remove("sideNaveMargintop");
        
        for (let ele in this.allEle) 
            if (ele != null && j < this.allEle.length) 
                var element = this.document.getElementById(this.allEle[ele].id).classList.contains("active");
                if (element === true) 
                    break;
                
                this.activeEle++;
            
        
        for (let cont in this.allContent) 
            if (cont != null && this.i < this.allContent.length && this.i > 0 && 
                this.activeEle < this.allContent.length - 1) 
                let contentEle = this.document.getElementById(this.allContent[cont].id);                
                if (contentEle != null) 
                    if (scrollOffset >= this.allContent[this.activeEle + 1].offsetTop) 
                        this.document.getElementById(this.allEle[this.activeEle].id).classList.remove("active");
                        this.document.getElementById(this.allEle[this.activeEle + 1].id).classList.add("active");
                    
                    else if (scrollOffset <= this.allContent[this.activeEle].offsetTop && this.activeEle - 1 >= 0) 
                        this.document.getElementById(this.allEle[this.activeEle].id).classList.remove("active");
                        this.document.getElementById(this.allEle[this.activeEle - 1].id).classList.add("active");
                    
                
            
            else if (this.allContent.length - 1 == this.activeEle && scrollOffset <= this.allContent[this.activeEle].offsetTop) 
                this.document.getElementById(this.allEle[this.activeEle].id).classList.remove("active");
                this.document.getElementById(this.allEle[this.activeEle - 1].id).classList.add("active");
            
            this.i++;
        

        this.i = 0;
        j = 0;
    

【讨论】:

以上是关于在带有 <router outlet> 的 Angular 4 中 - 在主/详细容器滚动时,如何控制侧栏或左侧 div 的导航/滚动的主要内容,如果未能解决你的问题,请参考以下文章

ng2中router-outlet用法

Angular 之 named outlet

Angular `<router-outlet>` 显示模板两次

Angular 2 与 <router-outlet> 组件通信

Angular 2 Activatedroute 参数在服务中或 <router-outlet> 之外不起作用

ion-router-outlet 未显示组件,但 router-outlet 显示