Reputation: 9121
Im having problems when using the below function to drag a div, for some reason it is lagging when i am dragging the div over content on the page (for example images and blocks of text).
Strange part is that this lag is not happening when dragging from left to right, only top to bottom..
Any ideas how to get rid of the vertical lag in this function?
function enableDragging(ele) {
var dragging = dragging || false,
x, y, Ox, Oy,
current;
enableDragging.z = enableDragging.z || 1;
var grabber = document.getElementById("wrapper");
grabber.onmousedown = function (ev) {
ev = ev || window.event;
var target = ev.target || ev.srcElement;
current = target.parentNode;
dragging = true;
x = ev.clientX + 2;
y = ev.clientY + 2;
Ox = current.offsetLeft;
Oy = current.offsetTop;
current.style.zIndex = ++enableDragging.z;
document.onmousemove = function (ev) {
ev = ev || window.event;
if (dragging == true) {
var Sx = parseFloat(ev.clientX) - x + Ox;
var Sy = parseFloat(ev.clientY) - y + Oy;
current.style.left = Math.min(Math.max(Sx, Math.min(viewport().width - Sx, 0)), viewport().width - current.offsetWidth) + "px";
current.style.top = Math.min(Math.max(Sy, Math.min(viewport().height - Sy, 0)), viewport().height - current.offsetHeight) + "px";
}
}
document.onselectstart = function () {
return false;
};
document.onmouseup = function (ev) {
ev = ev || window.event;
dragging && (dragging = false);
if (ev.preventDefault) {
ev.preventDefault();
}
}
document.body.style.MozUserSelect = "none";
document.body.style.cursor = "default";
return false;
};
}
function viewport() {
var e = window
, a = 'inner';
if ( !( 'innerWidth' in window ) ) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] }
}
Upvotes: 2
Views: 1861
Reputation: 1283
I have put a Fiddle and create a demo here: http://jsfiddle.net/N6A4q/ (note I've made modification to handle var grabber = ele;
to test.
and i do notice a slower behaviour depends on the positioning of css.
Probably the issue might need some optimization like caching the value.
For example:
current.style.top = Math.min(Math.max(Sx, Math.min(viewport().height - Sx, 0)), viewport().height - current.offsetWidth) + "px";
Could be improved with
var viewportHeight = viewport.height();
current.style.top = Math.min(Math.max(Sy, Math.min(viewportHeight - Sy, 0)), viewportHeight - current.offsetHeight) + "px";
Here's some good reading on browser repaint/flow: http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
The link advices that:
For example, it's a bad idea to set and get styles in a quick succession (in a loop), like:
// no-no!
el.style.left = el.offsetLeft + 10 + "px";
Simply because its like reading and write straightforward.
Upvotes: 1