Disable the automatic scrolling feature of the daisyUI carousel when moving between slides

I recently implemented a carousel with indicator buttons from daisyUI in my Nextjs application. Unfortunately, I noticed that when clicking on an indicator button, not only does it switch slides but it also scrolls the page so that the top of the slide aligns with the top of the screen.

Is there a way to utilize this component without triggering the scroll behavior?

Answer №1

After some exploration, I believe I've cracked the code on this one. The key to solving this puzzle lies in recognizing that the carousel functions as an element with horizontal scrolling capabilities. To address this, one approach is to manually adjust the horizontal scroll using a custom Javascript function.

While the specifics may vary in Next.js, the general concept involves defining a function similar to this:

let carouselElement = . . .; // Identify and store the HTMLElement of the carousel here

function scrollCarousel(targetImageNumber) {
    let carouselWidth = carouselElement.clientWidth;

    // Image numbers range from 1 to 4, hence the subtraction by 1
    let targetImage = targetImageNumber - 1;

    let targetXPixel = (carouselWidth * targetImage) + 1;

    carouselElement.scrollTo(targetXPixel, 0);
}

To implement this solution, you can substitute <a> tags with <button> tags and include an onClick event handler that triggers manual scrolling on the Carousel HTML Element, like so:

<div class="flex justify-center w-full py-2 gap-2">
    <!-- Remember to pass the image number to the function -->
    <button onClick={scrollCarousel(1)} class="btn btn-xs">1</button> 
    <button onClick={scrollCarousel(2)} class="btn btn-xs">2</button> 
    <button onClick={scrollCarousel(3)} class="btn btn-xs">3</button> 
    <button onClick={scrollCarousel(4)} class="btn btn-xs">4</button>
</div>

I've put together an example in Stackblitz (using Svelte, my apologies) showcasing the solution here.

Answer №2

I encountered a similar issue, but managed to find a workaround by utilizing the element.scrollIntoView method.

Initially, it presented the same problem as the fragment approach mentioned by the original poster; however, when invoked with the following parameters:

slide2.scrollIntoView({ block: 'nearest', inline: 'center' })
, it smoothly scrolls horizontally without any vertical movement. For more information, refer to the MDN documentation.

In my view, this solution is somewhat simpler compared to calculating x-coordinates manually, although obtaining a reference to the adjacent slide element is still necessary. The method of doing so may vary based on the JavaScript framework being used, if any.

Answer №3

CLS Cumulative Layout Shift 🔗 https://web.dev/cls/

*ℹī¸ Have not yet conducted any testing (currently focused on other tasks, will revisit this). The following list may provide some insights or leads to better understanding of the situation. It does not appear to require heavy scripting, there may be a more elegant solution available (potentially contrary to typical library practices where target-selectors for sidemenus are used without scripting).

Here are some initial thoughts, conjectures, experiences, investigations, links, and in my opinion, the root cause of why this issue occurs.

Let's begin:

  1. Initially, it seems like anchor jumping by id, e.g. #slide1 jumps to element with id="slide1", using native anchor jumps, so preventDefault would halt everything (let's rule that out)

Suspecting the unknown width and height of the images as the root cause (necessitating safeNumbers, percentages, vw,vh in safeNumbers rather than just percentages etc. might work, but we require percentages đŸĨŗ).

  1. Check if animation targets top, right, bottom, left and if so, use: `transform: translate()` instead. Just came to mind: DaisyUI and HeadlessUI could be ideal here.  

  2. The issue could potentially be related to loading time:

img { max-width: 100%; height: auto; }

...but don't we typically preload images in carousels anyway? If so, then the dimensions of the image are known – unknown width/height of the image as the root cause – and useLayoutEffect() is where you can calculate and set px values before the render is painted to the screen, right?

  1. Aspect Ratio Solution

good luck (will fix the typos another day ^^ when I pick up your end solution hehe)

Answer №4

If you're still facing this issue, here's a solution that worked for me in my React project:

