What is the best way to accurately determine the height and offset values of an element while utilizing ng-repeat?

My objective is to determine the offset and height of list items. Once I have those values, I trigger a function in a parent directive. Ultimately, this will involve transitioning elements in and out as they come into view.

Issue: Due to the use of ng-repeat (for reasons unknown), the values for el[0].offsetheight and

el[0].getBoundingClientRect().top;
appear to be somewhat arbitrary unless I place a $timeout around the logic. I suspect this is because the styles need time to render?

Query: How can I obtain accurate offset and height values without resorting to using a $timeout or implementing a $watch.

HTML:

<dt  spyed ng-repeat="exp in experiences">
 ...
</dt>

JS:

app.directive('spyed', function () {
    return {
        require: '^scrollSpyer',
        link: function(scope, el, attrs, ctrl) {
            // The offset value seems random after the first ng-repeat item
            var offset = el[0].getBoundingClientRect().top;
            // Similarly, the height value appears random after the first ng-repeat item
            var theHeight = el[0].offsetHeight;
            // This triggers the expMapper on the parent directive.
            ctrl.expMapper(offset, theHeight);
        }
    };
});

Note regarding why I am avoiding using a watcher: The reason I prefer not to utilize a watcher is because I am pushing these values to a collection in the parent directive. I wish to avoid constantly resetting the array, which would happen if ctrl.expMapper() kept firing due to two-way binding.

Parent Directive:

app.directive('scrollSpyer', function ($window, Experiences) {
    return {
        controller: function($scope){
            $scope.experiences = [];
            this.expMapper = function(offset, height) {
                $scope.experiences.push({'offset': offset, 'height': height, 'inView': false});
            };
        },
        link: function(scope) {
            var i = 0;
            angular.element($window).bind('scroll', function() {

                if(i < scope.experiences.length) {
                    if (this.pageYOffset >= scope.experiences[i].offset) {
                        Experiences.status.push(scope.experiences[i]);
                        i++;
                    } else {
                        console.log('middle');
                    }
                }

                scope.$apply();
            });
        }
    };
});

Answer №1

Transform it into a $scope function:

$scope.calculateOffsets = function () {
    //Implement your logic here
};

Take note of this minor modification:

<dt  inspected ng-repeat="exp in experiences" ng-init="$last ? calculateOffsets(): ''">
    ...
</dt>

Using ng-init with a condition to check for the last index will execute without needing a timeout

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

Removing Multiple Object Properties in React: A Step-by-Step Guide

Is there a way in React to remove multiple object properties with just one line of code? I am familiar with the delete command: delete obj.property, but I have multiple object properties that need to be deleted and it would be more convenient to do this i ...

Obtain the final array within an array composed of multiple arrays

