Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular JS: Detect when page content has rendered fully and is visible

My situation

I have a BIG list of people which all have their own profile pic and information. All items have some CSS3 styling/animations.

Im using:

<li ng-repeat="person in people">

Where people is an array with over 150 objects from an external JSON file that all have to show on the same page.

The page loads/renders slowly, and its not because of the $http GET function that gets the JSON data with people (which only takes about 100ms), but the rendering of the page and seemingly the rendering of all the css3 styling applied to each item (if i turn my CSS off it gets much faster).

My main problem

I can live with the page rendering slowly but what i really want is to detect whenever my heavy page has loaded its content in order to start and stop a loading indicator. Ive tried making a directive like this:

directive("peopleList", function () {
    return function (scope, element, attrs) {
        scope.$watch("people", function (value) {
            var val = value || null;
            console.log("Loading started");
            if (val){
                console.log("Loading finished");
            }
        });
    };
});

And put this directive on the wrapper div that is loading my list of people. But the loading appears to stop whenever my object with JSON data has been filled, which only takes around 100ms, but the actual visual rendering of the page takes more like 4-5s.

Ive also tried solutions like http://jsfiddle.net/zdam/dBR2r/ but i get the same result there.

What i need

When i navigate through my pages (which all have the same kind of lists) i need something that tells me whenever the page has fully loaded and is visible for the user so that i know when to hide my loading indicator.

like image 883
Rocaboca Avatar asked Sep 25 '13 09:09

Rocaboca


1 Answers

Try adding this directive -- the magic is in the link function:

directives
  .directive('onFinishRender', function ($timeout) {
  return {
    restrict: 'A',
    link: function (scope, element, attr) {
      if (scope.$last === true) {
          scope.$evalAsync(attr.onFinishRender);
      }
    }
  }
});

Add a loader as the first item:

<li ng-show="!isDoneLoading">
  <div class="loading">Loading...</div>
</li>

Then in your li, add this:

  <li ng-repeat="..." on-finish-render="isDoneLoading = true;"> ... </li>
like image 121
richardm Avatar answered Sep 17 '22 19:09

richardm