2017-08-21 47 views
4

我已经构建了一个Angular 4 web应用程序。当我移动鼠标时,我希望我的导航栏自动隐藏。有一个例子,我想使用https://codepen.io/JFarrow/pen/fFrpg。我看了一些网上的文件,但我仍然无法弄清楚如何。这里是我的navmenu.component.html代码:wep app的隐藏侧导航栏

<meta http-equiv="pragma" content="no-cache" /> 

<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> 
<script type="text/javascript" src="jquery-1.8.3.js"></script> 

<div class='main-nav'> 
    <div class='navbar navbar-inverse'> 
     <div class='navbar-header'> 
      <a class='navbar-brand' [routerLink]="['/home']">Navbar</a> 
      <button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'> 
       <span (click)="isCollapsed = !isCollapsed">Toggle navigation</span> 
       <span class='icon-bar'></span> 
       <span class='icon-bar'></span> 
       <span class='icon-bar'></span> 
       <span class='icon-bar'></span> 
      </button> 
     </div> 
     <div class='clearfix'></div> 
     <div class='navbar-collapse collapse' > 
       <ul class='nav navbar-nav'> 
        <li [routerLinkActive]="['link-active']"> 
         <a [routerLink]="['/home']"> 
          <span class='glyphicon glyphicon-home'></span> Home 
         </a> 
        </li> 
        <li [routerLinkActive]="['link-active']"> 
         <a [routerLink]="['/login']"> 
          <span class='glyphicon glyphicon-log-in'></span> Log In 
         </a> 
        </li> 
        <li [routerLinkActive]="['link-active']"> 
         <a [routerLink]="['/margin']"> 
          <span class='glyphicon glyphicon-list'></span> Report 
         </a> 
        </li> 
        <li [routerLinkActive]="['link-active']"> 
         <a [routerLink]="['/smart-table']"> 
          <span class='glyphicon glyphicon-list'></span> Smart table 
         </a> 
        </li> 
       </ul> 
</div> 
    </div> 
</div> 

而且我navmenu.component.ts:

import { Component } from '@angular/core'; 

@Component({ 
    selector: 'nav-menu', 
    templateUrl: './navmenu.component.html', 
    styleUrls: ['./navmenu.component.css'] 
}) 
export class NavMenuComponent { 
    public isCollapsed: boolean = false; 

    public collapsed(event: any): void { 
     console.log(event); 
    } 

    public expanded(event: any): void { 
     console.log(event); 
    } 
} 

而且我navmenu.component.css:

li .glyphicon { 
    margin-right: 10px; 
} 

/* Highlighting rules for nav menu items */ 
li.link-active a, 
li.link-active a:hover, 
li.link-active a:focus { 
    background-color: #4189C7; 
    color: white; 
} 

/* Keep the nav menu independent of scrolling and on top of other items */ 
.main-nav { 
    position: fixed; 
    top: 0; 
    left: 0; 
    right: 0; 
    z-index: 1; 
} 

@media (min-width: 768px) { 
    /* On small screens, convert the nav menu to a vertical sidebar */ 
    .main-nav { 
     height: 100%; 
     width: calc(25% - 20px); 
    } 
    .navbar { 
     border-radius: 0px; 
     border-width: 0px; 
     height: 100%; 
    } 
    .navbar-header { 
     float: none; 
    } 
    .navbar-collapse { 
     border-top: 1px solid #444; 
     padding: 0px; 
    } 
    .navbar ul { 
     float: none; 
    } 
    .navbar li { 
     float: none; 
     font-size: 15px; 
     margin: 6px; 
    } 
    .navbar li a { 
     padding: 10px 16px; 
     border-radius: 4px; 
    } 
    .navbar a { 
     /* If a menu item's text is too long, truncate it */ 
     width: 100%; 
     white-space: nowrap; 
     overflow: hidden; 
     text-overflow: ellipsis; 
    } 
} 

而我不知道应该在哪里添加代码。有关于添加js函数的网上代码,或使用一些buid在引导程序功能,只是不适合我....

感谢您的帮助。

+0

我也使用webpack ...万一有帮助.. == – Rachel

回答

1

有几种方法可以做到这一点,但这里是我如何做到这一点。您需要在整个页面或页面的主体/内容部分添加滚动事件侦听器。如果页面的内容部分是它自己的组件,并且导航栏是它自己的独立组件,那么您可能会有一个类似这样的模板。

<navbar-component></navbar-component> 
<content-component></content-component> 

