534 Stimmen

Wie lässt sich eine Änderung der DIV-Dimension erkennen?

Ich habe die folgende Beispiel-HTML, gibt es eine DIV, die 100% Breite hat. Es enthält einige Elemente. Bei der Größenänderung von Windows können die inneren Elemente neu positioniert werden, und die Größe des DIVs kann sich ändern. Ich frage, ob es möglich ist, die div's Dimension Änderung Ereignis Haken? und wie man das tun? Ich binde derzeit die Callback-Funktion an das jQuery-Resize-Ereignis auf dem Ziel-DIV, jedoch wird kein Konsolenprotokoll ausgegeben, siehe unten:

Before Resize enter 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>

0voto

Fábio Zangirolami Punkte 1736
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);

});

0voto

White Rabbit Punkte 1407

Mit Bharat Patil Antwort geben Sie einfach false in Ihrem Bind-Callback zurück, um einen maximalen Stack-Fehler zu vermeiden (siehe Beispiel unten):

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

0voto

Scrimothy Punkte 2491

Dies ist eine wirklich alte Frage, aber ich dachte mir, ich poste mal meine Lösung dazu.

Ich habe versucht, die ResizeSensor da alle ziemlich verknallt in sie zu sein schienen. Nach der Implementierung wurde mir jedoch klar, dass die Elementabfrage unter der Haube erfordert, dass das betreffende Element die Position relative o absolute angewandt, was in meiner Situation nicht funktioniert hat.

Ich habe das mit einem Rxjs gelöst. interval anstelle einer geraden setTimeout o requestAnimationFrame wie frühere Implementierungen.

Das Schöne an der beobachtbaren Variante eines Intervalls ist, dass man den Datenstrom so ändern kann, wie jede andere beobachtbare Größe auch behandelt werden kann. Für mich war eine grundlegende Implementierung genug, aber Sie könnten verrückt werden und alle Arten von Zusammenführungen usw. tun.

Im folgenden Beispiel verfolge ich die Änderungen der Breite des inneren (grünen) Divs. Es hat eine Breite auf 50 % festgelegt, aber eine max-Breite von 200px. Das Ziehen des Schiebereglers wirkt sich auf die Breite des Wrapper-Divs (grau) aus. Sie können sehen, dass die beobachtbare nur feuert, wenn die innere div's Breite ändert, die nur geschieht, wenn die äußere div's Breite kleiner als 400px ist.

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>

0voto

unsynchronized Punkte 4729

Weiterführend diese Antwort von @gman hier ist eine Funktion, die mehrere pro Element Rückrufe, Explodieren der Breite und Höhe in ein Quasi-Ereignis-Objekt ermöglicht. sehen Sie eingebettete Demo, die live hier auf Stack Overflow funktioniert (Sie müssen möglicherweise die Größe der Haupt-Browser drastisch für es auslösen)

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>

0voto

Paul H. Punkte 320

Reine Vanille-Implementierung.

var move = function(e) {
    if ((e.w && e.w !== e.offsetWidth) || (e.h && e.h !== e.offsetHeight)) {
        new Function(e.getAttribute('onresize')).call(e);
    }
    e.w = e.offsetWidth;
    e.h = e.offsetHeight;
}

var resize = function(e) {
    e.innerText = 'New dimensions: ' + e.w + ',' + e.h;
}

.resizable {
    resize: both;
    overflow: auto;
    width: 200px;
    border: 1px solid black;
    padding: 20px;
}

<div class='resizable' onresize="resize(this)" onmousemove="move(this)">
Pure vanilla implementation
</div>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X