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

What is a memory-saving method to clear an object in JavaScript?

I am looking for a way to use the same object repeatedly in JavaScript by emptying it after its purpose is served, without creating a new object each time. In arrays, I usually do arr.length=0 to clear an array instead of assigning it to a new memory locat ...

Pass an array from JavaScript to PHP

I am attempting to send an array to the server using jQuery. Here is my code snippet for sending the array: jQuery(document).ready(function($){ $.ajax({ type: "POST", url: "file.php", datatype : "json", data : JSON.str ...

Transmit data in the form of a buffer

const response = await client.render(data); const Writable = require('stream').Writable; var buffer = []; const myWritableStream = new Writable({ write(chunk, encoding, callback) { ...

Converting input dates in nest.js using TypeScript formatting

Is it possible to set a custom date format for input in nest.js API request body? For example, like this: 12.12.2022 @ApiProperty({ example: 'ADMIN', description: 'Role name', }) readonly value: string; @ApiProperty({ ...

Automatically execute JavaScript upon loading the page with the option to value run on

Upon loading the page, Week 1 is automatically selected which is great. However, the javascript function only runs when I manually choose an option. I want the javascript to automatically trigger for week 1 without needing manual selection. Any ideas on ...

Using JavaScript to create an image slider

My image slideshow with prototyping is not working properly and I am struggling to fix it. I have tried binding the setInterval function but it's not working. I also attempted to wrap it, but that didn't work either. What should I do to solve thi ...

jQuery code runs smoothly on Firefox but encounters issues on Chrome

I'm experiencing an issue with a script that is supposed to post a comment and load the answer from a server. The script works fine in Firefox, but in Chrome, it seems that no event is triggered. You can click the button, but nothing happens. I'v ...

Is there a way to retrieve the dynamically generated text content of an element using document.write?

I am encountering an issue similar to the following: <div id="myDiv"><script>document.write('SOMETHING');</script></div> My goal is to extract the content inside the script tag, which in this case is "SOMETHING" ...

Troubleshooting issue: AngularJS not receiving NodeJS GET requests

I recently developed a web application for sharing photos. Currently, I am working on a route that is designed to fetch and display the photos of all users from an array. The code for the route is as follows: router.get('/getphotos',function(re ...

Front end authentication failed (Angular/Spring stack)

Link to my front end code: http://embed.plnkr.co/toe4XO/. I made adjustments to the authentication/service.js file, see below: 'use strict'; angular.module('Authentication') .factory('AuthenticationService', ['Base ...

Is there a way to dynamically set the active panel of a JQuery Accordion when making a call?

Currently, I am faced with a scenario where I need to implement a greybox popup window using jQuery Accordion from the main page via links. I am curious to know if it is doable to specify a default active panel for the accordion when calling it. Below is ...

Vue.js versatile form for both adding and editing

As a newcomer to the world of vue.js, I am currently working on expanding some tutorials that I have completed. After struggling with this for three hours now, I must admit that I am feeling quite frustrated. Just to give you a heads up, I am using firebas ...

Currently, my goal is to create PDFs using Angular

<button class="print" (click)="generatePDF()">Generate PDF</button> Code to Generate PDF generatePDF(): void { const element = document.getElementById('mainPrint') as HTMLElement; const imgWidth = 210; ...

Creating a prompt within a while loop

Issue with the code is that it should only progress if the user inputs "rock", "paper" or "scissors". However, after re-entering any input the second time, it still moves on despite passing the condition in the while loop. For instance, entering "asdf" p ...

I possess a JSON array object and need to identify and extract the array objects that contain a specific child node

const jsonArray = { "squadName": "Super hero squad", "homeTown": "Metro City", "formed": 2016, "secretBase": "Super tower", "active": true, "members": [ { "name": "Molecule Man", "age": 29, "secretIdent ...

Any suggestions on resolving the message "Unable to locate module './commands/${file}'"?

Can someone assist me in resolving this issue? I am trying to develop a code that includes advanced commands. Here is the code snippet: const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js&apo ...

Retrieving the current day integer from a fullcalendar rendering in JavaScript and utilizing it as an array key

I am currently working on rendering a full calendar and I would like each cell to be displayed in a different color based on an array that contains color values for each day of the month. The array is retrieved in JSON format. Here is an example JSON arra ...

Tips for capturing HTTP error responses in Angular

Context In my Angular application, I have implemented communication with a database using API endpoints. The "user/authenticate" endpoint is responsible for handling username and password inputs and provides either a successful (200) or bad request (400) ...

"Learn how to capture the complete URL and seamlessly transfer it to another JavaScript page using Node.js and Express.js

Is there a way to access the token variable in another page (api.js)? I need to use it in my index.js. var express = require('express'); var router = express.Router(); router.get('/', function(req, res ...

Implementing file change detection using view model in Angular

When using the input type file to open a file and trigger a function on change, you can do it like this: <input type="file" multiple="multiple" class="fileUpload" onchange="angular.element(this).scope().fileOpened(this)" /> The functi ...