32

Ok, I'm a little stumped.

I'm trying to think the angular way coming from a jQuery background.

The problem: I'd just like to hide a fixed element if the window is not scrolled. If someone scrolls down the page I would like to hide the element.

I've tried creating a custom directive but I couldnt get it to work as the scroll events were not firing. I'm thinking a simple controller like below, but it doesnt even run.

Controller:

.controller('MyCtrl2', function($scope,appLoading, $location, $anchorScroll, $window ) {
   angular.element($window).bind("scroll", function(e) {
       console.log('scroll')
       console.log(e.pageYOffset)
       $scope.visible = false;
   })
})

VIEW

<a ng-click="gotoTop()" class="scrollTop" ng-show="{{visible}}">TOP</a>

LIVE PREVIEW http://www.thewinetradition.com.au/new/#/portfolio

Any ideas would be greatly appreciated.

2 Answers 2

70

A basic directive would look like this. One key point is you'll need to call scope.$apply() since scroll will run outside of the normal digest cycle.

app = angular.module('myApp', []);
app.directive("scroll", function ($window) {
    return function(scope, element, attrs) {
        angular.element($window).bind("scroll", function() {
            scope.visible = false;
            scope.$apply();
        });
    };
});

I found this jsfiddle which demonstrates it nicely http://jsfiddle.net/88TzF/

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks Eddiec, For some reason the scroll event doesnt run until the bottom of the page is hit. See console log here: thewinetradition.com.au/new/#/portfolio
you have an overflow-x: hidden; on your hh class (app.css line 3), that's stopping scroll from firing consistently it seems.
Will this automatically unbind the event when the directive is destroyed?
How do you get $(window).scrollTop()
I came across this solution:) and i was confused about the apply function, here's a good article that describes it very well if anyone is interested. jimhoskins.com/2012/12/17/angularjs-and-apply.html
|
0

This is an old post so my answer is for Angular 9+, this answer is tested on Angular 15

I've handled scrolling events in Angular with the Renderer2 Class listening for a scroll event on a DOM element.

Then, using a simple class to make the styling changes.

Like this.

  1. Add an ID to the DOM element (in your HTML template) that you want to manipulate, and the DOM element you want to listen to (if not the window element).

  2. inject Renderer2 into you component constructor

       constructor(private renderer: Renderer2) {  }
    
  3. In your ngOnInit, define a reference to the DOM elements you want to change & the element to want render2 to listen to.

       const addBtn : HTMLElement | any = document.getElementById('addBtn');
       const gridView : HTMLElement | any = document.getElementById('gridView');
    

...in this example its not the Document "Window", but a scrollable fixed height div, I'm listening to for scrolling changes.

  1. Next add this block of code. Mine is actually firing on an Input change so will be in ngOnChanges, but yours might be in AfterViewInit. You'll need to experiement, but all DOM elements must be rendered so that your references to them won't be undefined.

     this.renderer.listen(gridView, 'scroll', (event) => {
       const number = event.target.scrollTop;   
       if (number > 200 ) {
         addBtn.classList.add('showCompactBtn');
       } else {
         addBtn.classList.remove('showCompactBtn');
       }
     });
    

So what's happening here... First I instruct the renderer to listen for the "scroll" event in the DOM element "gridview" (which I defined earlier), but this could be 'window' if you wanted to listen to that.

Next, I get the scrolltop position from the returned renderer event.

Finally, setting a class to the target element when the scrolltop reaches a certain threshold.

You would then need to define the styling changes that the added class would effect in your CSS/SCSS

That's it. This is a bare bones with lots of room for improvement.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.