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

当前回答

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']}); #div {width: 100px; border: 1px solid #bbb; resize: both; overflow: hidden;} <div id = "div">DIV</div>

其他回答

通过@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>

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']}); #div {width: 100px; border: 1px solid #bbb; resize: both; overflow: hidden;} <div id = "div">DIV</div>

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

https://github.com/dustinpoissant/ResizeTriggering

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

唯一的窗户。onResize存在于规范中,但你总是可以利用IFrame在DIV中生成新的Window对象。

请核对这个答案。有一个新的jquery插件,它是可移植的,易于使用。您总是可以检查源代码,看看它是如何完成的。

<!-- (1) include plugin script in a page -->
<script src="/src/jquery-element-onresize.js"></script>

// (2) use the detectResizing plugin to monitor changes to the element's size:
$monitoredElement.detectResizing({ onResize: monitoredElement_onResize });

// (3) write a function to react on changes:
function monitoredElement_onResize() {    
    // logic here...
}

使用disconnect删除事件监听器:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["input", "context", "output"]

  connect() {
    this.inputObserver = new ResizeObserver(() => { this.resizeInput() })
    this.inputObserver.observe(this.inputTarget)
  }

  disconnect() {
    this.inputObserver.disconnect(this.inputTarget)
  }

  resizeInput() {
    const height = this.inputTarget.offsetHeight

    this.contextTarget.style.height = `${height}px`
    this.outputTarget.style.height = `${height}px`
  }
}