wake-up-neo.net

Wie kann man feststellen, dass sich die Dimension des DIV geändert hat?

Ich habe das folgende Beispiel-HTML, es gibt ein DIV, das 100% Breite hat. Es enthält einige Elemente. Während der Größenänderung von Fenstern können die inneren Elemente neu positioniert werden, und die Dimension des div kann sich ändern. Ich frage, ob es möglich ist, das Dimensionsänderungsereignis des Div zu aktivieren. und wie geht das? Derzeit binde ich die Rückruffunktion an das jQuery-Ereignis zur Größenänderung auf dem Ziel-DIV. Es wird jedoch kein Konsolenprotokoll ausgegeben, siehe unten:

Before Resizeenter image description here

<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>
273
William Choi

Es gibt eine sehr effiziente Methode, um festzustellen, ob die Größe eines Elements geändert wurde.

http://marcj.github.io/css-element-queries/

Diese Bibliothek hat eine Klasse ResizeSensor, die zur Erkennung von Größenänderungen verwendet werden kann. 
Es verwendet einen ereignisbasierten Ansatz, ist also verdammt schnell und verschwendet keine CPU-Zeit.

Beispiel:

new ResizeSensor(jQuery('#divId'), function(){ 
    console.log('content dimension changed');
});

Verwenden Sie nicht das jQuery onresize plugin, da es die setTimeout()-Schleife zur Überprüfung auf Änderungen verwendet. 
THIS IS UNGLAUBLICH UND NICHT GENAU.

Offenlegung: Ich bin direkt mit dieser Bibliothek verbunden.

228
Marc J. Schmidt

Ein neuer Standard dafür ist das in Chrome 64 verfügbare Resize Observer-API.

function outputsize() {
 width.value = textbox.offsetWidth
 height.value = textbox.offsetHeight
}
outputsize()

new ResizeObserver(outputsize).observe(textbox)
Width: <output id="width">0</output><br>
Height: <output id="height">0</output><br>
<textarea id="textbox">Resize me</textarea><br>

Beobachter verkleinern

Spec: https://wicg.github.io/ResizeObserver

Polyfills: https://github.com/WICG/ResizeObserver/issues/3

Firefox Ausgabe: https://bugzil.la/1272409

Safari Ausgabe: http://wkb.ug/157743

Aktueller Support: http://caniuse.com/#feat=resizeobserver

127
Daniel Herr

Sie müssen das Ereignis resize für das Objekt window und nicht für ein generisches HTML-Element binden.

Sie könnten dann folgendes verwenden:

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

und innerhalb der Rückruffunktion können Sie die neue Breite Ihres div-Aufrufs überprüfen

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

Die Antwort auf Ihre Frage ist also nein , Sie können das resize -Ereignis nicht an ein div binden.

Langfristig können Sie den ResizeObserver verwenden.

new ResizeObserver(callback).observe(element);

Leider wird es derzeit in vielen Browsern nicht standardmäßig unterstützt.

In der Zwischenzeit können Sie die folgenden Funktionen verwenden. Da die meisten Elementgrößenänderungen von der Größenänderung des Fensters oder vom Ändern von Elementen im DOM stammen. Sie können die Größenänderung des Fensters mit dem Ereignis resize des Fensters überwachen und DOM-Änderungen mithilfe von MutationObserver überwachen.

Hier ein Beispiel für eine Funktion, die Sie zurückruft, wenn sich die Größe des bereitgestellten Elements als Ergebnis eines dieser Ereignisse ändert:

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
  });
};
22
nkron

Die beste Lösung wäre die Verwendung der sogenannten Element Queries. Sie sind jedoch kein Standard, es gibt keine Spezifikation - und die einzige Option ist die Verwendung einer der verfügbaren Polyfills/Bibliotheken, wenn Sie auf diese Weise vorgehen möchten.

Die Idee hinter Elementabfragen besteht darin, einem bestimmten Container auf der Seite zu erlauben, auf den ihm zur Verfügung gestellten Speicherplatz zu reagieren. Dadurch können Sie eine Komponente einmal schreiben und dann an einer beliebigen Stelle auf der Seite ablegen, während der Inhalt an die aktuelle Größe angepasst wird. Egal was die Fenstergröße ist. Dies ist der erste Unterschied zwischen Elementabfragen und Medienabfragen. Jeder hofft, dass irgendwann eine Spezifikation erstellt wird, die Elementabfragen (oder etwas, das dasselbe Ziel erreicht) standardisiert und sie nativ, sauber, einfach und robust macht. Die meisten Leute sind sich einig, dass Medienanfragen ziemlich begrenzt sind und nicht für das modulare Design und echte Reaktionsfähigkeit hilfreich sind.

