
In one of my project, I am trying to jQuery UI sortable work with zoom CSS property on body. But it’s not allowing me to drag and drop correctly on the right position.
Drag only working with half area, if user try to drag and drop from empty area on right side (Black area in my case) it’s not working
Red area where drop not working
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
$(function () { var zoomScale = $("body").css("zoom"); console.log(typeof zoomScale, zoomScale.toString()); var canvasHeight = $("#sortable").height(); var canvasWidth = $("#sortable").width(); $("#sortable").sortable({ sort: function (e, ui) { var changeLeft = ui.position.left - ui.originalPosition.left; var changeTop = ui.position.top - ui.originalPosition.top; var sortIndex = $("#sortable .ui-sortable-placeholder").index() + 30; var newLeft = ui.originalPosition.left + changeLeft / zoomScale - ui.item.parent().offset().left; var newTop = ui.originalPosition.top + changeTop / zoomScale - ui.item.parent().offset().top + sortIndex; ui.helper.css({ left: newLeft, top: newTop, }); }, }); }); |
Possible Causes
The behavior of jQuery UI sortable is comparing the mouse position with the element offsets. However, It seems that offset values of children elements won’t be affected by zoom if setting zoom on a parent element. (Safari CSS Reference has mentioned it slightly.)
By the way, according to Mozilla document of zoom, CSS zoom is non-standard. It means it has possibility of different behaviors in variable browsers. If it’s possible, try not to use CSS zoom.
Now What solution I have used
With JS : Calculate new let and top points :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$(function () { var zoomScale = $("body").css("zoom"); console.log(typeof zoomScale, zoomScale.toString()); var canvasHeight = $("#sortable").height(); var canvasWidth = $("#sortable").width(); $("#sortable").sortable({ axis: "y", sort: function (e, ui) { var changeLeft = ui.position.left - ui.originalPosition.left; var changeTop = ui.position.top - ui.originalPosition.top; var sortIndex = $("#sortable .ui-sortable-placeholder").index() + 32; var newLeft = ui.originalPosition.left + changeLeft / zoomScale - ui.item.parent().offset().left; var newTop = ui.originalPosition.top + changeTop / zoomScale - ui.item.parent().offset().top + sortIndex; ui.helper.css({ left: newLeft, top: newTop, }); }, }); }); |
Solution With CSS only : Resetting CSS Zoom and again applying on target selector.
Solution: nested zooming
In your case, it works well to get the width after zooming if zoom set on <td>. So I try to set nested zoom to simulate the view of setting zoom on <body>:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
tbody { zoom: calc(1 / 1.3); } td { zoom: 1.3; padding: 0px; min-width: 100%; border: solid 1px #ddd; } body { zoom: 1.3; } |
If you do above, you don’t have to calculate helper the element by yourself:
1 |
$("#sortable").sortable(); |
[paypal-donation]