Wil*_*hoi 314 html javascript jquery
我有以下示例html,有一个100%宽度的DIV.它包含一些元素.在执行窗口重新调整大小时,可以重新定位内部元素,并且div的尺寸可以改变.我问是否可以挂钩div的尺寸变化事件?以及如何做到这一点?我目前将回调函数绑定到目标DIV上的jQuery resize事件,但是,没有输出控制台日志,请参见下文:

<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>
Run Code Online (Sandbox Code Playgroud)
Mar*_*idt 251
有一种非常有效的方法可以确定元素的大小是否已更改.
http://marcj.github.io/css-element-queries/
该库有一个ResizeSensor可用于调整大小检测的类.
它使用基于事件的方法,因此速度快,不会浪费CPU时间.
例:
new ResizeSensor(jQuery('#divId'), function(){
console.log('content dimension changed');
});
Run Code Online (Sandbox Code Playgroud)
请不要使用jQuery onresize插件,因为它使用setTimeout()循环来检查更改.
这是令人难以置信的缓慢而不准确.
披露:我直接与此库相关联.
Dan*_*err 191
一个新标准是Resize Observer api,可在Chrome 64中使用.
function outputsize() {
width.value = textbox.offsetWidth
height.value = textbox.offsetHeight
}
outputsize()
new ResizeObserver(outputsize).observe(textbox)Run Code Online (Sandbox Code Playgroud)
Width: <output id="width">0</output><br>
Height: <output id="height">0</output><br>
<textarea id="textbox">Resize me</textarea><br>Run Code Online (Sandbox Code Playgroud)
规范:https://wicg.github.io/ResizeObserver
Polyfills:https://github.com/WICG/ResizeObserver/issues/3
Firefox问题:https://bugzil.la/1272409
Safari问题:http://wkb.ug/157743
当前支持:http://caniuse.com/#feat=resizeobserver
Ale*_*olo 32
您必须resize在window对象上绑定事件,而不是在通用html元素上绑定事件.
然后你可以使用这个:
$(window).resize(function() {
...
});
Run Code Online (Sandbox Code Playgroud)
在回调函数中,您可以检查div调用的新宽度
$('.a-selector').width();
Run Code Online (Sandbox Code Playgroud)
所以,你的问题的答案是否定的,你不能将resize事件绑定到div.
nkr*_*ron 27
从长远来看,您将能够使用ResizeObserver.
new ResizeObserver(callback).observe(element);
Run Code Online (Sandbox Code Playgroud)
不幸的是,许多浏览器目前默认不支持它.
同时,您可以使用如下功能.因为,大多数元素大小的更改将来自窗口大小调整或来自DOM中的更改.您可以使用窗口的resize事件监听窗口大小调整,并且可以使用MutationObserver监听DOM更改.
下面是一个函数示例,当提供的元素的大小因这些事件中的任何一个而发生变化时,它将回调您:
var onResize = function(element, callback) {
if (!onResize.watchedElementData) {
// First time we are called, create a list of watched elements
// and hook up the event listeners.
onResize.watchedElementData = [];
var checkForChanges = function() {
onResize.watchedElementData.forEach(function(data) {
if (data.element.offsetWidth !== data.offsetWidth ||
data.element.offsetHeight !== data.offsetHeight) {
data.offsetWidth = data.element.offsetWidth;
data.offsetHeight = data.element.offsetHeight;
data.callback();
}
});
};
// Listen to the window's size changes
window.addEventListener('resize', checkForChanges);
// Listen to changes on the elements in the page that affect layout
var observer = new MutationObserver(checkForChanges);
observer.observe(document.body, {
attributes: true,
childList: true,
characterData: true,
subtree: true
});
}
// Save the element we are watching
onResize.watchedElementData.push({
element: element,
offsetWidth: element.offsetWidth,
offsetHeight: element.offsetHeight,
callback: callback
});
};
Run Code Online (Sandbox Code Playgroud)
Mar*_*tke 20
ResizeSensor.js是一个巨大的库的一部分,但我将其功能减少到了这个:
function ResizeSensor(element, callback)
{
let zIndex = parseInt(getComputedStyle(element));
if(isNaN(zIndex)) { zIndex = 0; };
zIndex--;
let expand = document.createElement('div');
expand.style.position = "absolute";
expand.style.left = "0px";
expand.style.top = "0px";
expand.style.right = "0px";
expand.style.bottom = "0px";
expand.style.overflow = "hidden";
expand.style.zIndex = zIndex;
expand.style.visibility = "hidden";
let expandChild = document.createElement('div');
expandChild.style.position = "absolute";
expandChild.style.left = "0px";
expandChild.style.top = "0px";
expandChild.style.width = "10000000px";
expandChild.style.height = "10000000px";
expand.appendChild(expandChild);
let shrink = document.createElement('div');
shrink.style.position = "absolute";
shrink.style.left = "0px";
shrink.style.top = "0px";
shrink.style.right = "0px";
shrink.style.bottom = "0px";
shrink.style.overflow = "hidden";
shrink.style.zIndex = zIndex;
shrink.style.visibility = "hidden";
let shrinkChild = document.createElement('div');
shrinkChild.style.position = "absolute";
shrinkChild.style.left = "0px";
shrinkChild.style.top = "0px";
shrinkChild.style.width = "200%";
shrinkChild.style.height = "200%";
shrink.appendChild(shrinkChild);
element.appendChild(expand);
element.appendChild(shrink);
function setScroll()
{
expand.scrollLeft = 10000000;
expand.scrollTop = 10000000;
shrink.scrollLeft = 10000000;
shrink.scrollTop = 10000000;
};
setScroll();
let size = element.getBoundingClientRect();
let currentWidth = size.width;
let currentHeight = size.height;
let onScroll = function()
{
let size = element.getBoundingClientRect();
let newWidth = size.width;
let newHeight = size.height;
if(newWidth != currentWidth || newHeight != currentHeight)
{
currentWidth = newWidth;
currentHeight = newHeight;
callback();
}
setScroll();
};
expand.addEventListener('scroll', onScroll);
shrink.addEventListener('scroll', onScroll);
};
Run Code Online (Sandbox Code Playgroud)
如何使用它:
let container = document.querySelector(".container");
new ResizeSensor(container, function()
{
console.log("dimension changed:", container.clientWidth, container.clientHeight);
});
Run Code Online (Sandbox Code Playgroud)
Jer*_*yal 17
我不建议setTimeout()破解,因为它会降低性能!相反,您可以使用 DOM突变观察器来收听Div大小更改.
JS:
var observer = new MutationObserver(function(mutations) {
console.log('size changed!');
});
var target = document.querySelector('.mydiv');
observer.observe(target, {
attributes: true
});
Run Code Online (Sandbox Code Playgroud)
HTML:
<div class='mydiv'>
</div>
Run Code Online (Sandbox Code Playgroud)
这是小提琴
尝试改变div大小.
您可以在方法中进一步包装debounce方法以提高效率.debounce将每x毫秒触发您的方法,而不是每隔毫秒触发DIV的大小调整.
jos*_*ley 15
当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>
Run Code Online (Sandbox Code Playgroud)
Sta*_*tan 14
最好的解决方案是使用所谓的Element Queries.但是,它们不是标准的,没有规范存在 - 唯一的选择是使用其中一个可用的polyfill /库,如果你想这样做的话.
元素查询背后的想法是允许页面上的某个容器响应提供给它的空间.这将允许一次编写一个组件,然后将其放在页面的任何位置,同时将其内容调整为当前大小.无论窗口大小是多少.这是我们在元素查询和媒体查询之间看到的第一个区别.每个人都希望在某个时候创建一个规范来标准化元素查询(或实现相同目标的东西),并使它们本机,干净,简单和健壮.大多数人都认为媒体查询非常有限,对模块化设计和真正的响应性没有帮助.
有一些polyfill /库以不同的方式解决问题(可称为变通方法,而不是解决方案):
我已经看到了提出类似问题的其他解决方案.通常他们使用计时器或窗口/视口大小,这不是一个真正的解决方案.此外,我认为理想情况下这应该主要在CSS中解决,而不是在javascript或html中.
Bha*_*til 13
看看这个http://benalman.com/code/projects/jquery-resize/examples/resize/
它有各种例子.尝试调整窗口大小,看看容器元素中的元素是如何调整的.
用js来解释如何使其工作的示例.
看看这个小提琴http://jsfiddle.net/sgsqJ/4/
因为resize()事件绑定到具有类"test"的元素以及窗口对象和窗口对象$('.test')的resize回调中.调用resize().
例如
$('#test_div').bind('resize', function(){
console.log('resized');
});
$(window).resize(function(){
$('#test_div').resize();
});
Run Code Online (Sandbox Code Playgroud)
您可以使用iframe或object使用contentWindow或contentDocument调整大小.没有setInterval或setTimeout
relativeIFRAME.contentWindow- onresize活动<div style="height:50px;background-color:red;position:relative;border:1px solid red">
<iframe style=width:100%;height:100%;position:absolute;border:none;background-color:transparent allowtransparency=true>
</iframe>
This is my div
</div>
Run Code Online (Sandbox Code Playgroud)
Javascript:
$('div').width(100).height(100);
$('div').animate({width:200},2000);
$('object').attr({
type : 'text/html'
})
$('object').on('resize,onresize,load,onload',function(){
console.log('ooooooooonload')
})
$($('iframe')[0].contentWindow).on('resize',function(){
console.log('div changed')
})
Run Code Online (Sandbox Code Playgroud)
JsFiddle:https://jsfiddle.net/qq8p470d/
var div = document.getElementById('div');
div.addEventListener('resize', (event) => console.log(event.detail));
function checkResize (mutations) {
var el = mutations[0].target;
var w = el.clientWidth;
var h = el.clientHeight;
var isChange = mutations
.map((m) => m.oldValue + '')
.some((prev) => prev.indexOf('width: ' + w + 'px') == -1 || prev.indexOf('height: ' + h + 'px') == -1);
if (!isChange)
return;
var event = new CustomEvent('resize', {detail: {width: w, height: h}});
el.dispatchEvent(event);
}
var observer = new MutationObserver(checkResize);
observer.observe(div, {attributes: true, attributeOldValue: true, attributeFilter: ['style']});Run Code Online (Sandbox Code Playgroud)
#div {width: 100px; border: 1px solid #bbb; resize: both; overflow: hidden;}Run Code Online (Sandbox Code Playgroud)
<div id = "div">DIV</div>Run Code Online (Sandbox Code Playgroud)
小智 7
令人惊讶的是,尽管这个问题已经存在,但在大多数浏览器中这仍然是一个问题。
正如其他人所说,Chrome 64+ 现在原生附带 Resize Observes,但是,规范仍在微调中,Chrome 目前(截至 2019-01-29)落后于最新版本的规范。
我在野外看到了几个很好的 ResizeObserver polyfill,但是,有些没有严格遵循规范,有些则有一些计算问题。
我迫切需要这种行为来创建一些可以在任何应用程序中使用的响应式 Web 组件。为了让它们很好地工作,它们需要始终知道它们的尺寸,所以 ResizeObservers 听起来很理想,我决定创建一个尽可能符合规范的 polyfill。
回购:https : //github.com/juggle/resize-observer
演示:https : //codesandbox.io/s/myqzvpmmy9
使用 Clay.js ( https://github.com/zzarcon/clay ) 检测元素大小的变化非常简单:
var el = new Clay('.element');
el.on('resize', function(size) {
console.log(size.height, size.width);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
318898 次 |
| 最近记录: |