Coder Social home page Coder Social logo

scroll-into-view / scroll-into-view-if-needed Goto Github PK

View Code? Open in Web Editor NEW
1.3K 11.0 76.0 8.23 MB

Element.scrollIntoView ponyfills for things like "if-needed" and "smooth"

Home Page: https://scroll-into-view.dev

License: MIT License

JavaScript 77.96% TypeScript 6.54% CSS 1.53% HTML 13.96%
ponyfill scrolling animation smooth-scrolling typescript polyfill scrollintoview scroll-into-view smooth smoothscroll

scroll-into-view-if-needed's People

Contributors

ambar avatar arturbien avatar borm avatar dependabot[bot] avatar forabi avatar github-actions[bot] avatar greenkeeperio-bot avatar hemnstill avatar icd2k3 avatar imgbot[bot] avatar iwangulenko avatar jclijmans avatar jkillian avatar khell avatar li-jia-nan avatar long76 avatar madkap avatar pelotom avatar philipp-spiess avatar prettierci[bot] avatar renovate[bot] avatar rostimelk avatar semantic-release-bot avatar sindresorhus avatar stipsan avatar stramel avatar tonybdesign avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scroll-into-view-if-needed's Issues

Content partially hidden behind scrollbars

When I set block/inline to end or nearest, in a container with scrollbars, part of the target element on the bottom and right remains hidden behind the scrollbars.

This is visible on https://scroll-into-view-if-needed.netlify.com/, the "scroll alignment" example. With block and inline both set to nearest, scrolling to 9 results in the green box being only partially visible, while scrolling to 1 results in that green box being fully visible. If I set the container to overflow: visible in devtools, scrolling to 9 results in the green box being fully visible, like for 1.

I get this behaviour on both Firefox 52.5 and Chromium 64.0.

Incorrect scroll behaviour on a page

Version: 2.2.14.
See the gif:

1234

I don't observe the bug on the react-responsive-ui demo page but in a real-world app I can see the bug.
Don't know what could cause such behaviour.
I guess there could be many variables affecting that.

I downgraded to various versions and found out that 2.1.0 doesn't have the bug and >= 2.1.1 has the bug, so I guess it was some change from 2.1.0 to 2.1.1.
I'm staying on version 2.1.0 because of that.

Scrolling on element happens only the first time

I have a slider of elements and a large view below the slider that is mounted when an element is clicked.
I have used scrollIntoViewIfNeeded when the large view component gets mounted.
It scrolls nicely the first time, but when i close the view and then open it again. It does not scroll.

Scrolling up doesn't work with scrollMode: if-needed

πŸ‘‹ hey there,

After some investigation of an issue posted in react-scroll-into-view-if-needed here. It looks as though there is a bug with the following behavior:

  • scrolling up to a target block with scrollMode: 'if-needed'.

I setup this codesandbox to demonstrate: https://codesandbox.io/s/l4w26w2jz7
(note: it is in React, but I'd be happy to setup an html/css only one soon if it helps)

In this example, with scrollMode set to 'always', scroll to the bottom of the page and click this button at the bottom:
button

Notice that it scrolls up to the target as expected

Now, switch to 'if-needed' and notice the button does not scroll up to the target.

I'm happy to dig deeper in the near future and submit a PR if I can find the problem, but in the meantime just wanted to document it here for visibility.

Thanks for your work on this package!

What happened to duration?

Hi, I just upgraded to v2, which looks great, except the duration option seems to have gone away... is it no longer possible to specify a duration for the smooth scroll animation?

Bug - full-height elements can't scroll into view

I ran into a situation in my code where I wanted to change something so that a full-height element (same height as scroll container) would scroll into view. To my surprise, nothing happened. I thought it must be my code, so I made a Codepen, with the same behavior (nothing happens): https://codepen.io/matthewdean/pen/KxaJga

To verify that it wasn't something wrong with scrolling setup, I made a 99% height tile version, which works: https://codepen.io/matthewdean/pen/qMRgVL

Then I thought, "Well maybe this is just a bug where elements larger than the scrollable area don't scroll into view," at which point I discovered something totally bonkers. A Codepen with tiles that are 101% also work. https://codepen.io/matthewdean/pen/QVdYQp

So this bug appears to be that only tiles the same exact height as the scrollable area cannot scroll into view

Expose amator's `done` option?

I need to do something after the animation is done but don't see a way of doing it with the current options, outside of doing something like setTimeout using the duration time.
I noticed aminate function accepts a done option that isn't being used by this package.

typescript typings are wrong

Typescript, unlike babel, differentiates between default and "whole" exports, this is.
import * as X from 'X'; = require('X')
import X from 'X'; = require('X').default;

whereas in babel
import X from 'X'; = require('X').default || require('X');

the thing is that the TS typings say that the function is actually on require('X').default, but it is actually in require('X') due to this last line in the generated index.js:

module.exports = exports['default'];

something to do most probably with how rollup does it.
could the typings be fixed? or if not at least then make it actually export the function on default :)

