Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No auto-scroll on drag #553

Closed
firatsarlar opened this issue Oct 11, 2016 · 26 comments
Closed

No auto-scroll on drag #553

firatsarlar opened this issue Oct 11, 2016 · 26 comments
Labels

Comments

@firatsarlar
Copy link

To reproduce :
Please open example page on safari or firefox ( maybe IE ) : https://gaearon.github.io/react-dnd/examples-sortable-simple.html
And resize browser keep some of elements of list outside screen, then try to drag, page should scroll during drag but not. ( In chrome works correctly )
This issue is open in Firefox.
You may want to check releated stack overflow question.
http://stackoverflow.com/questions/16822920/scroll-while-using-html5-drag-and-drop

As a solution :
Please checkout https://github.com/martindrapeau/jQueryDndPageScroll/blob/master/jquery.dnd_page_scroll.js

Also working example
https://jsfiddle.net/0vv7fs63/2/

I'm not suggesting to use jquery plugin but checking source code.
Simply adding two divs ( top and bottom of the page ) and listening drag over/enter events, and scrolling accordingly is the solution.

@nossila
Copy link

nossila commented May 15, 2017

there's this solution to react-dnd: https://github.com/azuqua/react-dnd-scrollzone
maybe this issue could be closed now @darthtrevino

@vaibhavarora14
Copy link

Please Sortable developers, provide some solution to this.

@AsceticBoy
Copy link

how to use it can you look for me ? @nossila

@nossila
Copy link

nossila commented Dec 13, 2017

@AsceticBoy I can't do a better job than it's README, tons of examples there

@Tsourdox
Copy link

I did my own implementation of this. Basically added the listcontainer as a Drop Target.

Used: findDOMNode(component).getBoundingClientRect()
to know when I was at either side of the listcontainer

then: listContainerDOMNode.scrollLeft += someValue
to scroll the list, which scrolls the listcontainer.

It's a good start but the problem is that if the user holds the pointer still no hover event is triggered and so the scrolling stops.

Has anyone solved this, scrolling the listcontainer when the pointer is still?

@yankopetrov
Copy link

@nossila ty! react-dnd-scrollzone works as charm :)

@tysonnero
Copy link

tysonnero commented May 10, 2018

I know this is an old thread but still open...

Has anyone successfully setup react-dnd-scrollzone with WindowScroller from react-virtualized in tandem. And if so, could you share the implementation.

I'm using a combination of WindowScroller, AutoSizer and List; and have not been able to get scrollzone working properly.

@tysonnero
Copy link

I realized that my problem is that I'm using a custom scrollElement with WindowScroller, where react-dnd-scrollzone sets it container as the element it wraps. I'm forking it to add a custom scroll element prop.

@evelant
Copy link

evelant commented Jun 21, 2018

Looks like react-dnd-scrollzone no longer works with the latest react-dnd. IMO drag scrolling should be part of the react-dnd core.

@Justin-ZS
Copy link

Justin-ZS commented Jul 30, 2018

Below is my solution:

const autoScrollInSafari = (step = 4) => (fn) => {
  const inSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

  if (inSafari) {
    return function (p, m, c) {
      const scrollDOM = document.querySelector('.your-scroll-dom-class');
      if (scrollDOM) {
        const cursor = m.getClientOffset();
        const rect = scrollDOM.getBoundingClientRect();
        if (cursor.y - rect.top < 50) scrollDOM.scrollTop -= step;
        if (rect.bottom - cursor.y < 50) scrollDOM.scrollTop += step;
        if (cursor.x - rect.left < 50) scrollDOM.scrollLeft -= step;
        if (rect.right - cursor.x < 50) scrollDOM.scrollLeft += step;
      }
      fn.apply(this, [p, m, c]);
    };
  }

  return fn;
};

const myDropSpec = {
  drop() {
    // your drop callback
  },
  hover: autoScrollInSafari((props, monitor, component) => {
    // your hover callback
  }),
}

Hope this help. 😄

@Soundvessel
Copy link

