Meteor Iron Router - Router.go callback possible?
Asked Answered
N

1

8

I've got a link that I want the user to press. When they press it, the router will go to a certain template and then run Smoothscroll.js code to animate and scroll down to the anchor tag.

      //When the user clicks on the link to get to the #contact anchor...
      //The code below does not work.
      Router.go('index');
      $('html,body').animate({
          scrollTop: $('#contact').offset().top
      }, 1200);

Router.go('index') works just fine.

      $('html,body').animate({
          scrollTop: $('#contact').offset().top
      }, 1200);

Works as well by itself on the index template.

But when I try to run them together, the router goes to index, but the scrolling does not work.

Any idea how I can do this?

EDIT

This is what I have for the latest Meteor 1.0+ and a path like /#contact

Router.route('/', {
  name: 'index'
});

Router.onAfterAction(function() {
    var self = this;
    // always start by resetting scroll to top of the page
    $(window).scrollTop(0);
    // if there is a hash in the URL, handle it
    if (this.params.hash) {
        // now this is important : Deps.afterFlush ensures that iron-router rendering
        // process has finished inserting the current route template into DOM so we
        // can manipulate it via jQuery, if you skip this part the HTML element you
        // want to scroll to might not yet be present in the DOM (this is probably
        // why your code fails in the first place)
        Tracker.afterFlush(function() {

            if (typeof $("#" + self.params.hash).offset() != "undefined"){
                var scrollTop = $("#" + self.params.hash).offset().top;

                $("html,body").animate({
                    scrollTop: scrollTop
                });

            }

        });
    }
});
Nazarius answered 14/8, 2014 at 6:59 Comment(0)
R
4

Unless you're doing something fancy you probably don't want to use Router.go and instead let iron-router manage routing on anchor click as it normally does.

As far as scrolling to an element is concerned, this is the onAfterAction hook I'm using, it supports any route and any hash (/anyroute#anyhash).

Router.onAfterAction(function() {
  // always start by resetting scroll to top of the page
  $(window).scrollTop(0);
  var hash=this.params.hash;
  // if there is a hash in the URL, handle it
  if (hash) {
    // now this is important : Tracker.afterFlush ensures that iron-router
    // rendering process has finished inserting the current route template
    // into DOM so we can manipulate it via jQuery, if you skip this part
    // the HTML element you want to scroll to might not yet be present in
    // the DOM (this is probably why your code fails in the first place)
    Tracker.afterFlush(function() {
      var element=$("#"+hash);
      var scrollTop = element.offset().top;
      $("html,body").animate({
        scrollTop: scrollTop
      });
    });
  }
});
Reductase answered 14/8, 2014 at 7:43 Comment(4)
Cool, I'll give this a shot. Where do you find Deps.autoFlush? I can't find any mention of it in documentation. It's definitely not in the Meteor Manual.Nazarius
Hi just wondering what this would look like for latest meteor 1.0.2.1? Also I am getting "undefined" on the $(#.. call.Sheeting
FYI created Meteor 1.0 version here and posted as iron-router issue: github.com/EventedMind/iron-router/issues/1171Sheeting
@aginsburg, I've updated my OP to highlight the code for the latest Meteor.Nazarius

© 2022 - 2024 — McMap. All rights reserved.