Es gibt ein paar Polyfills/Bibliotheken, die das Problem auf verschiedene Weise lösen (könnte man jedoch auch Problemumgehungen anstelle von Lösungen nennen):

Ich habe andere Lösungen für ähnliche Probleme gesehen. Normalerweise verwenden sie Timer oder die Größe des Fensters/Ansichtsfensters unter der Haube, was keine echte Lösung ist. Darüber hinaus denke ich, dass dies idealerweise hauptsächlich in CSS gelöst werden sollte und nicht in Javascript oder HTML. 

14
Stan

Ich fand diese Bibliothek zu funktionieren, wenn MarcJs Lösung nicht funktionierte:

https://github.com/sdecima/javascript-detect-element-resize

Es ist sehr leicht und erkennt sogar natürliche Größenänderungen über CSS oder einfach das Laden/Rendern von HTML.

Codebeispiel (aus dem Link entnommen):

<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>
14
joshcomley

Werfen Sie einen Blick auf diese http://benalman.com/code/projects/jquery-resize/examples/resize/

Es hat verschiedene Beispiele. Versuchen Sie, die Fenstergröße zu ändern, und sehen Sie, wie Elemente in Containerelementen angepasst werden.

Beispiel mit js Geige, um zu erklären, wie es funktioniert.
Schauen Sie sich diese Geige an http://jsfiddle.net/sgsqJ/4/

In diesem resize () -Ereignis ist ein Ereignis an ein Element mit der Klasse "test" und auch an das Fensterobjekt Gebunden. In resize () wird der Callback des Fensterobjekts $ ('. Test').

z.B.

$('#test_div').bind('resize', function(){
            console.log('resized');
});

$(window).resize(function(){
   $('#test_div').resize();
});
14
Bharat Patil

ResizeSensor.js ist Teil einer riesigen Bibliothek, aber ich habe die Funktionalität auf THIS reduziert:

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);
};

Wie man es benutzt:

let container = document.querySelector(".container");
new ResizeSensor(container, function()
{
    console.log("dimension changed:", container.clientWidth, container.clientHeight);
});
13
Martin Wantke

Ich empfehle NICHT setTimeout() hack, da dies die Leistung verlangsamt!!. Stattdessen können Sie DOM-Mutationsbeobachter verwenden, um die Div-Größenänderung zu hören.

JS:

var observer = new MutationObserver(function(mutations) {
    console.log('size changed!');
  });
  var target = document.querySelector('.mydiv');
  observer.observe(target, {
    attributes: true
  });

HTML:

<div class='mydiv'>
</div>

Hier ist die Geige
Versuchen Sie, die Div-Größe zu ändern.


Sie können Ihre Methode in die debounce -Methode einschließen, um die Effizienz zu verbessern. debounce löst Ihre Methode alle x Millisekunden aus, anstatt jede Millisekunde auszulösen, an der die DIV geändert wird.

12
JerryGoyal

Nur das Fensterobjekt generiert ein Ereignis "Größe ändern". Ich weiß nur, was Sie tun wollen, indem Sie einen Intervall-Timer ausführen, der die Größe regelmäßig überprüft.

7
Pointy

Sie können iframe oder object mit contentWindow oder contentDocument für die Größenänderung verwenden. Ohne setInterval oder setTimeout

Die Schritte:

  1. Setzen Sie Ihre Elementposition auf relative.
  2. Fügen Sie einen transparenten absoluten versteckten IFRAME hinzu
  3. Hören Sie das Ereignis IFRAME.contentWindow - onresize ab

Ein Beispiel für HTML:

<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>

Das 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')
})

Beispiel ausführen

JsFiddle: https://jsfiddle.net/qq8p470d/


Mehr sehen:

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>

6
Aikon Mogwai

Mein jQuery-Plugin aktiviert das "resize" -Ereignis für alle Elemente, nicht nur für die window.

https://github.com/dustinpoissant/ResizeTriggering

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

Dieser Blogbeitrag half mir, Größenänderungen an DOM-Elementen effizient zu erkennen.

http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/

So verwenden Sie diesen Code ...

AppConfig.addResizeListener(document.getElementById('id'), function () {
  //Your code to execute on resize.
});

Paketcode, der vom Beispiel verwendet wird ...

