Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple instances of Javascript function with resize function

Tags:

javascript

I created a quick library to help me position text absolutely over a background image. It works great with one instance. As soon as I add multiple instances, the resize function inside the library function only works on the last instance.

Here is my library code -

function overlay(params) {
  function resizeOverlay(params) {
    //get the overlay container
    var layContainer = document.getElementsByClassName(params.element)[0];

    //user sets height and width of bg image used so we can calculate ratio
    var bgHeight = params.height;
    var bgWidth = params.width;

    var w = window,
    d = document,
    e = d.documentElement,
    g = d.getElementsByTagName('body')[0],
    x = w.innerWidth || e.clientWidth || g.clientWidth,
    y = w.innerHeight|| e.clientHeight|| g.clientHeight;

    var newSize = getFinalMeasurements(x, y, bgWidth, bgHeight);

    var newPos = getNewPosition(x, y, newSize);

    function getFinalMeasurements(x, y, natWidth, natHeight) {
      var finalSize = {};

      var originalRatios = {
        width: x / natWidth,
        height: y / natHeight
      };

      var coverRatio = Math.max(originalRatios.width, originalRatios.height); 

      finalSize = {
        height: natHeight * coverRatio,
        width: natWidth * coverRatio
      }

      return finalSize;
    }

    function getNewPosition(x, y, finalSize) {
      var left = finalSize.width - x;
      var top = finalSize.height - y;
      var leftPos;
      var topPos;
      var finalPos = {};

      if(left > 0) {
        leftPos = left/2;
      } else {
        leftPos = left;
      }

      if(top > 0) {
        topPos = top/2;
      } else {
        topPos = top;
      }

      finalPos = {
        left: leftPos,
        top: topPos
      }

      return finalPos;
    }

    layContainer.setAttribute('style', 'height:' + newSize.height + 'px; width:' + newSize.width + 'px; left: -' + newPos.left + 'px; top:-' + newPos.top + 'px');
  }

  resizeOverlay(params);

  window.onresize = function() {
    resizeOverlay(params);
    console.log('resizing');
  }
}

And then my instances -

var compassTextContainer = new overlay({
    width: 2364,
    height: 1314,
    element: 'compass-overlay'
});

var liveFeedContainer = new overlay({
    width: 2364,
    height: 1314,
    element: 'livefeed-overlay'
});

var rocketContainer = new overlay({
    width: 2364,
    height: 1314,
    element: 'rocket-overlay'
});

All of them work on initial load but when I resize the window, the rocket-overlay element is the only one working.

like image 642
Tyler Nichol Avatar asked Aug 04 '26 07:08

Tyler Nichol


2 Answers

It's because you're using onresize that overrides the previous event listener. So each time you set up an instance, that instance's resize event listener will override the previous one, hence only the last one works.

To fix that use addEventListener which adds the new event listener without removing the previous ones:

window.addEventListener("resize", function() {
  resizeOverlay(params);
  console.log('resizing');
});

Note: Since the logic is repeated among all the instances, you could refactor your code to use event delegation which only sets one event listener. Also, try not to redefine the functions resizeOverlay and getNewPosition each time you call overlay, an IIFE is ideal for this:

var overlay = (function() {
  function resizeOverlay(params) {
    // ...
  }

  function getNewPosition(x, y, finalSize) {
    // ...
  }

  return function(params) {
    resizeOverlay(params);
    window.addEventListener("resize", function() {
      resizeOverlay(params);
    });
  }
})();
like image 189
ibrahim mahrir Avatar answered Aug 05 '26 20:08

ibrahim mahrir


Replace window.onresize with window.addEventListener('resize', () => { resizeOverlay(params) } )

like image 44
Walid Ammar Avatar answered Aug 05 '26 20:08

Walid Ammar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!