How to detect DIV's dimension changed?

后端 未结 25 2378
抹茶落季
抹茶落季 2020-11-22 06:14

I\'ve the following sample html, there is a DIV which has 100% width. It contains some elements. While performing windows re-sizing, the inner elements may be re-positioned,

25条回答
  •  感情败类
    2020-11-22 06:43

    This is a really old question, but I figured I'd post my solution to this.

    I tried to use ResizeSensor since everyone seemed to have a pretty big crush on it. After implementing though, I realized that under the hood the Element Query requires the element in question to have position relative or absolute applied to it, which didn't work for my situation.

    I ended up handling this with an Rxjs interval instead of a straight setTimeout or requestAnimationFrame like previous implementations.

    What's nice about the observable flavor of an interval is that you get to modify the stream however any other observable can be handled. For me, a basic implementation was enough, but you could go crazy and do all sorts of merges, etc.

    In the below example, I'm tracking the inner (green) div's width changes. It has a width set to 50%, but a max-width of 200px. Dragging the slider affects the wrapper (gray) div's width. You can see that the observable only fires when the inner div's width changes, which only happens if the outer div's width is smaller than 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;
    }
    
    
    

    Resize Browser width

    Width: px

提交回复
热议问题