Enhancing the efficiency of a JavaScript smooth scrolling feature for numerous listed items

I have been experimenting with recreating the recent Apple Mac retrospective using only CSS and JavaScript to create a small timeline of projects. While I have successfully implemented the layout for the full-screen hero and the expand-on-hover effect, I am facing an issue with achieving smooth scrolling for the timeline in the second half of the screen. Even when scrolling slowly, there is noticeable jitteriness in Google Chrome 32.0.1700.102 on Mac OS X. You can access the files needed for this project here.

I have two specific questions:

  1. Can you provide a solution using pure CSS/JavaScript to fix the smooth scrolling issue? I would prefer guidance on debugging this example rather than redirecting me to another working solution.

  2. In addition, what steps should I take to identify and isolate the problem during the debugging process? I attempted to collect a JavaScript CPU Profile but did not find any problematic areas that require attention.


Basic Structure

The timeline is structured as a navigation element (nav) containing an ordered list where each list item (li) represents a project.

<nav id='timeline'>
    <ol>
        <li class='project' id='zero'>
            <div class='description'>
                <h2> Project 0 </h2>
                <span> The project that changed everything </span>
                <div class='icon'></div>
            </div> <!-- div.description -->
        </li> <!-- li.project#zero -->
    </ol>
</nav> <!-- nav#timeline -->

An event loop is used to detect mouse position globally and handle scroll detection,

// Event loop to update global mouseX, mouseY positions and handle scroll detection
var mouseX = null;
var mouseY = null;
var scrollTimeline = null;
var updateInterval = 10;
var scrolling = false;
window.onmousemove = function(event) {
    mouseX = event.clientX;
    mouseY = event.clientY;
    if (!scrollTimeline) {
        scrollTimeline = window.setInterval(scroll, updateInterval);
    }
};

This event loop calls a scroll handler every 10ms,

function scroll(event) {
    var buffer = window.innerWidth/4;

    var distanceToCenter = Math.abs(window.innerWidth/2-mouseX);
    var speed = distanceToCenter/(window.innerWidth/2);
    if (mouseX < buffer) {
        scrolling = true;
        scrollLeft(speed);
    }
    else if ((window.innerWidth - mouseX) < buffer) {
        scrolling = true;
        scrollRight(speed);
    }
    else {
        scrolling = false;
        window.clearInterval(scrollTimeline);
        scrollTimeline = null;
    }
}

The scrolling effect is achieved by adjusting the left attribute of the navigation container using functions such as scrollRight and scrollLeft, based on the mouse position.

function scrollRight(speed) {
    var leftPixels = parseInt(getStyleProp(timeline, 'left'), 10);
    var toShift = Math.pow(speed,3)*updateInterval;
    var newLeft = leftPixels - toShift;

    if (newLeft >= -1400 && newLeft  <= 0) {
        timeline.style.left = newLeft + 'px';
    }
}

A handy utility function called getStyleProp is used to retrieve style properties like the computed left attribute.

// Utility function to grab style properties when unset
function getStyleProp(elem, prop){
    if(window.getComputedStyle)
        return window.getComputedStyle(elem, null).getPropertyValue(prop);
    else if(elem.currentStyle) return elem.currentStyle[prop]; //IE
}

What I've Tried

In my attempts to resolve the issue, I have:

  • Removed some CSS transitions creating the scalloped effect
  • Opted for one image instead of six images
  • Adjusted the left attribute incrementally rather than in large increments
  • Eliminated text content and respective transitions
  • Removed certain list items within the navigation container, which temporarily resolved the problem, although I am uncertain how this led to the observed jitteriness.

Thank you for your assistance!

Answer №1

It appears that the initial jitter was caused by the extra load of implementing the saturate transform in CSS. I was able to discover a more efficient solution by incorporating requestAnimationFrame.

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

Ways to stop cascading CSS attributes to child elements?

I am in the process of creating three tables. <table id="first"> <tr> <td> 1. CAPTION </td> </tr> <tr> <td> <table id="second"> <tr& ...

Tips for maintaining a loading screen for longer than 4 seconds?