在这种情况下,你可以滚动侦听器添加到触发一些变量,而滚动发生的内容组件,然后滚动停止时返回它(假设这是你想要的行为)。要做到这一点,您可能需要在滚动过程中使用去抖动和超时。是这样的:

<content-component (scroll)="scrollFunction()"></content-component> 

.... and then somewhere in the code for the component that hosts both the navbar and content ... 

timeout: any; 
isScrolling: boolean = false; 

scrollFunction() : void { 
    this.isScrolling = true; 
    clearTimeout(this.timeout); 
    this.timeout = setTimeout(()=> { 
     this.isScrolling = false 
    }, 1000); 
} 

这1000多款是NUM毫秒,你可以将其设置为任何你想要的,但基本上,该功能将只设置isScrolling变量设置为true当用户滚动,一旦他们停止滚动它将最终在该时间之后重置为假。只要滚动继续发生,clearTimeout就可以确保定时器一直保持复位为0。如果你使用这个方法,那么你会想要添加一个类绑定到navbar组件,该组件在isScrolling为true的时候添加了一些类,当它不是的时候删除它。

<navbar-component [class.navbar-hidden]="isScrolling"></navbar-component> 
<content-component (scroll)="scrollFunction()"></content-component> 

我建议将滚动侦听器添加到特定内容元素而不是文档或窗口对象,因为这会使您的应用与DOM更加脱钩。但是,典型的jQuery做事的方式是将滚动监听器添加到整个文档或窗口对象中,然后使用该对象切换类。如果您的应用程序要保持小而简单,并且您知道它将始终在浏览器中使用,那么这样做确实没有问题。您可以通过仅改变

(scroll)="scrollFunction()" 

(window:scroll)="scrollFunction()" 

任意位置添加窗口事件监听器如果您的内容分量不是单独的组件,它包含在其中的导航栏组分(即,如果您只是使用主体应用程序组件,并且内部有navbar组件),则可以使用HostListener而不是模板事件绑定来监听事件。因此,而不是在HTML并称“(滚动)”的东西,你会导入主监听:

import { Component, HostListener, ....(anything else you have...) } from '@angular/core' 

,然后在组件:

@HostListener('scroll') myScrollFunction() { 
... same code here as above.... 
} 

,将完成同样的事情,从而触发任何时候在组件内部检测到滚动事件时都会发挥作用。您可能希望将CSS过渡添加到navbar-hidden类,这样导航栏就会滑动或淡入淡出。 :-)

编辑:我注意到,在许多网站上,而不是简单地让导航栏在一定时间不滚动后重新出现,它们将只在用户开始向上滚动时才会出现,它会总是隐藏在下卷轴上。如果你这样做,你可以避免使用超时,并检查滚动事件,看它是否向上或向下滚动,并基于此切换isScrolling变量。要通过事件数据作为参数,在您的模板:

<navbar-component [class.navbar-hidden]="isScrollingDown"></navbar-component> 
<content-component (scroll)="scrollFunction($event)"></content-component> 

,然后在你的组件......

isScrollingDown: boolean; 
lastScrollPosition: number; 

scrollFunction($event) : void { 
    let newPosition = $event.srcElement.scrollTop; 
    if (newPosition <= this.lastScrollPosition){ 
     isScrollingDown = false; 
    } 
    else { 
     isScrollingDown = true; 
    } 
    this.lastScrollPosition = newPosition; // store the last position so you can compare the new and old position with each function call 
} 

scrollTop的仅仅是指定每个滚动位置的DOM的属性的名称元件。

如果你走HostListener路由,这里是你如何将$ event参数传递给它。

@HostListener('scroll', ['$event']) myScrollFunction($event){ 
    ... similar code here... 
} 
+0

嗨,感谢您的具体答案。答案是伟大的,但似乎有点复杂..你知道一些方式,我只能改变HTML文件..我想使用Bootstrap。我的导航栏位于屏幕的左侧,而不是顶部。 – Rachel

+0

“但似乎有点复杂” Yeeepp ...我讨厌这么说,但Angular 2/4就是这样。它使一些复杂的事情变得更简单,但它使最简单的事情变得相当复杂。如果没有事件监听器至少会触发某些变量,您将无法完成任何种类的滚动反应行为。 导航栏的位置并不重要,因为您可以在CSS中创建一个.hidden类并将其隐藏在任何/无论您想要的位置。 – diopside

+0

我明白,但你可以看看这个例子:https://codepen.io/anon/pen/qXYMzZ?我想使用这个例子..但我无法理解所有这些代码。 – Rachel