Disable the ability to scroll through a jQuery list as the elements near the top of the list are being changed in size

In this particular example, I have created a list with a click handler. The behavior is such that when an element in the list is clicked, the ".selected" class is added to it, which changes its height. Subsequently, if another list element is clicked, the ".selected" class is removed from the previously clicked element (thus restoring it to its original height) and added to the newly clicked element, altering its height.

Upon observing the demonstration in another version, an interesting behavior is noticed. When a lower list element is clicked, the clicked element remains stationary while expanding, and the previous selection contracts. However, clicking on an upper list element results in the list scrolling up to accommodate the contracting element, causing slight movement in the newly selected element. It would be ideal to implement a solution that prevents this scroll behavior, ensuring a seamless experience where the ".selected" list element remains still even in this scenario.

HTML:

<ul>
 <li>1</li>
 <li>2</li>
 <li>3</li>
 <li>4</li>
 <li>5</li>
 <li>6</li>
 <li>7</li>
 <li>8</li>
 <li>9</li>
 <li>10</li>
</ul>

JavaScript:

$(document).ready(function () {
    $("li").click(function () {
        $(".selected").removeClass("selected");
        $(this).addClass("selected");
    });
});

CSS:

li{
    width:100%;
    border-top:solid black 1px;
    height:100px;
    background:green;
}

.selected{
    height:300px;
    background:red;
}

Answer №1

If you're looking to ensure that the newly selected element remains in view with offset scroll, I recommend using the code below:

$(document).ready(function () {
    $("li").click(function(){

        var $this = $(this),
            pos = $this.offset().top,
            $doc = $(document);

        $(".selected").removeClass("selected");
        $this.addClass("selected");

        $doc.scrollTop($doc.scrollTop() + $this.offset().top - pos);
        console.log($this.offset().top - pos);
    });
});

Check out the DEMO here

Answer №2

Up until now:

I hope to find a way to smoothly control this behavior so that the ".selected" list item remains completely still in this situation.

I don't see how you can maintain it "completely still" because if the other item shrinks, and the rest of the list is somehow "fixed" in place, there would be a large gap between the items...

A few ideas... this css:

li{
    width:100%;
    border-top:solid black 1px;
    height:100px;
    background:green;
    transition: height 2s;
    -webkit-transition: height 2s;
}

.selected{
    height:300px;
    background:red;
    transition: height 2s;
    -webkit-transition: height 2s;
}

Creates a smoother transition that is easy on the eyes.

To achieve what you requested, "completely still," you could try something like this:

    $(document).ready(function () {
$("li").click(function(){
    $(".previouslySelected").removeClass("previouslySelected"); $(".selected").removeClass("selected").addClass("previouslySelected");
    $(this).addClass("selected");
});
    });

CSS

.previouslySelected {
    height:100px;
    margin-bottom:200px;
}

This prevents the item below from "jumping"... though I see this as a silly approach because I didn't bother checking if the newly clicked item was higher or lower than the previously selected one etc... but that could be easily added. Understand?

Answer №3

Have you considered adding a transition to the <li> elements? This will create a smooth effect when transitioning between selected and not-selected states.

li{
    width:100%;
    border-top:solid black 1px;
    height:100px;
    background:green;
    -webkit-transition: all .5s ease-in-out;
    -moz-transition: all .5s ease-in-out;
    -o-transition: all .5s ease-in-out;
    transition: all .5s ease-in-out;
}

.selected{
    height:300px;
    background:red;
}

Check out the DEMO here!

Answer №4

