mdbootstrap / perfect-scrollbar

Minimalistic but perfect custom scrollbar plugin. Get more free components with Material Design for Bootstrap UI Kit (link below)
https://perfectscrollbar.com/
MIT License
353 stars 69 forks source link

Smooth scroll behavior broken with Chrome v102+ #138

Open romrg opened 2 years ago

romrg commented 2 years ago

The perfect scrollbar element does not scroll to the expected offset with the 'smooth' behavior with the latest version of Chrome (v102). There is only a 1px change. It was working with previous versions.

See this jsfiddle: https://jsfiddle.net/5svurjg9/15/

NicerDicerPro commented 2 years ago

Any information or workarounds on this yet? (Using the react wrapped component of this, having the exact same issue tho).

Rotarepmi commented 2 years ago

Same issue

hjborger commented 2 years ago

Same issue here, problem seen in recent version of Chrome and Safari

Problem seems to be in the update-geometry.js If I disable element.scrollLeft / scrollTop it seems to work again.

  if (i.scrollbarXActive) {
    element.classList.add(cls.state.active('x'));
  } else {
    element.classList.remove(cls.state.active('x'));
    i.scrollbarXWidth = 0;
    i.scrollbarXLeft = 0;
//    element.scrollLeft = i.isRtl === true ? i.contentWidth : 0;
  }

  if (i.scrollbarYActive) {
    element.classList.add(cls.state.active('y'));
  } else {
    element.classList.remove(cls.state.active('y'));
    i.scrollbarYHeight = 0;
    i.scrollbarYTop = 0;
//    element.scrollTop = 0;
  }
tibineagu commented 2 years ago

We've had this issue with chrome 102 as well.

Element.scroll with behaviour: 'smooth' in the options seems to be broken.

ZeeshanAhmadKhalil commented 2 years ago

Getting the same issue when using scroll-behavior: smooth !important; in css and I sus that it's due to the perfect scrollbar.

ZeeshanAhmadKhalil commented 2 years ago

Same issue here, problem seen in recent version of Chrome and Safari

Problem seems to be in the update-geometry.js If I disable element.scrollLeft / scrollTop it seems to work again.

  if (i.scrollbarXActive) {
    element.classList.add(cls.state.active('x'));
  } else {
    element.classList.remove(cls.state.active('x'));
    i.scrollbarXWidth = 0;
    i.scrollbarXLeft = 0;
//    element.scrollLeft = i.isRtl === true ? i.contentWidth : 0;
  }

  if (i.scrollbarYActive) {
    element.classList.add(cls.state.active('y'));
  } else {
    element.classList.remove(cls.state.active('y'));
    i.scrollbarYHeight = 0;
    i.scrollbarYTop = 0;
//    element.scrollTop = 0;
  }

Commented these two lines but getting the exact same issue.

Marme7ad commented 2 years ago

Same issue

NicerDicerPro commented 2 years ago

Any update on this?

zeffon commented 1 year ago

Any update on this?

danny-dang commented 1 year ago

Pump!!

Youhan commented 1 year ago

I have the same issue using Chrome 115

DominikGanic commented 9 months ago

Any updates? Still broken.

EliseiNicolae commented 6 months ago

I had the same issue.

As a workaround I've used some js to make that smooth transition:

    scrollBy (offsetX, offsetY, duration = 0) {
      const startTime = performance.now()
      const startX = this.$el.scrollLeft
      const startY = this.$el.scrollTop

      if (duration === 0) {
        // Immediate jump to the new position
        this.$el.scrollLeft = startX + offsetX
        this.$el.scrollTop = startY + offsetY
        this.ps.update()
        return
      }

      const animateScroll = () => {
        const elapsedTime = performance.now() - startTime
        const fraction = Math.min(elapsedTime / duration, 1)
        const easeOutQuad = t => t * (2 - t)
        const fractionEased = easeOutQuad(fraction)

        const newScrollX = startX + fractionEased * offsetX
        const newScrollY = startY + fractionEased * offsetY

        this.$el.scrollLeft = newScrollX
        this.$el.scrollTop = newScrollY
        this.ps.update()

        if (fraction < 1) {
          requestAnimationFrame(animateScroll)
        } else {
          // Ensure final scroll position is set correctly
          this.$el.scrollLeft = startX + offsetX
          this.$el.scrollTop = startY + offsetY
          this.ps.update()
        }
      }

      requestAnimationFrame(animateScroll)
    },

where ps is:

this.ps = new PerfectScrollbar(this.$el, this.$props.options)

Hope this helps 🚀

plashenkov commented 1 month ago

Perfect scrollbar isn't perfect as it turned out 😂