jQuery UI Resizable滚动容器自动滚动问题:元素未正确缩放
问题原因
你的代码没实现预期效果,核心是两个错误:
- 坐标计算不对:
event.pageY是相对于整个文档的坐标,没考虑滚动容器的滚动位置和自身偏移,导致判断“是否靠近容器底部”的逻辑完全不准。 - 尺寸补偿逻辑错了:直接给
ui.size.height加delta不匹配jQuery UI Resizable的内部计算逻辑——滚动后元素和鼠标的相对位置变了,内部的尺寸计算基准已经偏移,只改当前size会导致后续计算混乱。
修正后的代码
<!DOCTYPE html> <html lang='en'> <head> <title>Test</title> <meta charset='utf-8'> <link rel="stylesheet" href="https://code.jquery.com/ui/1.14.1/themes/base/jquery-ui.css"> <style> #outer { height: 30em; width: 20em; border: 1px solid red; overflow: auto; } #middle { height: 60em; width: 15em; border: 1px solid green; } #inner { height: 10em; width: 10em; border: 1px solid blue; outline: 10px solid lightblue; outline-offset: -11px; } .helper { border: 1px dotted black; } </style> <script src="https://code.jquery.com/jquery-3.7.1.js"></script> <script src="https://code.jquery.com/ui/1.14.1/jquery-ui.js"></script> <script> $( function() { let resize = function (event, ui) { const outer = $('#outer'); const outerOffset = outer.offset().top; // 计算鼠标在滚动容器内的真实位置(考虑滚动距离) const mouseInOuter = event.clientY - outerOffset + outer.scrollTop(); const outerInnerHeight = outer.innerHeight(); const scrollTrigger = 30; // 触发滚动的阈值 // 当鼠标靠近容器底部时自动滚动 if (mouseInOuter > outerInnerHeight - scrollTrigger) { // 计算需要滚动的距离:鼠标超出阈值的部分 const scrollDelta = mouseInOuter - (outerInnerHeight - scrollTrigger); outer[0].scrollBy({top: scrollDelta, left:0, behavior: 'instant'}); // 同步调整Resizable的尺寸基准,避免计算偏差 ui.size.height += scrollDelta; ui.originalSize.height += scrollDelta; } }; $( "#inner" ).resizable({ helper: "helper", resize: resize }); } ); </script> </head> <body> <div id="outer"> <div id="middle"> <div id="inner"> </div> </div> </div> </body> </html>
改动说明
- 精准判断滚动时机:用
event.clientY(视口内的鼠标坐标)减去容器的页面偏移,再加上容器的滚动距离,得到鼠标在容器内部的真实位置,确保触发滚动的时机准确。 - 同步尺寸基准:滚动后不仅改当前的
ui.size.height,还更新ui.originalSize.height——jQuery UI Resizable是基于初始尺寸的偏移来计算当前尺寸的,同步基准后后续的缩放才会符合预期。 - 滚动距离匹配鼠标移动:直接用鼠标超出阈值的距离作为滚动量,让滚动速度和鼠标拖动的速度匹配,避免滚动过快或过慢。
内容的提问来源于stack exchange,提问作者Greenflash
相关产品推荐
相关产品推荐