My dilemma involves working with a dynamically generated array, where I need to extract only the values from the last array for aggregation purposes, discarding all others. Imagine a structure similar to this: let target = [] let data = [ [ { name: &apo ...

Error: The validation of a JSON request failed as schema.validate is not a recognized function

As a beginner, I am currently immersed in a node.js API authentication tutorial. Everything was going smoothly until I had to refactor my code into separate files. Now, every time I send a JSON request via Postman, I keep encountering the error message "Ty ...

Eliminating Repetitions in Array of Objects by Filtering Out Objects with Matching Properties

I am currently working with an array of objects where I need to identify duplicates based on specific properties (first and last names). Below is my attempt at solving this issue: The expected output should resemble: [ {first:"John", last: "Smith", id: ...

24-hour countdown tool featuring a visual progress bar

Currently, I am in the process of developing an application aimed at assisting individuals in either forming new habits or breaking old ones. In this application, I am looking to implement a countdown timer that ticks down daily; with the help of this help ...

PHP and MySQL collaborate for live countdowns in real-time

Looking for a code solution to implement a real-time countdown feature, similar to deal expiration timers on shopping websites. I have an expiry time stored in MySQL which needs to be displayed whenever the page is accessed. Additionally, it should calcul ...

After converting from php/json, JavaScript produces a singular outcome

After running a PHP query and converting the result to JSON using json_encode, I noticed that when I try to print the results using echo, only one entry from the query is output in JSON format. My objective is to make this information usable in JavaScript ...

The Date Picker pops up automatically upon opening the page but this feature is only available on IE10

There seems to be an issue with the date picker opening automatically on IE10, while it works fine in Firefox where it only appears when you click on the associated text box. Does anyone have insight into why this might be happening specifically in IE10? ...

Utilizing a single variable across different JavaScript scripts - where one script includes a .ready function while the other does not

I am facing a challenge with 2 javascript scripts that I have: <script type="text/javascript"> function capture(){ var canvas = document.getElementById('canvas'); var video = document.getElementById('video'); canvas.getContext ...

Incorporating an element into a nested array

I have an array stored in a variable called 'items' with various products and their attributes. I am looking to randomly generate a popularity score between 1 and 100 for the items that currently do not have one. This is my current array: const ...

What is the role of the app.use method in ExpressJS in handling URL redirects that end with a "/"?

This script automatically redirects URLs that end with a "/" to the same URL without it. For example, if a user visits http://localhost:3000/about/, they will be directed to http://localhost:3000/about. This ensures that image URLs and other HTML file refe ...

What is the best way to save an object in a variable in MeteorJS/React for future retrieval?

This code snippet is located at the bottom of a component called 'Block'. export default theBlockContainer = createContainer(({ params }) => { return { voteStatus: Meteor.user()['listofvoted'], } }, Block); Although the ...

Shipment calculation involves the consideration of factors such as the quantity,

Hello, my name is Mirella and I am from Italy. Please bear with me as I communicate through Google Translate. I am facing some issues with shipping costs while using Simplecart. My customers have varying shipping costs based on the items they purchase. T ...

When adding files through drag and drop, the FormData is including a blank file field in the sent

I am currently working on a photo upload page that has drag and drop functionality enabled. Below is the form code: <form id="Upload" method="post" action="sessionapi/UserPicture/Upload" enctype="multipart/form-data"> <input class="box__file ...

Looking for a discreet JavaScript-based text editor with advanced features?

Our CMS has been using the now-unsupported RichTextBox control for a while, and we want to find a lighter-weight alternative with better cross-browser support. Initially, we were considering different ASP.NET components, but I am starting to think that an ...

"Include the 'unsafe' prefix at the start of the URL in AngularJS

Whenever I attempt to access app://csttree?featuretype=cst_issue&verticalid=2132321&l1=3213&l2=3242 within my app, the URL gets parsed as ==> unsafe:app://csttree?featuretype=cst_issue&verticalid=2132321&l1=3213&l2=3242 Is ...

Execute asynchronous calls within each iteration and proceed to the next iteration in Node.js

I am currently faced with a dilemma at work and I need advice on the most effective approach to handle it. Below is an example of my code: for(var i =0 ;i < collection.length; i++){ asynCall( collection[i],function(){....})//doing a asynchronous cal ...

Animate.css does not function properly when loaded locally

I'm currently using a Flask server to host an HTML file for testing purposes. Within the head of this HTML file, I have linked to a locally stored animate.min.css file (<link rel="stylesheet" type="text/css" href="{{ url_fo ...

delivering axios response to display the page

I have a code snippet that requests data from an external API using axios and I want to incorporate the response into my rendered page. Here is my code: //Snippet from my controller required in main routes exports.recordBySlug = async (req, res, next) =&g ...

How come my Bootstrap tooltip title only updates once when I use the keydown event in jQuery?

My goal is to provide users with a character count for text inputs and textareas based on a maximum limit. To achieve this, I have added tooltips to elements with a data-maxlength attribute. I update the tooltip for text inputs to display the current lengt ...