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

Add scrolling support vertically and horizontally #449

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 143 additions & 73 deletions dist/dragula.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/dragula.min.js

Large diffs are not rendered by default.

76 changes: 73 additions & 3 deletions dragula.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var crossvent = require('crossvent');
var classes = require('./classes');
var doc = document;
var documentElement = doc.documentElement;
var _autoScrollingInterval; // reference to auto scrolling

function dragula (initialContainers, options) {
var len = arguments.length;
Expand Down Expand Up @@ -218,6 +219,7 @@ function dragula (initialContainers, options) {

function end () {
if (!drake.dragging) {
clearInterval(_autoScrollingInterval);
return;
}
var item = _copy || _item;
Expand Down Expand Up @@ -303,6 +305,7 @@ function dragula (initialContainers, options) {

function cleanup () {
var item = _copy || _item;
clearInterval(_autoScrollingInterval);
ungrab();
removeMirrorImage();
if (item) {
Expand Down Expand Up @@ -355,9 +358,12 @@ function dragula (initialContainers, options) {
}

function drag (e) {
if (!_mirror) {
return;
}
if (!_mirror) { return; }
// For iframe. When dragging an item and mouse moves out of the iframe and
// mouseup, then decides to move back, the event will be 0 so we should
// just call cancel.
if (whichMouseButton(e) === 0) { cancel(); }

e.preventDefault();

var clientX = getCoord('clientX', e);
Expand Down Expand Up @@ -409,6 +415,8 @@ function dragula (initialContainers, options) {
function moved (type) { drake.emit(type, item, _lastDropTarget, _source); }
function over () { if (changed) { moved('over'); } }
function out () { if (_lastDropTarget) { moved('out'); } }

startScroll(_item, e);
}

function spillOver (el) {
Expand Down Expand Up @@ -605,4 +613,66 @@ function getCoord (coord, e) {
return host[coord];
}

function getScrollContainer(node) {
if (node === null) { return null; }
if (node.scrollHeight > node.clientHeight) {
return node;
} else {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else here is redundant, please remove

if (!/(body|html)/i.test(node.parentNode.tagName)) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract regexp to a variable

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why I need a variable for this. Why would you want to hold on to the reference if it's not going to be used unless we're scrolling?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a commit for it, e9e4e5a; but I'm not sure if I'm happy with this path. I'm open to suggestions.

Copy link
Owner

@bevacqua bevacqua Dec 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nguyenj I just meant putting it in a variable like this:

var rbodyhtml = /(body|html)/i
if (!rbodyhtml.test(node.parentNode.tagName)) {
  // ...

I avoid inline regular expressions in conditionals because they dampen readability. There's no need to hoist it to the top of the file, certainly.

return getScrollContainer(node.parentNode);
} else {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else here is redundant, please remove

return null;
}
}
}

function startAutoScrolling(node, amount, direction) {
_autoScrollingInterval = setInterval(function() {
node[direction] += (amount * 0.25);
}, 15);
}

function startScroll(item, event) {
var scrollEdge = 20;
var scrollSpeed = 20;
var scrollContainer = getScrollContainer(item);

clearInterval(_autoScrollingInterval);

// If a container contains the list that is scrollable
if (scrollContainer) {

// Scrolling vertically
if (event.pageY - getOffset(scrollContainer).top < scrollEdge) {
startAutoScrolling(scrollContainer, -scrollSpeed, 'scrollTop');
} else if ((getOffset(scrollContainer).top + scrollContainer.getBoundingClientRect().height) - event.pageY < scrollEdge) {
startAutoScrolling(scrollContainer, scrollSpeed, 'scrollTop');
}

// Scrolling horizontally
if (event.pageX - scrollContainer.getBoundingClientRect().left < scrollEdge) {
startAutoScrolling(scrollContainer, -scrollSpeed, 'scrollLeft');
} else if ((getOffset(scrollContainer).left + scrollContainer.getBoundingClientRect().width) - event.pageX < scrollEdge) {
startAutoScrolling(scrollContainer, scrollSpeed, 'scrollLeft');
}

// If the window contains the list
} else {

// Scrolling vertically
if ((event.pageY - window.scrollY) < scrollEdge) {
startAutoScrolling(document.body, -scrollSpeed, 'scrollTop');
} else if ((window.innerHeight - (event.pageY - window.scrollY)) < scrollEdge) {
startAutoScrolling(document.body, scrollSpeed, 'scrollTop');
}

// Scrolling horizontally
if ((event.pageX - window.scrollX) < scrollEdge) {
startAutoScrolling(document.body, -scrollSpeed, 'scrollLeft');
} else if ((window.innerWidth - (event.pageX - window.scrollX)) < scrollEdge) {
startAutoScrolling(document.body, scrollSpeed, 'scrollLeft');
}
}
}

module.exports = dragula;
22 changes: 22 additions & 0 deletions example/example.css
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,28 @@ button:hover {
#right-lovehandles > div {
cursor: initial;
}
.scrollable {
display: block;
width: 100%;
overflow-y: auto;
height: 12em;
}

.scrollable--horizontal {
display: block;
max-width: 100%;
margin-top: 1.5em;
overflow-y: hidden;
overflow-x: auto;
}
.scrollable--horizontal .scroll {
display: block;
width: 1000px;
}
.scrollable--horizontal .scroll div {
display: inline-block;
width: auto;
}
.handle {
padding: 0 5px;
margin-right: 5px;
Expand Down
2 changes: 2 additions & 0 deletions example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ dragula([$('left-copy-1tomany'), $('right-copy-1tomany')], {
});

dragula([sortable]);
dragula([document.querySelector('.scrollable')]);
dragula([document.querySelector('.scroll')]);

crossvent.add(sortable, 'click', clickHandler);

Expand Down
6 changes: 4 additions & 2 deletions example/example.min.js

Large diffs are not rendered by default.

92 changes: 92 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,98 @@ <h3 class='tagline'><span class='tagline-text'>Drag and drop so simple it hurts<
</code>
</pre>
</div>
<div class='parent'>
<label for='hy'>Need to see more while dragging? Sure we'll scroll for you.</label>
<div class='wrap'>
<div class="container scrollable">
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
<div>Integer luctus magna elementum nibh vestibulum, ut commodo justo vulputate.</div>
<div>Praesent in ex tempor, maximus arcu et, fermentum magna.</div>
<div>Suspendisse a urna et tellus commodo condimentum.</div>
<div>Suspendisse convallis nulla at sapien hendrerit dignissim.</div>
<div>Suspendisse ut ex in sem rutrum volutpat.</div>
<div>Nullam quis mauris et leo pretium tincidunt.</div>
<div>Sed sit amet mauris lobortis, auctor ligula quis, convallis dui.</div>
<div>Nulla id neque nec odio accumsan eleifend.</div>
<div>Donec eget quam in neque sollicitudin molestie.</div>
<div>Nunc ut est sed nisi eleifend commodo.</div>
<div>Nulla sollicitudin odio eu sollicitudin rhoncus.</div>
<div>Quisque ac tortor placerat, tempus turpis sit amet, mollis risus.</div>
<div>Morbi at arcu euismod, facilisis nisl condimentum, ultrices leo.</div>
<div>Vestibulum pulvinar quam id nisl dictum, quis ultricies dui laoreet.</div>
<div>Nunc sed nisl eu nisl accumsan tincidunt non at nibh.</div>
<div>Nullam bibendum leo vitae sollicitudin hendrerit.</div>
<div>Suspendisse imperdiet odio ut diam fermentum iaculis.</div>
<div>Vestibulum elementum sapien a purus facilisis egestas.</div>
<div>Pellentesque ac nulla quis ex congue pellentesque eu eleifend lacus.</div>
<div>Nunc rutrum lectus vitae ipsum facilisis, et tincidunt nisi dapibus.</div>
<div>Phasellus vehicula nisl quis felis rutrum, vel dictum est rutrum.</div>
<div>Nunc in orci vitae nunc hendrerit ultrices.</div>
<div>Sed scelerisque dui vel sapien congue, at vestibulum orci pretium.</div>
<div>Nulla a nisl vel massa rhoncus gravida molestie id leo.</div>
<div>Integer a dui iaculis nisl tincidunt convallis.</div>
<div>In quis purus eu tellus ultricies egestas ut in quam.</div>
<div>Integer fringilla metus nec lorem mattis, vel gravida mauris vulputate.</div>
<div>Nullam scelerisque sapien ac dui euismod vestibulum.</div>
<div>Aliquam ac erat vel dolor gravida viverra.</div>
<div>Sed vitae ex accumsan, venenatis dolor quis, molestie mi.</div>
<div>Duis quis libero sit amet mauris rutrum porta a at augue.</div>
<div>Cras vitae magna nec dui vestibulum pharetra.</div>
<div>In vitae libero ac odio consectetur lobortis.</div>
<div>Fusce congue ante nec pretium consequat.</div>
<div>Aliquam efficitur nulla ac risus scelerisque, id viverra lacus tempus.</div>
<div>Mauris ornare eros at lacus efficitur posuere quis et ligula.</div>
<div>In in ipsum id justo vulputate lobortis vel vitae ipsum.</div>
<div>Proin at ipsum bibendum, finibus mi ac, accumsan felis.</div>
<div>Aenean malesuada massa id tempus mollis.</div>
<div>Mauris pellentesque dolor vitae urna condimentum, sed sodales elit commodo.</div>
<div>Sed sollicitudin elit et tellus tincidunt maximus.</div>
<div>Nunc eleifend neque at lorem dapibus mollis.</div>
<div>Aliquam ullamcorper massa eu aliquam viverra.</div>
<div>Vestibulum vitae quam id enim consectetur facilisis.</div>
<div>Curabitur viverra justo vel eros tempor ornare.</div>
<div>Duis gravida augue sit amet dictum cursus.</div>
<div>Mauris ut massa convallis, hendrerit massa ut, maximus nulla.</div>
<div>Aenean vitae leo sit amet felis faucibus porta ut ut nibh.</div>
<div>Phasellus ac massa sit amet purus vehicula tempus.</div>
<div>Vestibulum pharetra eros id odio pellentesque, ac aliquet risus lobortis.</div>
<div>Maecenas gravida purus non interdum dignissim.</div>
<div>Mauris molestie mi congue nibh viverra convallis.</div>
<div>Vivamus eget sem nec lorem sagittis mattis.</div>
<div>Donec pellentesque turpis et magna pretium hendrerit.</div>
<div>Morbi rhoncus quam quis ligula pellentesque tincidunt.</div>
<div>Curabitur pretium erat sed orci posuere rhoncus.</div>
<div>Donec congue sapien nec convallis maximus.</div>
<div>Vivamus consectetur justo et consequat tempor.</div>
<div>Mauris scelerisque justo vitae ligula pretium, non auctor justo cursus.</div>
<div>Mauris congue nunc porta tortor sagittis dapibus.</div>
<div>Morbi hendrerit mauris vitae imperdiet condimentum.</div>
<div>Nulla volutpat tellus sit amet sem vehicula viverra.</div>
<div>Nullam aliquet dui nec pharetra gravida.</div>
</div>
</div>

<div class="wrap">
<div class="scrollable scrollable--horizontal">
<div class="container scroll">
<div>Morbi rhoncus quam quis ligula pellentesque tincidunt.</div>
<div>Curabitur pretium erat sed orci posuere rhoncus.</div>
<div>Donec congue sapien nec convallis maximus.</div>
<div>Vivamus consectetur justo et consequat tempor.</div>
<div>Mauris scelerisque justo vitae ligula pretium, non auctor justo cursus.</div>
<div>Mauris congue nunc porta tortor sagittis dapibus.</div>
<div>Morbi hendrerit mauris vitae imperdiet condimentum.</div>
<div>Nulla volutpat tellus sit amet sem vehicula viverra.</div>
<div>Nullam aliquet dui nec pharetra gravida.</div>
</div>
</div>
</div>
<pre>
<code>
dragula([document.querySelector('.scrollable')]);
</code>
</pre>
</div>
<div class='parent'>
<label for='hy'>Copying stuff is common too, so we made it easy for you.</label>
<div class='wrapper'>
Expand Down