我有下面的样本html,有一个DIV有100%的宽度。它包含了一些元素。在执行窗口调整大小时,内部元素可能会被重新定位,div的尺寸可能会改变。我在问是否有可能挂钩div的维度变化事件?以及如何做到这一点?我目前绑定回调函数到目标DIV上的jQuery调整大小事件,但是,没有输出控制台日志,如下所示:
<html>
<head>
<script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript" language="javascript">
$('#test_div').bind('resize', function(){
console.log('resized');
});
</script>
</head>
<body>
<div id="test_div" style="width: 100%; min-height: 30px; border: 1px dashed pink;">
<input type="button" value="button 1" />
<input type="button" value="button 2" />
<input type="button" value="button 3" />
</div>
</body>
</html>
一个更新的标准是Resize Observer api,有很好的浏览器支持。
函数输出大小() {
宽度.值 = 文本框偏移宽度
高度.值 = 文本框偏移高度
}
输出大小()
new ResizeObserver (outputsize).observe(textbox)
宽度:<输出 id=“宽度”>0</output><br>
高度:<输出 id=“高度”>0</output><br>
<textarea id=“textbox”>调整我</textarea><br>的大小
调整观察者
文档:https://developer.mozilla.org/en-US/docs/Web/API/Resize_Observer_API
规范:https://wicg.github.io/ResizeObserver
当前支持:http://caniuse.com/#feat=resizeobserver
填充物:https://github.com/pelotoncycle/resize-observer
https://github.com/que-etc/resize-observer-polyfill
https://github.com/juggle/resize-observer
这几乎是顶部答案的精确副本,但不是链接,它只是重要的代码的一部分,翻译成IMO更易读,更容易理解。其他一些小的改变包括使用cloneNode(),和不把html放入js字符串。很小的东西,但是你可以复制粘贴它就可以了。
它的工作方式是让两个看不见的div填充你正在观看的元素,然后在每个div中设置一个触发器,并设置一个滚动位置,如果大小发生变化,将导致触发滚动变化。
所有真正的荣誉都属于Marc J,但如果你只是在寻找相关的代码,这里是:
window.El = {}
El.resizeSensorNode = undefined;
El.initResizeNode = function() {
var fillParent = "display: block; position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;";
var triggerStyle = "position: absolute; left: 0; top: 0; transition: 0s;";
var resizeSensor = El.resizeSensorNode = document.createElement("resizeSensor");
resizeSensor.style = fillParent;
var expandSensor = document.createElement("div");
expandSensor.style = fillParent;
resizeSensor.appendChild(expandSensor);
var trigger = document.createElement("div");
trigger.style = triggerStyle;
expandSensor.appendChild(trigger);
var shrinkSensor = expandSensor.cloneNode(true);
shrinkSensor.firstChild.style = triggerStyle + " width: 200%; height: 200%";
resizeSensor.appendChild(shrinkSensor);
}
El.onSizeChange = function(domNode, fn) {
if (!domNode) return;
if (domNode.resizeListeners) {
domNode.resizeListeners.push(fn);
return;
}
domNode.resizeListeners = [];
domNode.resizeListeners.push(fn);
if(El.resizeSensorNode == undefined)
El.initResizeNode();
domNode.resizeSensor = El.resizeSensorNode.cloneNode(true);
domNode.appendChild(domNode.resizeSensor);
var expand = domNode.resizeSensor.firstChild;
var expandTrigger = expand.firstChild;
var shrink = domNode.resizeSensor.childNodes[1];
var reset = function() {
expandTrigger.style.width = '100000px';
expandTrigger.style.height = '100000px';
expand.scrollLeft = 100000;
expand.scrollTop = 100000;
shrink.scrollLeft = 100000;
shrink.scrollTop = 100000;
};
reset();
var hasChanged, frameRequest, newWidth, newHeight;
var lastWidth = domNode.offsetWidth;
var lastHeight = domNode.offsetHeight;
var onResized = function() {
frameRequest = undefined;
if (!hasChanged) return;
lastWidth = newWidth;
lastHeight = newHeight;
var listeners = domNode.resizeListeners;
for(var i = 0; listeners && i < listeners.length; i++)
listeners[i]();
};
var onScroll = function() {
newWidth = domNode.offsetWidth;
newHeight = domNode.offsetHeight;
hasChanged = newWidth != lastWidth || newHeight != lastHeight;
if (hasChanged && !frameRequest) {
frameRequest = requestAnimationFrame(onResized);
}
reset();
};
expand.addEventListener("scroll", onScroll);
shrink.addEventListener("scroll", onScroll);
}
有一种非常有效的方法来确定元素的大小是否已经改变。
http://marcj.github.io/css-element-queries/
这个库有一个resizessensor类,可以用于调整大小检测。它使用基于事件的方法,所以它非常快,而且不会浪费CPU时间。
例子:
new ResizeSensor(jQuery('#divId'), function(){
console.log('content dimension changed');
});
请不要使用jQuery onresize插件,因为它使用setTimeout()结合在循环中读取DOM clienttheight /clientWidth属性来检查更改。这是令人难以置信的缓慢和不准确,因为它会导致布局抖动。
披露:我与这个库直接相关。
当MarcJ的解决方案不起作用时,我发现这个库可以工作:
https://github.com/sdecima/javascript-detect-element-resize
它是非常轻量级的,甚至可以通过CSS或简单的HTML加载/渲染来检测自然的大小调整。
代码示例(摘自链接):
<script type="text/javascript" src="detect-element-resize.js"></script>
<script type="text/javascript">
var resizeElement = document.getElementById('resizeElement'),
resizeCallback = function() {
/* do something */
};
addResizeListener(resizeElement, resizeCallback);
removeResizeListener(resizeElement, resizeCallback);
</script>