I want to maintain the loading screen for a minimum of 4 seconds. However, the timer at the end does not seem to be functioning as expected. Here is the code snippet I am using: window.addEventListener("load", () => { const preload = document.querySe ...

Tips on utilizing AngularJS $http for transferring multipart/form-data

In the process of creating a visual interface that interfaces with various REST services (coded in Java), I am encountering an issue when attempting to call one such service: @PUT @Path("serviceName") public Response serviceName(final FormDataMultiPart mu ...

Steer clear of including optional dependencies when using Yarn for package installations

Within my yarn.lock file, there is a single reference to momentjs: pikaday@^1.6.0: version "1.6.1" resolved "https://registry.yarnpkg.com/pikaday/-/pikaday-1.6.1.tgz#b91bcb9b8539cedd8dd6d08e4e7465e12095671b0" optionalDependencies: moment "2.x" ...

Is it possible to use Chrome developer tools to find out the current file's name?

I am having difficulty locating a specific code within my online shop on Prestashop. The meta-data of the current page contains the content="Shop on PrestaShop" string, but when I search for it in Webstorm to identify which page file it is located in, I ca ...

Conceal a single column on mobile devices using Bootstrap 4

Take a look at this code snippet: <div class="row"> <div class="col-lg-3"> <div class="ava-block"> </div> </div> <div class="col-lg-6 ...

The folder could not be located by MAMP

For years, I've relied on MAMP to manage my web development projects. However, after performing a clean install of my Mac recently, I reinstalled MAMP only to encounter issues with it not functioning properly. Upon reinstalling the program and placin ...

AngularJS directive not registering event after model update

Within my angularjs application, I have implemented an element directive that is equipped with an event listener. This listener is designed to respond to a broadcast event from the controller. app.directive('listItem', function(){ return { ...

Ways to create two separate references pointing to a single object

Here is the code I am currently running: function TypeOfCar(vehicle) { this.vehicle = vehicle; } var sedan = new TypeOfCar('sedan'); var carType = race; console.log(carType); console.log(sedan); After running the code, the output is as follo ...

When using React, draggable components with input fields may lose their ability to receive focus when clicking on the input field

<Draggable axis="y" grid={[135,135]} onStop={this.handleStop} defaultPosition={{x: this.props.task.positionX, y: this.props.task.positionY,}}> <div id="edit-task-component"> <form onSubmit={this.handleSubmit} id=" ...

Description positioned along the edge of the image

Is it achievable in Bootstrap 4.1 to have the caption aligned with the image margin as displayed in the image below? Illustration of aligning caption with image Following the sample at getbootstrap.com, there exists a discrepancy between the caption and ...

"Here's a simple guide to generating a random number within a specified range

I have encountered a specific issue: Within an 8-column grid, I am attempting to randomly place an item with a random span width. While I have successfully managed to position the item and give it a random width, I am struggling with adjusting the width b ...

Emphasize a specific line of text within a <div> with a highlighting effect

I'm looking to achieve a similar effect as demonstrated in this fiddle As per StackOverflow guidelines, I understand that when linking to jsfiddle.net, it's required to provide some code. Below is the main function from the mentioned link, but f ...

Utilizing the Fetch API to retrieve a Flickr feed in JSON structure

When interacting with the flicker feed API, I have successfully received a JSON response using $.getJSON. However, when attempting to use Fetch instead, only an XML response seems to be retrieved. Example of working with $.getJSON: var flickerAPI = "http ...

Press on the row using jQuery

Instead of using link-button in grid-view to display a popup, I modified the code so that when a user clicks on a row, the popup appears. However, after making this change, nothing happens when I click on a row. Any solutions? $(function () { $('[ ...

Ensure the Firebase real-time database in Javascript purges the active session upon tab or browser closure

I need to implement a feature in my Firebase real-time database project using JavaScript where the current session is logged out automatically after closing the tab or browser. When I log in with my email and password, if I copy the URL and paste it into ...

The CSS list formatting does not seem to be compatible with Bootstrap 4

For my website, I am working on creating a table using the list method along with CSS. However, I encountered a problem where the table is not displaying correctly when Bootstrap CDN is applied. Removing Bootstrap CDN resolves the issue, but I need to keep ...

When individuals discuss constructing a stack, or a full stack, in JavaScript, what exactly are they referring to and how does this concept connect with Node JS?

I recently started learning about node.js, but I'm struggling to understand its purpose. I have experience with JavaScript/jQuery and Angular, so I don't see how Node can benefit me. People keep talking about full stack JavaScript but I'm st ...

Retrieve the total count of rows present in a specific table

Is there a way to accurately determine the number of rows in a table? I've attempted multiple methods (all unsuccessful) and this is my latest attempt: var _tableOfInterestsCount = wait.Until(x => x.FindElements(By.XPath("//*[@id='gridBody ...

Retrieve key codes from inputs sharing the same class

My webpage contains multiple text inputs that all share the same class for various reasons. Currently, I am attempting to capture the ESC button press when an input is focused and alert whether the input has a value or not. However, this functionality on ...