Delay the execution of the function in AngularJS until the browser has finished rendering completely and the view-model synchronization cycle has ended

I'm uncertain about the appropriate title for this inquiry, so please correct me if I am mistaken.

Suppose that upon page refresh (load), I require an animated scroll to an anchor based on the current location's hash (I am aware of ngAnchorScroll, but I specifically need animated scrolling, which ngAnchorScorll cannot accomplish).

To achieve this, I have created a service that will be called upon controller initialization:

var Ctrl = function ($scope, initAnchorScrolling) {
    initAnchorScrolling($scope);
};

Ctrl.$inject = ['$scope', "initAnchorScrolling"];

applicationServices.factory("initAnchorScrolling",
    ['scroll', '$location', '$timeout', function(scrollUtils, $location, $timeout) {
    return function(scope) {

    /** Some stuff here */

    function scroll() {
        var hash = $location.hash(), elm;

        if (!hash) {
            scrollUtils.scrollTo(0, 0);
        } else if ((elm = getAnchorElement(hash))) {
            scrollUtils.scrollToElement(elm);
        } else {
            scrollUtils.scrollTo(0, 0);
        }
    }

    scope.$watch(function scrollWatch() { return $location.hash(); },
        function scrollWatchAction() {
            $timeout(function () {
                scroll();
            }, 0, true);
        });
    };
}]);

You can observe that this anchor implementation is very similar to ngAnchorScroll. The main distinction is that I utilize jQuery.animate() to transition between anchors.

According to my understanding from here, in order to delay function execution until the browser has finished rendering, one simply needs to call the $timeout service with a delay parameter set to 0. However, this method is not proving effective for me. Occasionally, the page scrolls to different positions unexpectedly. I attribute this issue to the fact that the scroll function is invoked before the digest cycle completes synchronization of views and models—the HTML blocks therefore possess inaccurate height and position at the time of invocation.

Hence, my query: is there a way to defer function invocation until the moment when the browser has fully completed rendering and the digest cycle has synchronized views and models (applied bindings)?

Answer №1

This particular solution addresses the issue of maintaining scroll position regardless of any changes, rather than simply scrolling to a specific hash. While it may offer a resolution to your problem, it's important to note that the directive created works specifically on window scroll events (although it could be adapted for other elements).

Here is an example of how you can implement this in your HTML code:

<div ng-keep-scroll="service.scrollY">
<!-- Place your scrolling content here -->
</div>

It's crucial to ensure that "service.scrollY" is a variable within a service. Services retain their data and values, unlike controllers which reset every time they load. The controller should have a scope variable that references the service.

Below is the directive JavaScript code:

app.directive('ngKeepScroll', function ($timeout) {
    return function (scope, element, attrs) {

        // Load scroll position after everything has rendered
        $timeout(function () {
            var scrollY = parseInt(scope.$eval(attrs.ngKeepScroll));
            $(window).scrollTop(scrollY ? scrollY : 0);
        }, 0);

        // Save scroll position when there's a route change
        scope.$on("$routeChangeStart", function () {
            scope.$eval(attrs.ngKeepScroll + " = " + $(window).scrollTop());
        });
    }
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for pausing a video while it is still buffering and loading?

Is it possible to suspend a video when it is in an opening or preparing state? For example, if I open a video and then switch to another application using the smart hub feature, how can I suspend the video while it is in the process of opening or preparin ...

Let's leverage the power of Node.js and Express with the Jade templating

My goal is to iterate over an array within a jade layout file named lessons.jade: each lesson in myLessons ul.nav.pull-center: li.dropdown.nav.text-center .btn.btn-default.dropdown-toggle.btn-lg.btn-block(data-toggle="dropdown ...

Learn the process of integrating VueJS with RequireJS

I am attempting to set up VueJS with RequireJS. Currently, I am using the following VueJS library: . Below is my configuration file for require: require.config({ baseUrl : "js", paths : { jquery : "libs/jquery-3.2.1.min", fullcalendar : "libs/ful ...

Tips for effectively transmitting and managing a JSON object within an ASP.NET MVC controller

I am currently working on a project using ASP.NET MVC 4 and I'm facing an issue with sending a JSON object to a controller that is supposed to accept it. Here is the snippet of javascript and jQuery code I am using: var jsonObject = { "PlantShip ...

Seeking a light-weight, text-rich editor specifically designed for use on our enterprise website. This editor should be even lighter than TinyMCE

I am in search of a lightweight text editor for an enterprise website, lighter than tinymce with basic buttons for the comment form. It is imperative that the editor also functions properly in IE6. So far, I have tried cleditor 15KB, but it has an issue in ...

What is the best way to import a file in meteor version 1.3?

Trying to incorporate react-datepicker into a meteor 1.3 and react project has been quite successful so far. The only issue I am facing is the inability to access any of the css styles from the package. According to the readme, I'm supposed to requir ...

I am looking for an image search API that supports JSONP so that users can easily search for images on my website

I am currently in the process of creating a blog platform. My goal is to allow users to input keywords on my site and search for images directly within the website. This way, I can easily retrieve the URL of the desired image. ...

Ways to stop users from inputting incorrect characters into an input field

I need help with restricting user input in a text field to only allow letters, numbers, and dashes (-). For alphanumerics only - "The alphanumeric character set includes numbers from 0 to 9 and letters from A to Z. In the Perl programming language, the un ...

Do the dependencies in the devDependencies section impact the overall size of the

My search for a definitive answer to this question was fruitless. Are the packages I include as devDependencies included in the final production JS bundle, impacting its size? Or does only the dependencies list affect the bundle's content? ...

What is the best way to send HTML tag content to mark.js and delimit them with a space or comma?

I have been utilizing the mark.js library to highlight keywords on a webpage, and it's been working well. However, I now need to insert an extra space or a comma after each tag such as h1, h2, etc. Initially, I thought about using a loop like the one ...

Uh-oh! Trouble loading web app dependencies: 404 Error

Currently, I have a functional SailsJS boilerplate application. The next step I am trying to undertake involves integrating Angular-Material as a dependency in order to kickstart some UI development tasks. However... After installing angular-material usin ...

What is preventing comment upvotes from functioning properly? thinkster.io offers tutorials on AngularJS, MEAN stack, and the function incrementUpvote()

Currently, I am working through the Angular JS tutorial provided by thinkster at this link: When attempting to increment the upvote count by clicking on the upvotes icon adjacent to a comment, it fails to execute. Within a ui-router template embedded wit ...

Struggling to display the array after adding a new item with the push method

Seeking assistance in JavaScript as a newcomer. I have written some code to print an array once a new item is added, but unfortunately, it's not displaying the array. I am puzzled as there are no errors showing up in the console either. In my code, I ...

Utilizing MongoDB query for geoLocation with maxDistance parameter

Customer location: customerCoordinates: [83,24] stores: { id:1, location: {coordinates:[85,44]...} maxRadiusDelivery: 2000 //meters }, { id:2, location: {coordinates:[82,34]...} maxRadiusDelivery: 100 //meters } Query: db.wh.find({ 'locati ...

Using JQuery to make POST requests is successful, however, utilizing the XMLHttpRequest object to make

Currently, I am attempting to make a POST request from Javascript to my server in PHP but without utilizing jQuery. The following code successfully sends the required data to the database: var msg = {}; msg['name'] = 'joe'; msg['m ...

Elements in Motion

Working on a parallax effect, I've managed to assign unique scroll speeds to (almost) every element. Moreover, these elements are programmed not to activate their scroll speed until they enter the viewport. Below is the JavaScript code for trigger co ...

Error message appears when attempting to submit a form with empty values in NodeJs

I need help troubleshooting a display error that occurs when setting empty values in form fields. When I delete the row with res.redirect('/') and then attempt to register, if I refresh the page later, an error appears. However, if I keep this re ...

Unable to fetch Rails response through Ajax

Whenever I make a post request from my phonegap app (using ajax in javascript) to my rails server, the post goes through successfully. However, I do not receive any response from the server which ultimately leads to failure. It's puzzling why I'm ...

Creating a vibrant and mesmerizing inward spiraling rainbow of colors on canvas using JavaScript

After coming across an image that caught my eye, I was inspired to recreate it using canvas: https://i.stack.imgur.com/fqk3m.png I've attempted drawing arcs starting from the center of the screen, but I'm struggling with getting their paths acc ...

Show the dropdown menu with names from the array in the ajax response

<html> <select name="cars"> <option value="34">Volvo XC90</option> <option value="54">Saab 95</option> <option value="12">Mercedes SLK</option> <option value="10">Audi TT</option> </select> ...