Tips for eliminating stuttering when fixing the position of an element with JavaScript

I am currently facing an issue with a webpage I created where the text freezes when scrolled down to the last paragraph, while the images continue to scroll. Although my implementation is functional, there is noticeable jankiness when using the mouse wheel for scrolling, whereas clicking and dragging the scrollbar results in smoother movement.

Are there any optimizations that can be applied to this code to achieve the desired functionality without the janky scrolling, or perhaps a different approach altogether?

window.addEventListener('scroll', function (e) {
    window.requestAnimationFrame(keepTextStationary);
});

function keepTextStationary() {

    var textRect = writtenContent.getBoundingClientRect();
    var imageRec = images.getBoundingClientRect();

    if (textRect.bottom < window.innerHeight && document.documentElement.scrollTop > 0) {

        writtenContent.style.position = 'relative';
        writtenContent.style.bottom = (225 - document.documentElement.scrollTop) + 'px';

        if (imagesTop === undefined) {
            imagesTop = imageRec.y;
        }

    } else {
        writtenContent.style.bottom = (225 - document.documentElement.scrollTop) + 'px';
    }

    if (imageRec.y >= imagesTop) {
        writtenContent.style.position = '';
    }
}

If you would like to view the problem on the site, you can do so by visiting:

Answer №1

To prevent layout trashing when calling getBoundingClientRect, it is recommended to debounce your scroll events:

var lastScrollY = 0;
var ticking = false;

function keepTextStationary() {

    var textRect = writtenContent.getBoundingClientRect();
    var imageRec = images.getBoundingClientRect();

    if (textRect.bottom < window.innerHeight && lastScrollY > 0) {

        writtenContent.style.position = 'relative';
        writtenContent.style.bottom = (225 - lastScrollY) + 'px';

        if (imagesTop === undefined) {
            imagesTop = imageRec.y;
        }

    } else {
        writtenContent.style.bottom = (225 - lastScrollY) + 'px';
    }

    if (imageRec.y >= imagesTop) {
        writtenContent.style.position = '';
    }

    ticking = false;
}

function onScroll() {
    lastScrollY = document.documentElement.scrollTop;
    requestTick();
}

function requestTick() {
    if (!ticking) {
        requestAnimationFrame(keepTextStationary);
        ticking = true;
    }
}

window.addEventListener('scroll', onScroll );

For more detailed information, check out this article: https://www.html5rocks.com/en/tutorials/speed/animations/

Answer №2

There is a better way to approach this situation.

Moving elements or applying styles in JavaScript should be avoided if possible, as it is considered bad practice and can lead to performance issues. An alternative solution could be to utilize CSS animations to create a more visually appealing effect.

Have you considered using pure CSS instead of relying on JavaScript for this task?

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

Leveraging functions with Ng-Repeat

I am currently dealing with two different arrays of objects. The first array contains a list of permissions groups, while the second array consists of user groups. My main goal is to compare the Group Owner (which is represented by ID 70) with the list of ...

Exploring how to use React with a select component featuring objects

Hello, I am new to working with React and I have a question regarding the select component of Material UI. Here's my situation: I am creating functionality for creating and editing a User object. This User object has a primary key and some data, incl ...

Can I modify a property in DataTables.Net using the data itself?

I am trying to set the "column" property based on the ajax data that I receive. The json data contains a "data" and "columns" property, so in order to extract the data, my code would look something like this: primaryTable = $('#example').DataTa ...

Creating a personalized Material UI theme for enhancing the appearance of a Next.js App Router

Recently transitioned from C# development to diving into Next.js for a client project. Utilizing MUI, I have put in a day of work so far, resulting in a relatively small project. While I grasp the concept of SSR (Server-Side Rendering) theoretically, the ...

How can labels be added when mapping over JSON data?

If I have JSON data structured like this: { "siteCode": "S01", "modelCode": "M001", "modelDesc": "Desc01", "price": 100 "status": "A", "startDate": "Ma ...

Ways to incorporate NPM packages into your browser projects using TypeScript

This is the current setup: index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8> <script src="../node_modules/systemjs/dist/system.js"></script> <script src="../node_modules/lodash/in ...

Can javascript be used to swap out the folder in my URL?

I have been searching for solutions on how to change the language of my website using jQuery, but so far I have not found anything that works for me. Let's take my website as an example: www.domain.com I have separate folders for different languages. ...

Is it possible to maintain a fixed footer while utilizing async/ajax functions?

Looking for a reliable solution to have a fixed footer that adjusts based on the page content? I've tested multiple samples, but they all fall short when it comes to incorporating AJAX elements. Is there a fixed footer out there that truly works seaml ...

Dynamic and static slugs in Next.js routing: how to navigate efficiently

I am facing a scenario where the URL contains a dynamic slug at its base to fetch data. However, I now require a static slug after the dynamic one to indicate a different page while still being able to access the base dynamic slug for information. For Ins ...

Module 'BrowserFetcher.js' could not be located

After updating all my npm packages, I encountered an issue when trying to run on my local server. The error message reads: Error: Cannot find module './BrowserFetcher.js' This error specifically points to a line in my puppeteer file located at - ...

What is the reason onbeforeunload does not fire requests in Safari browser?

Is there a way to ensure that data is saved to the database when a user interacts with the page and also when they refresh it? I have tried using onbeforeunload event, but Safari does not wait for the server request to finish before reloading the page, c ...

Tips for creating a responsive tab indicator in Material UI?

I successfully integrated react router with material-ui and the routing system is working as expected. Clicking on a tab routes you to the corresponding component. However, I am facing an issue where the blue underline indicator that typically accompanies ...

The removal of the div element doesn't seem to be functioning properly

I am struggling with adding and removing div elements using jQuery. While adding a div element is working fine, I am facing issues with removing a div element. Here is the implementation: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

Submitting documents via jQuery post

I am facing an issue with my HTML form where I am trying to upload an image file. After submitting the form, I use JavaScript to prevent the default action and then make a jQuery post request (without refreshing the page) with the form data. However, despi ...

Sorting of tables does not function properly following an ajax request

I built a table that utilizes an AJAX response triggered by selecting a date from a drop-down menu. <!--datepicker--> <div class="col-md-4"> <input type="text" name="date_po_month_picker" id="date_po_month_picker" class ...

Switch up the key while iterating through a JSON object

Can you modify the key while iterating through objects using an external variable? Picture it like this: var data = [{ "id": 1, "name": "Simon", "age": 13 }, { "id": 2, "name": "Helga", "age": 18 }, { "id": 3, "name": "Tom ...

Click-triggered CSS animations

Trying to achieve an effect with regular JS (not jQuery) by making images shake after they are clicked, but running into issues. HTML: <img id='s1_imgB' class="fragment"... onClick="wrongAnswer()"... JS: function wrongAnswer(){ docume ...

JavaScript salary calculation function not functioning properly

Once the user inputs the employee's name and the number of hours they worked on the HTML form, the submit button captures this information and stores it in variables for calculating their pay. The script also factors in overtime pay. Despite feeling l ...

The function cannot be accessed during the unit test

I have just created a new project in VueJS and incorporated TypeScript into it. Below is my component along with some testing methods: <template> <div></div> </template> <script lang="ts"> import { Component, Vue } from ...

The alert box in Javascript appears before the execution of the statement preceding it

I am encountering a peculiar issue, which is not unexpected considering my limited experience with JavaScript. I am currently working on developing a basic high-low card game where two cards are drawn and the highest card wins. Below you can find the code ...