How would I make it so I can mousedown on the body on my page, then drag the page up or down, like you can in a PDF?
Basically I want to be able to drag the whole page up and down, any idea how to do this? I don't want to use jQuery UI for anything.
Okay, here are the stages...
1) You need to have a constant listener on the body of the document that will keep tabs on the current mouse position
2) On mouse down you will need to scroll roughly equal to the mouse movement (you could choose to scroll slightly faster)
Here is an example of doing this in jQuery
var gesturesX = 0;
var gesturesY = 0;
var startPosition = 0;
var velocity = 0;
var isMouseDown = false;
var timer;
function GetVelocity() {
velocity = startPosition - gesturesY;
}
$(document).mousemove( function (e) {
gesturesX = parseInt(e.pageX, 10);
gesturesY = parseInt(e.pageY, 10);
$("#mouse").html(gesturesY);
if (isMouseDown) {
window.scrollBy(0, startPosition - gesturesY);
return false;
}
});
$(document).mousedown( function() {
startPosition = gesturesY;
isMouseDown = true;
timer = window.setTimeout(GetVelocity, 50);
});
$(document).mouseup( function() {
isMouseDown = false;
if (velocity != 0) {
$Body = $("body");
var distance = velocity * 20;
var scrollToPosition = $Body.scrollTop() + distance;
$Body.eq(0).animate({ scrollTop: scrollToPosition}, 1000);
velocity = 0;
}
return false;
});
Quick fix for the scrollbar problem: use $(document.body) instead of $(document).
Still, the animation behave strangely sometimes, especially with repetitive scrolls. (eg. scrolling up and the following animation scrolls down).
Since the OP asked for a PDF viewer-like scrolling (and not an iPhone-like scrolling) that don't involve any kind of animation, I guess we could put Sohnee's code on a diet and write this:
var gesturesY = 0;
var startPosition = 0;
var isMouseDown = false;
$(document.body).mousemove( function (e) {
gesturesY = parseInt(e.pageY, 10);
if (isMouseDown) {
window.scrollBy(0, startPosition - gesturesY);
return false;
}
});
$(document.body).mousedown( function() {
startPosition = gesturesY;
isMouseDown = true;
});
$(document.body).mouseup( function() {
isMouseDown = false;
return false;
});
Variation of Francesco's answer that includes scrolling along the X-axis:
$(function ()
{
var gesturesX = 0
, gesturesY = 0
, startX = 0
, startY = 0
, isMouseDown = false
$(document.body).mousemove(function (e)
{
gesturesX = parseInt(e.pageX, 10)
gesturesY = parseInt(e.pageY, 10)
if (isMouseDown)
{
window.scrollBy(startX - gesturesX, startY - gesturesY)
return false
}
}
)
$(document.body).mousedown(function ()
{
startX = gesturesX
startY = gesturesY
isMouseDown = true
return false
}
)
$(document.body).mouseup(function ()
{
isMouseDown = false
return false
}
)
}
)
Define CSS classes to set cursor like pdf reader, closed hand when dragging to scroll and open hand when not scrolling.
.closehand {
cursor: url(https://mail.google.com/mail/images/2/closedhand.cur), default !important;
}
.openhand {
cursor: hand;
}
Define a div on page where the content to scroll is placed, and attach to event listeners. In the example (Variation of Francesco's answer) I use #draggable to link the div. mousemove will cause drag. mousedown will detect user starting scroll. click will detect user completing drag.
I tried mouseup but that let the page snap back to initial position.
mouseout detects if user moves out of scrollable area while still holding mouse down.
var gesturesY = 0;
var startPosition = 0;
var isMouseDown = false;
$('#draggable').mousemove( function (e) {
gesturesY = parseInt(e.pageY, 10);
if (isMouseDown) {
$(this).removeClass('openhand');
$(this).addClass('closehand');
window.scrollBy(0, startPosition - gesturesY);
return false;
}
});
$('#draggable').mousedown( function() {
startPosition = gesturesY;
isMouseDown = true;
return false;
});
$('#draggable').click( function() {
$(this).removeClass('closehand');
$(this).addClass('openhand');
isMouseDown = false;
return false;
});
$('#draggable').mouseout( function() {
$(this).removeClass('closehand');
$(this).addClass('openhand');
isMouseDown = false;
return false;
});