Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deep link to a position in a page, using Meteor JS

Tags:

meteor

I have a meteor app with multiple pages. I want to be able to deeplink to an anchor somewhere halfway the page.

Traditionally, in normal html, you'd make an somewhere in your page, and link to it via /mypage.html#chapter5.

If I do this, my meteor app won't scroll down to that spot.

What is the best approach around this?

like image 343
Marten Sytema Avatar asked Jul 17 '13 09:07

Marten Sytema


3 Answers

@Akshat 's answer works for on the same page, but what if you want to be able to pass around a url w/ a "#" in it? I did it how the meteor docs did.

Template.myTemplate.rendered = function() {
  var hash = document.location.hash.substr(1);
  if (hash && !Template.myTemplate.scrolled) {
  var scroller = function() {
    return $("html, body").stop();
  };

  Meteor.setTimeout(function() {
    var elem = $('#'+hash);
    if (elem.length) {
      scroller().scrollTop(elem.offset().top);
      // Guard against scrolling again w/ reactive changes
      Template.myTemplate.scrolled = true;
    }
   }, 
  0);
  }
};

Template.myTemplate.destroyed = function() {
  delete Template.myTemplate.scrolled;
};

Stolen from the source to the meteor docs.

like image 91
Mike Graf Avatar answered Oct 17 '22 19:10

Mike Graf


Are you using some kind of javascript router? Meteor Router?

You could use something like a javascript based scrolling method. One such example is with JQuery: (You can place this in your link/buttons click handler)

Template.hello.events({
  'click #theitemtoclick':function(e,tmpl) {
      e.preventDefault();
      $('html, body').animate({
          scrollTop: $("#item_id").offset().top
      }, 600);
   }
});

Then tag your html item where you would put your anchor with the id:

<h1 id="item_id">Section X</h1>
like image 42
Tarang Avatar answered Oct 17 '22 17:10

Tarang


Currently, there's an issue in IronRouter where the hash is removed from the url. This is discussed here and here. Fortunately there is a fix even though it doesn't appear to be in the stable version.

My Iron Router solution with traditional anchor tags:

1) Apply the IronRouter fix above

2)

Router.configure({
    ...
    after: function () {
        Session.set('hash', this.params.hash);
    },
    ...
});

3)

function anchorScroll () {
    Deps.autorun(function (){
        var hash =  Session.get('hash');
        if (hash) {
            var offset = $('a[name="'+hash+'"]').offset();
            if (offset){
                $('html, body').animate({scrollTop: offset.top},400);
            }
        }
        Session.set('hash', '');
    });
}

Template.MYTEMPLATE.rendered = function (){
    anchorScroll();
};

Unfortunately this has to be set in each template's .rendered() otherwise the anchor tag is not guaranteed to be in the DOM.

For better or worse this will scroll again with a code push.

like image 34
Shwaydogg Avatar answered Oct 17 '22 19:10

Shwaydogg