我有下面的样本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>

当前回答

这是一个非常老的问题,但我想我会把我的解决方案贴出来。

我尝试使用resizsensor,因为每个人似乎都对它有很大的好感。在实现之后,我意识到在底层,元素查询要求所讨论的元素具有相对位置或绝对位置,这不适用于我的情况。

我最终用Rxjs间隔来处理这个问题,而不是像以前的实现那样直接使用setTimeout或requestAnimationFrame。

间隔的可观察对象的好处在于,你可以修改流,但任何其他可观察对象都可以被处理。对我来说,一个基本的实现就足够了,但是你可以疯狂地做各种各样的合并等等。

在下面的例子中,我正在跟踪内部(绿色)div的宽度变化。它的宽度设置为50%,但max-width为200px。拖动滑块会影响包装器(灰色)div的宽度。你可以看到,只有当内部div的宽度发生变化时,可观察对象才会触发,只有当外部div的宽度小于400px时才会发生这种情况。

const { interval } = rxjs; const { distinctUntilChanged, map, filter } = rxjs.operators; const wrapper = document.getElementById('my-wrapper'); const input = document.getElementById('width-input'); function subscribeToResize() { const timer = interval(100); const myDiv = document.getElementById('my-div'); const widthElement = document.getElementById('width'); const isMax = document.getElementById('is-max'); /* NOTE: This is the important bit here */ timer .pipe( map(() => myDiv ? Math.round(myDiv.getBoundingClientRect().width) : 0), distinctUntilChanged(), // adding a takeUntil(), here as well would allow cleanup when the component is destroyed ) .subscribe((width) => { widthElement.innerHTML = width; isMax.innerHTML = width === 200 ? 'Max width' : '50% width'; }); } function defineRange() { input.min = 200; input.max = window.innerWidth; input.step = 10; input.value = input.max - 50; } function bindInputToWrapper() { input.addEventListener('input', (event) => { wrapper.style.width = `${event.target.value}px`; }); } defineRange(); subscribeToResize(); bindInputToWrapper(); .inner { width: 50%; max-width: 200px; } /* Aesthetic styles only */ .inner { background: #16a085; } .wrapper { background: #ecf0f1; color: white; margin-top: 24px; } .content { padding: 12px; } body { font-family: sans-serif; font-weight: bold; } <script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script> <h1>Resize Browser width</h1> <label for="width-input">Adjust the width of the wrapper element</label> <div> <input type="range" id="width-input"> </div> <div id="my-wrapper" class="wrapper"> <div id="my-div" class="inner"> <div class="content"> Width: <span id="width"></span>px <div id="is-max"></div> </div> </div> </div>

其他回答

我的jQuery插件在所有元素上启用了“调整大小”事件,而不仅仅是窗口。

https://github.com/dustinpoissant/ResizeTriggering

$("#myElement") .resizeTriggering().on("resize", function(e){
  // Code to handle resize
}); 

通过@gman扩展这个答案,这里有一个允许每个元素多次回调的函数,将宽度和高度分解为一个准事件对象。请参阅关于堆栈溢出的嵌入式演示(您可能需要彻底调整主浏览器的大小以触发它)

function elementResizeWatcher(element, callback) { var resolve=function(element) { return (typeof element==='string' ? document[ ['.','#'].indexOf(element.charAt(0)) < 0 ? "getElementById" : "querySelector" ] (element) : element); }, observer, watched = [], checkForElementChanges = function (data) { var w=data.el.offsetWidth,h=data.el.offsetHeight; if ( data.offsetWidth !== w || data.offsetHeight !== h ) { data.offsetWidth = w; data.offsetHeight = h; data.cb({ target : data.el, width : w, height : h }); } }, checkForChanges=function(){ watched.forEach(checkForElementChanges); }, started=false, self = { start: function () { if (!started) { // Listen to the window resize event window.addEventListener("resize", checkForChanges); // Listen to the element being checked for width and height changes observer = new MutationObserver(checkForChanges); observer.observe(document.body, { attributes: true, childList: true, characterData: true, subtree: true }); started=true; } }, stop : function ( ) { if (started) { window.removeEventListener('resize', checkForChanges); observer.disconnect(); started = false; } }, addListener : function (element,callback) { if (typeof callback!=='function') return; var el = resolve(element); if (typeof el==='object') { watched.push({ el : el, offsetWidth : el.offsetWidth, offsetHeight : el.offsetHeight, cb : callback }); } }, removeListener : function (element,callback) { var el = resolve(element); watched = watched.filter(function(data){ return !((data.el===el) && (data.cb===callback)); }); } }; self.addListener(element,callback); self.start(); return self; } var watcher = elementResizeWatcher("#resize_me_on_stack_overflow", function(e){ e.target.innerHTML="i am "+e.width+"px&nbsp;x&nbsp;"+e.height+"px"; }); watcher.addListener(".resize_metoo",function(e) { e.target.innerHTML="and i am "+e.width+"px&nbsp;x&nbsp;"+e.height+"px"; }); var mainsize_info = document.getElementById("mainsize"); watcher.addListener(document.body,function(e) { mainsize_info.innerHTML=e.width+"px&nbsp;x&nbsp;"+e.height+"px"; }); #resize_me_on_stack_overflow{ background-color:lime; } .resize_metoo { background-color:yellow; font-size:36pt; width:50%; } <p> resize the main browser window! <span id="mainsize"><span> </p> <p id="resize_me_on_stack_overflow"> hey, resize me. </p> <p class="resize_metoo"> resize me too. </p>

您必须将resize事件绑定到窗口对象上,而不是绑定到通用html元素上。

然后你可以使用这个:

$(window).resize(function() {
    ...
});

在回调函数中,你可以检查div调用的新宽度

$('.a-selector').width();

因此,您的问题的答案是否定的,您不能将resize事件绑定到div。

我认为这是不可能的,但后来我想了一下,你可以手动调整一个div通过style="resize: both;"为了做到这一点,你必须点击它,所以添加了一个onclick函数来检查元素的高度和宽度,它工作。只有5行纯javascript(当然可以更短) http://codepen.io/anon/pen/eNyyVN

<div id="box" style="
                height:200px; 
                width:640px;
                background-color:#FF0066;
                resize: both;
                overflow: auto;" 
                onclick="myFunction()">
    <p id="sizeTXT" style="
                font-size: 50px;">
       WxH
    </p>
    </div>

<p>This my example demonstrates how to run a resize check on click for resizable div.</p>

<p>Try to resize the box.</p>


<script>
function myFunction() {
var boxheight = document.getElementById('box').offsetHeight;
var boxhwidth = document.getElementById('box').offsetWidth;
var txt = boxhwidth +"x"+boxheight;
document.getElementById("sizeTXT").innerHTML = txt;
}
</script>

您可以尝试以下代码片段中的代码,它使用纯javascript满足您的需求。(如果您想测试div,则运行代码片段并单击整页链接以触发div调整大小的警报。)

基于这是一个100毫秒的setInterval的事实,我敢说我的PC没有发现它太多的CPU饥饿。(0.1%的CPU被用作测试时Chrome中所有打开的选项卡的总和。)但这只是一个div,如果你想为大量的元素这样做,那么是的,它可能是非常CPU饥饿。 无论如何,您总是可以使用单击事件来停止div-resize嗅探。

var width = 0; var interval = setInterval(function(){ if(width <= 0){ width = document.getElementById("test_div").clientWidth; } if(document.getElementById("test_div").clientWidth!==width) { alert('resized div'); width = document.getElementById("test_div").clientWidth; } }, 100); <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>

你也可以检查一下小提琴

更新

var width = 0; function myInterval() { var interval = setInterval(function(){ if(width <= 0){ width = document.getElementById("test_div").clientWidth; } if(document.getElementById("test_div").clientWidth!==width) { alert('resized'); width = document.getElementById("test_div").clientWidth; } }, 100); return interval; } var interval = myInterval(); document.getElementById("clickMe").addEventListener( "click" , function() { if(typeof interval!=="undefined") { clearInterval(interval); alert("stopped div-resize sniffing"); } }); document.getElementById("clickMeToo").addEventListener( "click" , function() { myInterval(); alert("started div-resize sniffing"); }); <div id="test_div" style="width: 100%; min-height: 30px; border: 1px dashed pink;"> <input type="button" value="button 1" id="clickMe" /> <input type="button" value="button 2" id="clickMeToo" /> <input type="button" value="button 3" /> </div>

更新的小提琴