Give this jQuery solution a try:

 $(document).ready(function() {
   $("li").click(function() {

     var selectItemTop = $(this).position().top;

     var windowTop = $(window).scrollTop();
     var selectItemHeight = $(".selected").height();
     var selectionTop = $('li').hasClass('selected') ? $(".selected").position().top : 0;
     console.log(selectionTop);
     if (selectionTop < selectItemTop) {
       selectItemTop = selectItemTop - windowTop;
       $(window).scrollTop(windowTop + selectItemTop - selectItemHeight);

     }


     $(".selected").removeClass("selected");

     $(this).addClass("selected");


   });

I was able to get close to meeting your needs successfully.

To see an example in action, click on this link

Answer №5

$(document).ready(function () {
$("li").click(function(){    
    var selectedTop = $(this).position().top;    
    var scrollTop = $(window).scrollTop();
    var selectedItemHeight = $(".chosen").height();
    var selectionPosition =  $('li').hasClass('chosen') ? $(".chosen").position().top : 0;
    console.log(selectionPosition);    
    if(selectionPosition < selectedTop){
      selectedTop = selectedTop-scrollTop;
            $(window).scrollTop(scrollTop+selectedTop-selectedItemHeight);        
    }
    $(".chosen").removeClass("chosen");
    $(this).addClass("chosen");    
      });

    });

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

"Displaying an array using React Hooks' useState causes the content to

I want to enhance my image uploading functionality in useState by implementing a specific function. Once the images are uploaded, I need to render them on the page. However, I am facing an issue with rendering the returned array. Here is the current code ...

Tips for customizing the appearance of the day button in a React Material-UI date picker

In my React project, I am using material-ui date picker and I am looking for a way to customize the styling of the day buttons. Specifically, I want to change the text color of the available days. By default, as seen in the screenshot, the text color is bl ...

unemployed with XMLHttpRequest not functioning

I have exhausted all recommended solutions for similar issues, yet this simple code refuses to work. My goal is to retrieve a message from the PHP code in the same file using XMLHttpRequest. <!DOCTYPE html> <head></head> <body> < ...

Ways to eliminate the black fill color from a smiley face icon and replace it with white色

I am looking to modify my custom icon in my application. It currently has a black fill, but I need to change the fill color to white while keeping the border of the smiley face black. The original smiley icon is provided below: https://i.sstatic.net/44gTw ...

Ensure that your ASP.NET application can gracefully switch between executing codebehind logic when JavaScript is not available, and calling JavaScript

Looking for advice on how to handle form processing in an asp.net page depending on whether the user's browser supports JavaScript. Specifically, I want to call JavaScript methods if available, and fallback to using code behind events if JavaScript is ...

What is the best way to trigger the opening of this modal after a certain amount

I'm currently working on a CSS and HTML modal and I'd like it to appear 3 seconds after the page loads using jQuery. I'm struggling to find the right event handler for this task. How can I achieve this effectively? Check out the modal desig ...

Output JSON data to an HTML5 table

Here is a code snippet to retrieve data: function fetchInformation(){ $.get('http://mywebsite.net/getFile.php', function(data) { var result = JSON.parse(data); } The returned JSON data is as follows: Object {0: "11", 1: ...

Adjust the header width and column alignment when freezing the header in a gridview interface

Looking to implement a gridview with a fixed header? I've tried various solutions including this link and this one. While I've managed to get it working, the main issue lies in the alignment of header width and column width. The scroll and freez ...

The zip() operator in RxJS is not functioning as intended. It consistently finishes execution without emitting any values

Suppose you have an observable containing a large number of elements, say 450 or more. You want to transfer these elements to a different observable in batches of 100 elements each. You can check out a functional example provided by @martin at this link: ...

Using jQuery and $.ajax to update <td> contents

I need assistance with updating the content of a table using jQuery. Here is an example of my table structure: <table id="table-name"> <tr><td id="td-name">something</td></tr> <tr><td id="td-name">somethin ...

Using the Angular translate filter within a ternary operator

I am currently working on translating my project into a different language. To do this, I have implemented the Angular Translate library and uploaded an external JSON file containing all the translations. Here is an example of how it looks: { "hello_wor ...

Encountering an issue of Property not existing on JSX intrinsic elements when utilizing TSS with Javascript (without TypeScript)

I am currently working on a JavaScript project (using create-react-app 2.0) and utilizing tsserver without Typescript. I encountered a linting error that states: Property 'svg-icon' does not exist on type 'JSX.intrinsictElements'. Thi ...

Encountering challenges with the angular2-infinite-scroll plugin

I encountered 2 errors while using my application: Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:3002/angular2-infinite-scroll angular2-polyfills.js:1243 Error: XHR error (404 Not Found) loading htt ...

Trying to find out which div is currently visible on the screen

As part of my project, I am working on implementing a swipe effect that involves moving the upper div based on calculated x and y coordinates. This creates a swipe-like visual effect by adjusting the wrapper's position with the screen width. However, ...

Create an immediate impact by injecting CSS

I currently have the following code set up: style.js: function applyStyle(str) { var element = document.createElement('style'); element.innerHTML = str; document.body.appendChild(element); } var style = 'body {' style ...

What is the best way to display items from top to bottom in React?

Currently, I am working with a list of objects structured in this way: const items = [{name: 'some name', count: 'how many of that name'}, ...] My goal is to display them in the following format: {items.map((item) => ( ...

Understanding how to parse a JSON object in JavaScript is a

In my JSON object, I have the following data: rows = [{name:"testname1" , age:"25"}, {name:"testname2" , age:"26"}] My goal is to extract the names and store them in a variable like this: name = "testname1, testname2"; ...

Modifying the color of text within an element using CSS and the ::after pseudo

Is there a way to change the text color when a user hovers over it without interfering with the background effect? I currently have a hover effect set to show a background section when hovering over the text, but when I try to change the text color separat ...

Sharing a Detailed Mongoose Schema

Hey there! So, I've been working on this Mongoose Schema and there seems to be something off about it. The main area of concern is the "region" part. const mongoose = require('mongoose'); const destination = new mongoose.Schema({ ...

What is the best way to determine if a JSON response value contains a hyphen '-' in Java Script?

When I receive a JSON response, I sometimes encounter values with hyphens. In JavaScript, the hyphen '-' is treated as a subtraction operator. JSON books": { "red": "2008-17801", "blue": "TERTERIAN-HAYK" } After obtaining these values, I store ...