An updated fork of scrollzone (https://github.com/frontend-collective/frontend-collective-react-dnd-scrollzone) works with more modern versions of react-dnd up to and including 7.0.2. Beyond that version, react-dnd moved the DragDropContext producing this error.

./node_modules/frontend-collective-react-dnd-scrollzone/lib/index.js
Module not found: Can't resolve 'react-dnd/lib/DragDropContext' in 'X:\WSProjects\sonnys-queue\node_modules\frontend-collective-react-dnd-scrollzone\lib'

@darthtrevino
Copy link
Member

@Soundvessel That was due to the CommonJS/ESModule feature, which probably should have been a major version cut (my bad!). You can find it at react-dnd/lib/cjs/DragDropContext or you can import it from the top-level of react-dnd

@stale
Copy link

stale bot commented Jul 6, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@andrefox333
Copy link

Did anyone find a solution to work with the latest version of react-dnd?

@orlandovallejos
Copy link

An updated fork of scrollzone (https://github.com/frontend-collective/frontend-collective-react-dnd-scrollzone) works with more modern versions of react-dnd up to and including 7.0.2. Beyond that version, react-dnd moved the DragDropContext producing this error.

./node_modules/frontend-collective-react-dnd-scrollzone/lib/index.js
Module not found: Can't resolve 'react-dnd/lib/DragDropContext' in 'X:\WSProjects\sonnys-queue\node_modules\frontend-collective-react-dnd-scrollzone\lib'

@Soundvessel Did you apply the fix @darthtrevino suggested?

@orlandovallejos
Copy link

Since I couldn't find a solution out of the box, and some solutions don't work with the latest react-dnd version, I came up with a solution myself: https://gist.github.com/orlandovallejos/ed9c79dd67e96c25cfcc8f1008df9489

I hope it helps someone else.

@MartinN3
Copy link

@orlandovallejos
Hello, could it be implemented on this Sort stress test example? https://react-dnd.github.io/react-dnd/examples/sortable/stress-test

I tried i little but no success.

@orlandovallejos
Copy link

@MartinN3 Here you have my friend: https://codesandbox.io/s/react-dnd-example-12-s3nnf

https://imgur.com/a/heuPO48

You have to update it for your requirements, offset, div containers (probably more than 1), scrolling speed (using the PX_DIFF variable), etc.

Remember the scrolling feature works out of the box in Chrome.

@alqamabinsadiq
Copy link

Since I couldn't find a solution out of the box, and some solutions don't work with the latest react-dnd version, I came up with a solution myself: https://gist.github.com/orlandovallejos/ed9c79dd67e96c25cfcc8f1008df9489

I hope it helps someone else.

This is the best solution. Thank you so much for the solution :)

@its-me-ilia
Copy link

@MartinN3 Here you have my friend: https://codesandbox.io/s/react-dnd-example-12-s3nnf

https://imgur.com/a/heuPO48

You have to update it for your requirements, offset, div containers (probably more than 1), scrolling speed (using the PX_DIFF variable), etc.

Remember the scrolling feature works out of the box in Chrome.

not working in chrome desktop

@Chetan11-dev
Copy link

I put effort into it full day at the end I am happy to tell that through god's grace I am able to implement this feature reliably.
See the truth for yourself at https://codesandbox.io/s/react-dnd-example-12-forked-241x9?file=/src/helper.js:0-1242

AwesomeScreensho.1.mp4

@darthtrevino
Copy link
Member

That's badass @Chetan11-dev - may I use that in an example in the repo?

@Chetan11-dev
Copy link

Chetan11-dev commented Aug 21, 2021

Feel Free, I will be more than happy if you use it. Also it would be great if you could create a package for it on npm that integrates with react-dnd as you deem fit. (Just don't attribute the plugin to me. I do not like attribution.)

@windmaomao
Copy link

windmaomao commented Oct 18, 2021

Thanks @Chetan11-dev for the solution, i noticed lastMouseClientY isn't used, so i simplified it by using the dropover event only. This example is not using react-dnd either, however just making the point it can work with this approach.

https://codepen.io/windmaomao/pen/GRvZQdv

  const ref = useRef()
  useEffect(() => {
    let evt = e => { 
      const parent = ref.current
      const rect = parent.getBoundingClientRect()
      const top = e.clientY - rect.top
      console.log(parent.scrollTop)
      if (top < 50 && top > 0) {
        parent.scrollTo(0, parent.scrollTop - 1)
      }
      const bottom = rect.bottom - e.clientY
      if (bottom < 50 && bottom > 0) {
        parent.scrollTo(0, parent.scrollTop + 1)
      }
    }
    window.addEventListener('dragover', evt)
    
    return () => {
      window.removeEventListerner('dragover', evt)
    }
  }, [])

@raineorshine
Copy link
Contributor

Here is a solution for mobile, where dragover doesn't work:

https://stackoverflow.com/a/73197415/480608

@DanielSadovskiy
Copy link

solution is here. Works with react 18

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests