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.
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);
});
}
})();
Replace window.onresize with window.addEventListener('resize', () => { resizeOverlay(params) } )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With