var AppConfig = AppConfig || {};
AppConfig.ResizeListener = (function () {
    var attachEvent = document.attachEvent;
    var isIE = navigator.userAgent.match(/Trident/);
    var requestFrame = (function () {
        var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
            function (fn) { return window.setTimeout(fn, 20); };
        return function (fn) { return raf(fn); };
    })();

    var cancelFrame = (function () {
        var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
               window.clearTimeout;
        return function (id) { return cancel(id); };
    })();

    function resizeListener(e) {
        var win = e.target || e.srcElement;
        if (win.__resizeRAF__) cancelFrame(win.__resizeRAF__);
        win.__resizeRAF__ = requestFrame(function () {
            var trigger = win.__resizeTrigger__;
            trigger.__resizeListeners__.forEach(function (fn) {
                fn.call(trigger, e);
            });
        });
    }

    function objectLoad(e) {
        this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__;
        this.contentDocument.defaultView.addEventListener('resize', resizeListener);
    }

    AppConfig.addResizeListener = function (element, fn) {
        if (!element.__resizeListeners__) {
            element.__resizeListeners__ = [];
            if (attachEvent) {
                element.__resizeTrigger__ = element;
                element.attachEvent('onresize', resizeListener);
            } else {
                if (getComputedStyle(element).position === 'static') element.style.position = 'relative';
                var obj = element.__resizeTrigger__ = document.createElement('object');
                obj.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; pointer-events: none; z-index: -1;');
                obj.__resizeElement__ = element;
                obj.onload = objectLoad;
                obj.type = 'text/html';
                if (isIE) element.appendChild(obj);
                obj.data = 'about:blank';
                if (!isIE) element.appendChild(obj);
            }
        }
        element.__resizeListeners__.Push(fn);
    };

    AppConfig.removeResizeListener = function (element, fn) {
        element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
        if (!element.__resizeListeners__.length) {
            if (attachEvent) element.detachEvent('onresize', resizeListener);
            else {
                element.__resizeTrigger__.contentDocument.defaultView.removeEventListener('resize', resizeListener);
                element.__resizeTrigger__ = !element.removeChild(element.__resizeTrigger__);
            }
        }
    }
})();

Hinweis: AppConfig ist ein Namespace/Objekt, das ich zum Organisieren wiederverwendbarer Funktionen verwende. Fühlen Sie sich frei, den Namen durch alles zu ersetzen, was Sie möchten.

3
Ben Gripka

Sie können den Code im folgenden Snippet ausprobieren. Er deckt Ihre Bedürfnisse mit einfachem Javascript ab. ( Führen Sie das Code-Snippet aus und klicken Sie auf den Link für die gesamte Seite, um die Warnung auszulösen, dass die Größe des Divs geändert wird, wenn Sie es testen möchten.).

Aufgrund der Tatsache, dass dies eine setInterval von 100 Millisekunden ist, würde ich sagen, dass mein PC es nicht zu sehr CPU-hungrig fand. (0,1% der CPU wurden in Chrome zum getesteten Zeitpunkt) als Gesamtmenge für alle geöffneten Tabs verwendet.) Aber auch dies gilt nur für einen Div, wenn Sie dies für einen tun möchten große Menge an Elementen dann könnte es ja sehr CPU-hungrig sein.

Sie können jederzeit ein Klickereignis verwenden, um die Größenänderung zu stoppen schnüffeln.

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>

Sie können das Geige auch überprüfen

[~ # ~] Update [~ # ~]

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>

Aktualisiert Geige

2
Peter Darmis

Mit Clay.js ( https://github.com/zzarcon/clay ) ist es sehr einfach, Änderungen an der Elementgröße zu erkennen:

var el = new Clay('.element');

el.on('resize', function(size) {
    console.log(size.height, size.width);
});
2
Zzarcon

Erstaunlicherweise so alt dieses Problem ist, ist dies in den meisten Browsern immer noch ein Problem.

Wie bereits erwähnt wurde, wird Chrome 64+ jetzt nativ mit Resize Observes ausgeliefert. Die Spezifikation wird jedoch immer noch optimiert, und Chrome liegt derzeit (Stand: 29.01.2017) hinter der neuesten Ausgabe der Spezifikation .

Ich habe ein paar gute ResizeObserver-Polyfills in freier Wildbahn gesehen, jedoch folgen einige nicht genau den Spezifikationen, die eng beieinander liegen, und andere haben einige Berechnungsprobleme.

Ich brauchte dieses Verhalten dringend, um responsive Webkomponenten zu erstellen, die in jeder Anwendung verwendet werden können. Damit sie einwandfrei funktionieren, müssen sie ihre Abmessungen zu jeder Zeit kennen. Deshalb klangen ResizeObservers ideal und ich entschied mich für eine Polyfill, die der Spezifikation so genau wie möglich folgte.

Repo: https://github.com/juggle/resize-observer

Demo: https://codesandbox.io/s/myqzvpmmy9

2
Trem

Dies ist so ziemlich eine exakte Kopie der obersten Antwort, aber statt eines Links ist es nur der Teil des Codes, der ausschlaggebend ist. Er ist übersichtlich, so dass er IMO besser lesbar und verständlicher ist. Ein paar andere kleine Änderungen beinhalten die Verwendung von cloneNode () und nicht das Einfügen von html in einen js-String. Kleinigkeiten, aber Sie können dies kopieren und einfügen, und es funktioniert.

Die Funktionsweise besteht darin, dass zwei unsichtbare divs das Element, das Sie gerade betrachten, ausfüllen und dann einen Auslöser in jedes Element setzen und eine Bildlaufposition festlegen, die beim Ändern der Größe zu einer Bildlaufänderung führt.

Alles, was Sie wirklich verdienen, geht an Marc J, aber wenn Sie nur nach dem entsprechenden Code suchen, dann hier:

    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);
    }
