具有可resize/可拖动元素的响应式jQuery UI
我正在尝试使用jQuery UI构建一个响应式界面,它允许可移动和可resize的元素,即使屏幕resize也会保持成比例。
示例: http : //jsfiddle.net/NSLmQ/3/
在用户完成resize或拖动之后,我正在使用dragStop
和resizeStop
的UI回调将像素位置值转换为百分比值。
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+"%" }); }
如果父容器具有明确的高度和宽度,则此工作完全正常 – 在后续resize或拖动之前,jQuery UI将百分比转换回像素,并且在完成resize或拖动之后 ,我的回调将它们返回到百分比。 所有的笨蛋。
当resizable元素的父元素设置为height:auto时(在链接的小提琴中,我使用子图像为包含父元素提供高度), 在调整大小期间会出现问题
当我尝试调整UI元素的大小时,jQuery UI会不正确地将顶部和左侧的百分比转换为像素,并且元素将跳转到位。
此问题似乎是特定于Chrome的。 Firefox偶尔会出现迷你跳跃,但它们似乎只是略微四舍五入的问题。 在Chrome中,位置转移是戏剧性的。
虽然在父容器上设置显式高度可以解决UI问题,但它不允许响应式解决方案。
有任何想法吗?
===========================================
最新更新
@ peteykun的答案解决了我的根本问题,但有一个分支问题,我认为可能值得解决。
Chrome在计算“自动”大小时使用子像素,因此通过.height()
获取jQuery的高度会返回一个不精确的舍入答案(并在像素和百分比之间转换时导致视觉抖动,反之亦然)。
因此,使用Vanilla JS .getBoundingClientRect().height
而不是.height()
返回无抖动解决方案的子像素结果。
function setContainerSize(el) { var parent = $(el.target).parent().parent(); parent.css('height', parent[0].getBoundingClientRect().height+'px'); }
再次感谢您的帮助,@ peteykun
如何在resize之前显式设置容器的height
?
理想情况下,这应该可以使用.resizable{}
的start
选项,但我自己尝试了,它没有帮助。 相反,通过将.mouseover()
绑定到句柄,似乎可以实现所需的效果:
$('.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/
更新: 为了保持响应性,您可以在resize完成后再次使高度 请查看以下更新。 auto
。
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:为了解决在第二次resize之前鼠标永远不会离开句柄的情况,让我们在mouseout上重置高度:
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/
只是想添加,小提琴和问题中的代码几乎完美适合我,你必须确保在重置宽度/高度时考虑任何填充。
el.css({ ... width: (el.width()+LEFT_PADDING+RIGHT_PADDING)/parent.width()*100+"%", height: (el.height()+TOP_PADDING+BOTTOM_PADDING)/parent.height()*100+"%" });