这是经典之作.您有父元素和子元素.子元素绝对定位,您希望用户滚动其内容.但是,当您到达子元素的底部时,父元素(也允许有滚动条)开始滚动.那是不可取的.我想要重现的基本行为是“纽约时报”评论部分.对于
example:
允许正文向下滚动,但当你在评论部分的底部时,向下滚动不会做任何事情.我认为在这种情况下的主要区别在于,当光标位于body元素上方时,我想让用户向下滚动.其他方法需要向正文添加类以防止正文中的任何滚动事件.我想我可以用Angular 2中的一些Javascript来做到这一点,但这是我到目前为止失败的尝试:
我的子组件中有一个自定义指令:
< child-element scroller class =“child”>< / child-element>
并且该指令应该停止将scroll事件传播到body元素:
import {Component} from 'angular2/core' import {Directive,ElementRef,Renderer} from 'angular2/core'; @Directive({ selector: '[scroller]',}) export class ScrollerDirective { constructor(private elRef: ElementRef,private renderer: Renderer) { renderer.listen(elRef.nativeElement,'scroll',(event) => { console.log('event!'); event.stopPropagation(); event.preventDefault(); }) } }
它实际上会监听事件但不会阻止传播.
Demo:向下滚动数字列表,当您到达底部时,其父元素开始向下滚动.那就是问题所在.
如果您有其他方法可以实现此目的,请告诉我.
谢谢
更新:根据GünterZöchbauer提供的答案,我试图在用户到达底部时阻止车轮事件.这基本上就是我在updated demo中所拥有的:
renderer.listen(elRef.nativeElement,'wheel',(e) => { console.log('event',e); console.log('scrollTop',elRef.nativeElement.scrollTop); console.log('lastScrollTop',lastScrollTop); if (elRef.nativeElement.scrollTop == lastScrollTop && e.deltaY > 0) { e = e || window.event; if (e.preventDefault) e.preventDefault(); e.returnValue = false; } else if (elRef.nativeElement.scrollTop == 0) { lastScrollTop = -1; } else { lastScrollTop = elRef.nativeElement.scrollTop; } },false)
然而,逻辑是丑陋的,并不是很好.例如,当用户到达底部时,向上滚动一点并再次向下滚动,父组件稍微移动.有谁知道如何处理这个? (更好)实施?
更新2:
This好多了,但现在已经晚了,所以我明天再来看看.
在我看来,我会建议一些更直接的东西:向任意父级添加一个任意类,并防止通过CSS overflow:hidden滚动.
原文链接:https://www.f2er.com/angularjs/142181.html在这个例子中,我编写了指令,以防止父元素在元素存在时滚动,因为这是我想要的行为.对于您的用例,您应该绑定到mouseenter和mouseleave,而不是OnDestroy和AfterViewInit
HTML:
<div add-class="noscroll" to="body">Some Content Here</div>
CSS:
.noscroll { overflow: hidden; }
TS:
import {Directive,AfterViewInit,OnDestroy,Input} from "@angular/core"; @Directive({ selector: '[add-class]' }) export class AddClassDirective implements AfterViewInit,OnDestroy { @Input('add-class') className: string; @Input('to') selector: string; ngOnDestroy(): void { document.querySelector(this.selector).classList.remove(this.className); } ngAfterViewInit(): void { document.querySelector(this.selector).classList.add(this.className); } }