const navigateTo = (event) => {
    event.preventDefault();
    const button = event.currentTarget;

    //Alternative approach
    //const gallery = document.querySelector('.gallery');
    //const gallery = button.parentElement!.parentElement!.parentElement!;
    const gallery = document.querySelector('#imageGallery');

    const link = button.getAttribute('href');
    const targetSlide = gallery.querySelector(link);
    const offsetLeftValue = targetSlide.offsetLeft;
    gallery.scrollTo({ left: offsetLeftValue });
}

<div className="absolute flex justify-between transform -translate-y-1/2 left-5 right-5 top-1/2">
   <>
       <a onClick={navigateTo} href={"#slide" + previous} className="btn btn-circle">❎</a>
       <a onClick={navigateTo} href={"#slide" + next} className="btn btn-circle">❯</a>
   </>
</div>

I've provided the above code snippet for each anchor tag responsible for slide switching.

Make sure to adjust the id assigned to "#imageGallery" in the "navigateTo" function according to the daisy ui carousel id in your project. Add an id if necessary.

Answer №5

Although it's a bit tardy, here's a proven solution for this scenario:

import { useEffect, useRef, useState } from "react";

const ImageSlider = ({ images, slideDuration = 5000 }) => {
    const [currentSlide, setCurrentSlide] = useState(0);
    const [isAutoPlayEnabled, setIsAutoPlayEnabled] = useState(true);
    const imageSliderRef = useRef(null)

    const moveToSlide = (targetSlideNumber) => {
        let sliderWidth = imageSliderRef.current?.clientWidth;
        let targetXPos = (sliderWidth * targetSlideNumber) + 1
        imageSliderRef.current?.scrollTo(targetXPos, 0);
    }

    const goToNextSlide = () => {
        const nextIndex = (currentSlide + 1) % images.length;
        setCurrentSlide(nextIndex);
        moveToSlide(nextIndex)
    };

    const goToPreviousSlide = () => {
        const prevIndex = (currentSlide - 1 + images.length) % images.length;
        setCurrentSlide(prevIndex);
        moveToSlide(prevIndex)
    };
    
    useEffect(() => {
        if (!isAutoPlayEnabled) return; 
    
        const intervalId = setInterval(goToNextSlide, slideDuration);
    
        return () => clearInterval(intervalId);
      }, [currentSlide, isAutoPlayEnabled, slideDuration]);

    return <div className="image-slider w-full" ref={imageSliderRef}>
        {images.map((img, idx)=><div key={idx} id={`slide${idx}`} className={`image-slide relative w-full transition ease-in-out duration-700`}>
      <img src={img.url} className="w-full" />
      <div className="absolute flex justify-between transform -translate-y-1/2 left-5 right-5 top-1/2">
        <a onClick={goToPreviousSlide} className="btn btn-circle">❎</a> 
        <a onClick={goToNextSlide} className="btn btn-circle">❯</a>
      </div> 
    </div> )}
  </div>
  
}

export default ImageSlider

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

Is there a method to imitate the background-size "cover" attribute specifically for a div nested within another div using CSS?

Is there a way to have a div inside a div behave like an image with the CSS property background-size:cover? I can't use the image as a background, so I'm looking for a solution that mimics the same behavior. ...

Investigating SCSS Issues: The Problem with Absolute Imports

I am working on a project with the following structure: - my/project - assets - images - image-name.svg - source - components - MyComponent - MyComponent.module.scss - ... - ... ...

Take off the wrapping from the package

I need help with my code on how to remove the wrapper span tag without removing the text. <ul> <li> <a href="#"> </a> <ul> <li> <a href="#"> ...

Encountering a CSS issue during the edit process with PHP and JavaScript

I'm encountering an issue when clicking on the edit button, as my data fetched from the DB should be displayed inside a text field. However, I'm facing a CSS-related error: Uncaught TypeError: Cannot read property 'style' of null Belo ...

In NextJs version 13, you can access parameters from the URL directly within the layout.js file

With the introduction of server components in Next.js 13, accessing parameters from the URL has become seamless. Let's look at an example: app/shop/[tag]/[item]/layout.js /shop/1/2 { tag: '1', item: '2' } When accessing page ...