1
Seph Reed

verwenden Sie Bharat Patil answer, um den maximalen Stapelfehler zu vermeiden. Siehe Beispiel unten:

$('#test_div').bind('resize', function(){
   console.log('resized');
   return false;
});
0
White Rabbit

Hier ist eine vereinfachte Version der Lösung von @nkron, die auf ein einzelnes Element anwendbar ist (anstelle eines Arrays von Elementen in der Antwort von @nkron, Komplexität, die ich nicht brauchte).

function onResizeElem(element, callback) {    
  // Save the element we are watching
  onResizeElem.watchedElementData = {
    element: element,
    offsetWidth: element.offsetWidth,
    offsetHeight: element.offsetHeight,
    callback: callback
  };

  onResizeElem.checkForChanges = function() {
    const data = onResizeElem.watchedElementData;
    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 resize event
  window.addEventListener('resize', onResizeElem.checkForChanges);

  // Listen to the element being checked for width and height changes
  onResizeElem.observer = new MutationObserver(onResizeElem.checkForChanges);
  onResizeElem.observer.observe(document.body, {
    attributes: true,
    childList: true,
    characterData: true,
    subtree: true
  });
}

Der Ereignislistener und -beobachter kann entfernt werden durch:

window.removeEventListener('resize', onResizeElem.checkForChanges);
onResizeElem.observer.disconnect();
0
Gman

Reine Javascript-Lösung, funktioniert aber nur, wenn die Größe des Elements mit der Schaltfläche css resize geändert wird :

  1. elementgröße mit offsetWidth und offsetHeight speichern;
  2. füge einen onclick event Listener zu diesem Element hinzu;
  3. vergleichen Sie bei Auslösung die aktuellen Werte für offsetWidth und offsetHeight mit den gespeicherten Werten. Wenn dies nicht der Fall ist, führen Sie die gewünschten Schritte aus und aktualisieren Sie diese Werte.
0
roipoussiere
jQuery(document).ready( function($) {

function resizeMapDIVs() {

// check the parent value...

var size = $('#map').parent().width();



if( $size < 640 ) {

//  ...and decrease...

} else {

//  ..or increase  as necessary

}

}

resizeMapDIVs();

$(window).resize(resizeMapDIVs);

});
0

Dies ist eine wirklich alte Frage, aber ich dachte mir, ich würde meine Lösung dazu posten.

Ich habe versucht, ResizeSensor zu verwenden, da jeder ziemlich verknallt zu sein schien. Nach der Implementierung wurde mir jedoch klar, dass unter der Haube der Elementabfrage die Position relative oder absolute angewendet werden muss.

Am Ende handelte ich dies mit einem Rxjs interval anstatt einer geraden setTimeout oder requestAnimationFrame wie bei vorherigen Implementierungen. 

Das Schöne an der beobachtbaren Variante eines Intervalls ist, dass Sie den Stream ändern können, jedoch auch alle anderen beobachtbaren Werte bearbeitet werden können. Für mich war eine grundlegende Implementierung ausreichend, aber Sie könnten verrückt werden und alle Arten von Zusammenführungen usw. durchführen.

Im folgenden Beispiel verfolge ich die Breitenänderungen des inneren (grünen) Divs. Es hat eine Breite von 50%, aber eine maximale Breite von 200 Pixeln. Durch Ziehen des Schiebereglers wird die Breite des Wrappers (grau) div beeinflusst. Sie können sehen, dass das Observable nur ausgelöst wird, wenn sich die Breite des inneren Bereichs ändert, was nur dann der Fall ist, wenn die Breite des äußeren Bereichs weniger als 400 Pixel beträgt.

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>

0
Scrimothy