0

I'm trying to use the jQuery scollsnap plugin in AngularJS, and have tried following the guide from this other post. However, it neither gives an error nor does it work.

This is what I had.

App.directive('scrollsnap', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            angular.element(element).scrollsnap({ snaps: 'section' });
        }
    };
}); 

And in my HTML:

<body scrollsnap class="... ... ...>
5
  • 1
    What error did it give? Commented Aug 4, 2014 at 4:12
  • @runTarm: As mentioned, "it neither gives an error nor does it work". No error given. Commented Aug 4, 2014 at 4:58
  • Oh, sorry I missed that. BTW, there is no need to wrap the element with angular.element(), it is already wrapped. Commented Aug 4, 2014 at 5:03
  • Has the link function really been called? May be put a console.log() in there and see if it output something. Commented Aug 4, 2014 at 5:04
  • @runTarm No worries :) The link function has been called and returns the correct object. Commented Aug 4, 2014 at 5:22

1 Answer 1

1

Your jquery plugin may need to be initialized after the view has been rendered.

Try using $timeout:

App.directive('scrollsnap', function($timeout) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            $timeout(function() {
               angular.element(element).scrollsnap({ snaps: 'section' });
            });
        }
    };
}); 
Sign up to request clarification or add additional context in comments.

5 Comments

Hmm, is this the best-practice? Using timeouts to wait for the view to render?
Yes.. if you're mixing jquery plugins with angular. There is no after render event in angular that you can hook into, but often times you need one when initializing jquery plugins. $timeout accomplishes this. The angular way might be to not use jquery plugins.
Here is a feature request for the Angular team to introduce an after render event: github.com/angular/angular.js/issues/734. In the discussion, they suggest best practice is not use code (jquery plugins) that necessitates the need for an after render process. Compilation is a continuous process, so to discourage the (bad) practice of hooking in code that runs after the render event, they don't make it easy or intuitive. $timeout waits until after the render phase has finished before executing the code - not by design, its just how it works.
Before reaching for your jquery toolbox, check if there is an angular way to do the same thing using directives. You might be able to do the same thing with a fraction of the code. If you still can't find a way, check with the community, maybe they have ideas. If you still can't find a way, ask google, or look through some Angular textbooks. Basically, only reach for your jquery toolbox as a last resort. And since it is a last resort, might as well use $timeout to initialize your plugin.
Thanks, but unfortunately, I don't seem to find any plugins for AngularJS that snaps the scroll to elements. I'll probably have to go with this and will give it a try.

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.