Encountering the error "gapi-script causing a ReferenceError: window is not defined in Next.js"

Despite trying numerous solutions, I continue to encounter the error shown in the screenshot below... puzzled as to why? Server Error ReferenceError: window is not defined This error occurred during page generation. Any console logs will be visible in the ...

Ways to specify the default value for a component

A sample of my custom component code (Amount.tsx) is shown below: const Price = ({ price, prevPrice }) => { return ( <div className="product-amount"> <div className="price"> {prevPrice ? (<del class ...

Arranging elements based on specific coordinates

const renderTimeSlots = () => { const timeSlots = []; for (let i = parseInt(workStartsAt); i <= parseInt(workEndsAt); i++) { if (i !== 0) { timeSlots.push( <div className="flex flex-row cursor-pointer"> ...

The Stylish Choice: Materialize CSS Dropdown Selector

I am currently integrating Materialize CSS into my application and have used media queries to ensure that the layout is responsive. However, I am facing an issue with a select dropdown element. It works fine on laptops but does not allow for selecting any ...

I am experiencing an issue with applying responsiveFontSize() to the new variants in Material UI Typography

I am looking to enhance the subtitles in MUI Typography by adding new variants using Typescript, as outlined in the documentation here. I have defined these new variants in a file named global.d.ts, alongside other customizations: // global.d.ts import * a ...

The toggle feature of the Bootstrap responsive navbar is not functioning properly

I am currently implementing Twitter Bootstrap in a Rails project, but I'm encountering issues with the responsive navbar. When I resize the screen, the menu toggle button appears along with the navbar options open below it. Upon further shrinking, the ...

"Discover the magic of jQuery: Unveiling the hidden div with one simple CSS visibility change

I want to implement a functionality on my screen where the Previous button is hidden initially and only becomes visible when the user clicks the Next button. I have set the CSS property for the Previous button to hide it by default, but despite using an if ...

Having trouble getting the Vue Sidebar Transition to work properly with tailwind CSS

I am having trouble making the sidebar function properly in relation to this link Opening works fine, but closing does not work for both overlay and sliding back. <div class="fixed inset-0 flex z-40 lg:hidden" role="dialog" aria-mod ...

I'm having trouble accessing the Next JS Docker multistage on my localhost

I have tried to dockerize a Next JS multi-build for Next JS 14 by following the instructions and cloning the repo to make sure I haven't missed any configurations. However, despite seeing the container running on port 3000 when I check with 'dock ...

What are some ways to achieve a smooth rotation of an icon?

Does anyone know why I am unable to smoothly rotate the icon? Any help would be greatly appreciated! <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!DOCTYPE html> <html> <head> ...

I am having trouble with Mpdf's block absolute positioning feature not functioning correctly

I am trying to position my block using absolute, but it seems to be staying in the same place regardless of the left/top attributes I set. Here is the PHP code snippet: $mpdf = new \Mpdf\Mpdf(); $mpdf->WriteHTML($stylesheet,\Mpdf\HT ...

What is the best way to create a smooth transition for a bootstrap navbar in chrome, toggling from right to left on

I have successfully modified the bootstrap navbar to toggle from right to left instead of top to bottom using the following code: For HTML- <nav class="navbar navbar-inverse" role="navigation" style="height: 55px; padding-top: 2px; background-color: # ...

Tips for keeping a div element at the top of the page

I am looking to have a div stick to the top of the page when someone scrolls down When the page is scrolled, the green div with class stickdiv should automatically stick to the top var left = document.getElementsByClassName("stickdiv"); for( var i = 0; ...

React Material Design Cards for Responsive Layouts

Hi there, I am currently navigating my way through Material Design and attempting to ensure that the cards section is responsive by utilizing media queries and flex. However, I have encountered an issue where only a portion of the image is displayed when t ...

The implementation of a secondary sidebar for internal pages

Currently, I am in the process of customizing a Wordpress theme and my goal is to achieve a similar 3-column layout for the homepage as seen on . Specifically, I am interested in replicating the inner sidebar's custom image title. The theme I'm ...