具有可调整大小/可拖动元素的响应式jQuery UI [英] Responsive jQuery UI with resizable / draggable elements
问题描述
我正在尝试使用jQuery UI构建响应界面,该界面允许可移动和可调整大小的元素,即使调整屏幕大小,这些元素也将保持比例.
I am attempting to build a responsive interface using jQuery UI, that allows for movable and resizable elements, which will stay in proportion even if the screen is resized.
示例: http://jsfiddle.net/NSLmQ/3/
在用户完成其大小调整或拖动操作后,我正在使用dragStop
和resizeStop
的UI回调将像素位置值转换为百分比值.
I am using the UI callbacks for dragStop
and resizeStop
to convert the pixel position values into percentage values, after the user has completed their resize or drag.
function resizeStop(event, ui){
convert_to_percentage($(this));
}
function dragStop(event, ui){
convert_to_percentage($(this));
}
function convert_to_percentage(el){
var parent = el.parent();
el.css({
left:parseInt(el.css('left'))/parent.width()*100+"%",
top: parseInt(el.css('top'))/parent.height()*100+"%",
width: el.width()/parent.width()*100+"%",
height: el.height()/parent.height()*100+"%"
});
}
如果父容器具有明确的高度和宽度,则此方法非常好-jQuery UI在后续调整大小或拖动之前将百分比转换回像素,而我的回调在完成调整大小后将其返回至百分比或拖动.都是笨蛋.
This works perfectly fine if the parent container has an explicit height and width — jQuery UI converts the percentages back to pixels before subsequent resize or drags, and my callbacks return them to percentage after the finished resize or drag. All hunky-dory.
当可调整大小元素的父级设置为height:auto时,会在调整大小期间发生问题(在链接的小提琴中,我正在使用子图像为包含父级的父级设置高度)
The problem occurs during resize when the resizable element's parent is set to height:auto (in the linked Fiddle, I am using a child image to give the containing parent a height)
当我尝试调整UI元素的大小时,jQuery UI会不正确地将顶部和左侧的百分比转换为像素,并且该元素会跳到适当位置.
When I attempt to resize the UI element, jQuery UI will improperly convert the percentage of the top and left into pixels, and the element will jump in position.
此问题似乎是特定于Chrome的. Firefox在位置上偶尔会出现迷你跳跃,但似乎只是四舍五入的问题.在Chrome中,位置变化非常明显.
This problem seems to be Chrome-specific. Firefox exhibits occasional mini-jumps in position, but they seem to be a matter of slight rounding differences. In Chrome, the position shifting is dramatic.
在父容器上设置显式高度可以解决UI问题,但它不允许响应式解决方案.
While setting an explicit height on the parent container solves the UI problem, it doesn't allow for a responsive solution.
有什么想法吗?
=========================================
===========================================
@peteykun在下面的回答解决了我的基本问题,但是有一个分支问题,我认为可能值得解决.
@peteykun's answer below solved my fundamental problem, but there was one offshoot problem that I thought it might be worth addressing.
Chrome在计算自动"大小时会使用子像素,因此通过.height()
使用jQuery获取高度会返回不精确的舍入答案(并且在像素和百分比之间的转换过程中会引起视觉上的抖动,反之亦然) ).
Chrome uses sub-pixels when calculating 'auto' sizing, so that getting the height with jQuery through .height()
returns an inexact, rounded answer (and causes a visual jiggle during the conversion between pixels and percentage, and vice-versa).
因此,使用Vanilla JS .getBoundingClientRect().height
代替.height()
会返回无抖动解决方案的亚像素结果.
Therefore, using the Vanilla JS .getBoundingClientRect().height
instead of .height()
returns a sub-pixel result for a jiggleless solution.
function setContainerSize(el) {
var parent = $(el.target).parent().parent();
parent.css('height', parent[0].getBoundingClientRect().height+'px');
}
再次感谢您的帮助,@ peteykun
Thanks again for your help, @peteykun
推荐答案
如何在调整大小之前显式设置容器的height
?
How about setting the container's height
explicitly before the resize takes place?
理想情况下,使用.resizable{}
的start
选项应该可以完成此操作,但是我自己尝试了一下,但没有帮助.相反,通过将.mouseover()
绑定到句柄,似乎可以达到预期的效果:
Ideally, this should have been doable with the start
option for .resizable{}
, but I tried it out myself, and it did not help. Instead, by binding a .mouseover()
to the handle, the desired effect seems to be achieved:
$('.box')
.resizable({containment: 'parent', handles: "se", create: setContainerResizer, stop:resizeStop})
function setContainerResizer(event, ui) {
console.log($(this)[0]);
$($(this)[0]).children('.ui-resizable-handle').mouseover(setContainerSize);
}
function setContainerSize(el) {
var parent = $(el.target).parent().parent();
parent.css('height', parent.height() + "px");
}
JSFiddle:: http://jsfiddle.net/w2Jje/4/
更新: 为了保持响应速度,您可以在调整大小后再次将高度设置为检查以下更新.auto
.
Update: In order to retain responsiveness, you can make the height Check the update below.auto
once again after the resize is complete.
function convert_to_percentage(el){
var parent = el.parent();
el.css({
left:parseInt(el.css('left'))/parent.width()*100+"%",
top: parseInt(el.css('top'))/parent.height()*100+"%",
width: el.width()/parent.width()*100+"%",
height: el.height()/parent.height()*100+"%"
});
parent.css('height', 'auto'); // Set it back to auto
}
JSFiddle:: http://jsfiddle.net/w2Jje/5/
更新#2:要解决鼠标在第二次调整大小之前从不离开手柄的情况,请改为在鼠标移开时重置其高度:
Update #2: To get around the case where the mouse never leaves the handle before a second resize, let's reset the height on mouseout instead:
function setContainerResizer(event, ui) {
console.log($(this)[0]);
$($(this)[0]).children('.ui-resizable-handle').mouseover(setContainerSize);
$($(this)[0]).children('.ui-resizable-handle').mouseout(resetContainerSize);
}
function resetContainerSize(el) {
parent.css('height', 'auto');
}
JSFiddle:: http://jsfiddle.net/w2Jje/6/
这篇关于具有可调整大小/可拖动元素的响应式jQuery UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!