NPM distribution is unusual

Just tried out this package for this first time, and I'm a big fan! The native browser scrollIntoView was causing issues for me and this package is working perfectly.

However, I did notice the NPM distribution for this package is somewhat strange. The distributed files, specifically dist/bundle.js seem to contain all the dependent packages bundled together. This isn't the NPM way - ideally your distributed module should just require the other modules it wants to use. My friendly suggestion here is to use babel to compile your src/index.js file and distribute that in your final package as either index.js or dist/index.js and appropriately link to it in your package.json. You can still distribute the full rolled-up dist/bundle.js if you want, but it shouldn't be the main file.

Also, I noticed that the export in the distributed version is not a default export. So you have to do import * as scrollIntoView from "scroll-into-view-if-needed" instead of the examples given in the README.

Finally, I'd recommend adding the MIT license or another similar license to this package! Don't want to scare people away from using it πŸ˜„

Why accept arg #2 (centerIfNeeded) and options.centerIfNeeded?

This is mostly curiosity: why even include the 2nd parameter if the options parameter can do so?

The following cases (I presume) are analogous:

scrollIntoViewIfNeeded(myEl, true);
scrollIntoViewIfNeeded(myEl, null, {centerIfNeeded: true});

If they aren't analogous:

  1. Why not?
  2. Why is it not documented?

I feel as though the signature could be simplified to just be:

export default function(
  node: Element,
  options?: ScrollIntoViewIfNeededOptions,
  finalElement?: Element
): void;

I understand that parameter 2 is for convenience (at least I assume so), in which case, I recommend removing it from the ScrollIntoViewIfNeededOptions interface to avoid confusion.

Otherwise good work on a useful module. It's nice to have this around instead of pretending that browsers support the native implementation ;)

animation not working

Using
scrollIntoViewIfNeeded(node, {duration: 500});

It is getting scrolled to that particular div but but animation is not working.
pls look into this.

compute.js

Hi,
you left console.log in compute.js -> line 67 -> "console.log('test')"

Body behind the modal scrolls

I have modal inside which I have a list of passengers who have scroll into view when clicked on a particular passenger. This works perfectly fine, but the body behind the modal also scrolls when this happens even thous I have frozen scroll using "overflow: hidden" CSS property. How to avoid body scroll.

Todo for v2

Moving it out of #155 so this can be done in multiple PRs.

