Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Re-rendering list template causes page to scroll to top

Tags:

meteor

I have some templates that look roughly like this:

<template name="items">
  <div class="item-list">
    {{#each items}}
      {{> item}}
    {{/each}}
  <div>
  {{> loadMore}}
</template>

<template name="item">
  <div class="item" id="{{unique_string}}">
    <!-- stuff here -->
  </div>
</template>

<template name="loadMore">
  <a href="#">Load more...</a>
</template>

With associated javascript:

Template.items.items = function() {
  return Items.find({}, {limit: Session.get("itemCount")});
}

Template.loadMore.events({
  "click": function() {
    Session.set("itemCount", Session.get("itemCount") + 10);
  }
})

All that together more-or-less gives me something that pretty much works like an infinite scrolling section. (The actual code has a few more moving parts, but this is the important bit.)

Whenever I click on loadMore, though, it both pulls more data down and scrolls me back to the top of the page, rather defeating the purpose of infinite scroll. I can throw in some javascript to scroll back down to where it should be, but that leaves a nasty flicker as the page hops around quicly.

I've tried using preserve on the entire list as well as on each item div to keep them from getting updated, but that didn't seem to stop the scrolling. I've also tried putting {{#isolate}} blocks around just about any and everything, without any luck.

Is there something I can do here to make the page not scroll around while it re-renders? Composing templates differently? Some aspect of preserve or {{#isolate}} that I've missed?

like image 264
user1830246 Avatar asked Nov 16 '12 17:11

user1830246


1 Answers

The page scrolls to top because your <a href="#">Load more...</a> will make the page scroll to top. When your href links to "#" the page will scroll to the DOM element with #"element id". Clicking a link with only "#" will scroll to top.

You have two options:

  1. Prevent the default behaviour on the click event (easy option):

    Template.loadMore.events({
    "click": function(event) {
      event.preventDefault();
      Session.set("itemCount", Session.get("itemCount") + 10);
    }   })
    

    This will stop the page reload

  2. Even better: make the <a href="#">Load more...</a> link to "#{{_id}}" then the page will automatically scroll to the element with the id you provided. This will require some restructuring of the templates and maybe a helper method in the template to give you the id of the last item. But it will make your page load exactly where you want.
like image 195
Erlend V Avatar answered Oct 02 '22 06:10

Erlend V