Guiding principles behind the rebuild

  • Ponyfill principles, never alter globals that one day could break the web (cough cough mootools cough cough)..
  • Minimal in design and API surface.
  • Follow the Element.scrollIntoView(ScrollIntoViewOptions) spec and related draft specs instead of reinventing the wheel.
  • Comprehensive testing suite to ensure the spec is implemented correctly, and that common use cases are accounted for.
  • Modular design, favor composition over configuration.
  • Adapts to your priorities. If speed and bundlesize is more important than every visitor seeing a nice smooth scroll then the default version is enough. If a consistent user experience for all your users is more important, opt in to the smooth-behavior ponyfill.
  • Sensible defaults, zero-config (as long it doesn't break spec compliance).
  • Lifecycle hooks instead of a million options.

Entirely new API, implementing Element.scrollIntoView(ScrollIntoViewOptions) and {scrollMode: 'if-needed' | 'always'}.

  • new docs page.
  • upgrade cypress to be all TS.
  • upgrade next.js to follow TS best practice.
  • upgrade next.js to export test pages when cypress is running it.
  • update readme.
  • rewrite old tests to new changes.
  • migration guide with a list over breaking changes.
  • new rollup build that generates react-router like suite of bundles so this package is easier to consume for most people.
  • {scrollMode: 'if-needed'}, this feature is what spawned the creation of this package, but it needs to be rewritten to simply check if something isn't visible before it should optimistically attempt scrolling it into view (reference implementations: 1)
  • {scrollMode: 'always'}, and suddenly this package became a lot more useful.
  • {block: 'start'}
  • {block: 'center'}
  • {block: 'end'}
  • {block: 'nearest'}
  • {inline: 'start'}
  • {inline: 'center'}
  • {inline: 'end'}
  • {inline: 'nearest'}
  • scroll it yourself {behavior: (scrollInstructions: [Element, scrollTop, scrollLeft])}. Maybe you want to be creative, or a different transition, easing, do it in a sequence or throttle it. Whatever floats your boat.
  • {behavior: 'smooth'} (ensure ponyfilled animation matches what firefox and chrome is doing, it must not feel slow or odd).
  • {boundary: Element}, limit propagation of scrolling as it traverses innermost to outermost scrolling boxes by passing in an element reference.
  • {boundary: (el: Element) => boolean}, provide a way to do custom checks. This solves the problem with cross-realm elements (scrolling up iframes and frames) where referencial checks won't work. It also provides an escape hatch for userland business logic like "skip all elements that are overflow: hidden".

Testing strategy

Helpful reference material

https://github.com/chromium/chromium/blob/f18e79d901f56154f80eea1e2218544285e62623/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js#L392-L433

https://github.com/chromium/chromium/blob/7bacbbc6c0e5e337f642811374d9023f52795bd3/chrome/browser/resources/chromeos/chromevox/common/selection_util.js#L226-L249

http://www.performantdesign.com/2009/08/26/scrollintoview-but-only-if-out-of-view/

https://github.com/chromium/chromium/blob/f18e79d901f56154f80eea1e2218544285e62623/third_party/WebKit/LayoutTests/fast/scroll-behavior/bordered-container-child-scroll.html

https://github.com/iamdustan/smoothscroll/blob/master/src/smoothscroll.js

https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/dom/element.cc?sq=package:chromium&dr=CSs&l=500

Using FireFox' implementation as reference

The way FireFox handles smooth scrolling, and the scrollIntoView features in general is the best one today. So I am using their C++ implementation to guide me on the JS implementation: https://github.com/mozilla/gecko/blob/03abe3240ab1ad8c2e7f78ebb16a6bd3c17febb1/layout/base/PresShell.cpp#L3626-L3743

Rationale from dropping Element.scrollIntoViewIfNeeded

The fine folks over at chromium are already discussing removing this non-standard api: https://bugs.chromium.org/p/chromium/issues/detail?id=699843&q=scrollintoView&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified

It's time to move on πŸ˜ƒ

Can i set a offset?

I have some thing floating on the screen like header. I want to set a offset to scroll more and show the content behind the floating header out.

Add option to force centering

Description of options.centerIfNeeded says:

Center the target if possible, and if it's not already visible. If it's not centered but still visible it will not scroll

Description of options.forceCenter would be:

Brute force version of options.centerIfNeeded. This will adjust the scroll to center the target even if it's visible already

`scrollIntoView` Promise doesn't resolve on some elements

I discovered an apparent bug, where I have something like this:

scrollIntoView([HTMLElement], {
  scrollMode: 'if-needed',
  block: 'nearest',
  boundary: document
}).then(() => { console.log('done') })

It appears that if the element doesn't need to be scrolled into view (or some other reason?), then the Promise will never resolve. Even if I change .then() to .finally(), nothing happens. No console.log is output. Meaning I can't chain scrollIntoViews.

I didn't have this problem until the element I needed to check if it needed to be scrolled into view was sometimes the same height as the document.

Setup automatic changelog generation

Changelog haven't been updated since v2, and I'd rather not continue to update it manually.

It should be generated the same way release notes are generated during publish.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.


Using a curated preset maintained by


Sanity: The Composable Content Cloud

Pending Approval

These branches will be created by Renovate only once you click their checkbox below.

  • chore(deps): update dependency @sanity/pkg-utils to v5
  • chore(deps): update dependency @sanity/pkg-utils to v6
  • chore(deps): lock file maintenance
  • πŸ” Create all pending approval PRs at once πŸ”

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

circleci
.circleci/config.yml
  • circleci/node 17
  • circleci/node 17
  • circleci/node 17-browsers
  • circleci/node 17
github-actions
.github/workflows/ci.yml
  • actions/checkout v4
  • actions/setup-node v4
  • actions/checkout v4
  • actions/setup-node v4
  • actions/checkout v4
  • actions/setup-node v4
.github/workflows/prettier.yml
  • actions/checkout v4
  • actions/setup-node v4
  • actions/cache v4
  • EndBug/add-and-commit v9@61a88be553afe4206585b31aa72387c64295d08b
npm
package.json
  • compute-scroll-into-view ^3.0.2
  • @sanity/pkg-utils ^3.2.2
  • @sanity/semantic-release-preset ^4.0.0
  • cross-env ^7.0.3
  • prettier ^3.0.3
  • prettier-plugin-packagejson ^2.4.3
  • rimraf ^4.1.2
  • typescript ^5.0.0

  • Check this box to trigger a request for Renovate to run again on this repository

Add support for upcoming promise behavior

Smooth scrolling will return promises in the future: w3c/csswg-drafts#1562

Suggested implementation here is:
If the browser is returning a promise, pass it through and let the browser decide how it's resolved.
If the browser isn't returning a promise, but the behavior is set to "smooth", use Promise.reject as there is no way of knowing when scrolling is complete anyway so userland code needs to handle both cases.

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


The push permission to the Git repository is required.

semantic-release cannot push the version tag to the branch master on remote Git repository with URL http://[secure]@github.com/stipsan/scroll-into-view-if-needed.git.

Please refer to the authentication configuration documentation to configure the Git credentials on your CI environment and make sure the repositoryUrl is configured with a valid Git URL.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

how to know when scrolling is complete?

Hi, is there any way to know whether the scroll into view action has completed (promise resolution? a recommended timer approach?)?

the closest to this issue I found is #387 . Thanks!

Set block: nearest with offset?

I need to be able to scroll into view with block: 'nearest' but with an offset. So this means I can have it scroll to the bottom of a div, but provide some buffer space below so the div isn't on the exact bottom of the screen. The center option is too drastic for my use, I just need a buffer of 30 pixels or so but still want it at the bottom of the screen.

I'm hoping there is a way to do this, but if not then this would be a feature request :)

How can I combine behavior function and behavior smooth

Hi, there.

Because there is a banner above the scroll container, I need to set a target offset. I tried the behavior function implementation, but also wanted to use behavior smooth. How can we combine the two? Do you have any idea?

behavior: actions => {
      const [{el, top}] = actions;
      el.scrollTop = top - targetOffset
      return scrollMotion ? 'smooth' : 'auto'; // works or not?
}

Scrolls both window and container

Hi πŸ‘‹ Thanks for making this library!

I'm using it to scroll a list that has overflow-y: scroll. However, when scrolling to an element on the bottom of this list the window is scrolled to the bottom as well. Is there a way to avoid this or is it a bug?

Unneeded scrolling of ancestors

https://recordit.co/z3vQ93V1YP

Scrolling the parent also scrolls another ancestor higher up the DOM tree.

I understand this is the "standard" behavior even for the browser-implemented scrollIntoView. Is there any way to prevent this? It would be useful if the method did what its name suggest ("ifNeeded").

Cannot read property 'clientHeight' of undefined

2.2.8 is the last version that works for me (tried both Chrome and Safari). 2.2.9 and all later versions fail with:

scroll-into-view.min.js:1 Uncaught TypeError: Cannot read property 'clientHeight' of undefined
    at n (scroll-into-view.min.js:1)
    at r (scroll-into-view.min.js:1)
    at scroll-into-view.min.js:1

Here is the failing invocation (elem is neither undefined nor null):

scrollIntoView(elem, {
        behavior: 'instant',
        scrollMode: 'if-needed',
        block: 'nearest',
        inline: 'nearest',
      });

[BUG] Safari on macOS Monterey 12.3.1

Hey there, thanks for your job!

I would like to report that default function does not work on Safari macOS Monterey 12.3.1. The native function scrollIntoViewIfNeeded does work.

Is there any fix we can do?

Angular production support

When importing your lib to an angular project (I tried it with 6.1.9 with a simple empty project created with ng new) and running ng serve it works fine.

When I run ng serve --prod though, calling scrollIntoView just does nothing. There are no errors on compilation or at runtime, but apparently minification/uglification destroys something essential.

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

Scroll element inside a iframe stop working when update to version 2.2.19

I have a React component render list chidrent inside a iframe (fixed height and scrollable). When i click on a child element i want to scroll it to center viewport. I use scroll-into-view-if-needed and it worked. but after update to version 2.2.19 it stop work without any error message. It work again when downgrade to version 2.2.15

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.