3

I've seen similar cases but I can't seem to figure it how on my case.

So I got 3 different divs all having the same class of "display-boxes". What I'm trying to do is to apply my functions for all 3 divs. At the moment it's only applying the function for the last div.

$(".display-boxes").each(function() {
  var boxList = $(this).context;

  function resizeTeasersTablet(teaserNumber, teaserCollection) {
    if (teaserNumber == 1) {
      teaserCollection[0].style.width = '73.834%';
      teaserCollection[0].style.margin = '0 auto 40px';
      for (let i = 1; i < teaserNumber; i++) {
        teaserCollection[i].style.width = '25%';
      }
    } else if (teaserNumber == 2) {
      for (let i = 0; i < teaserNumber; i++) {
        teaserCollection[i].style.width = '50%';
      }
    } else if (teaserNumber == 4) {
      for (let i = 0; i < teaserNumber; i++) {
        teaserCollection[i].style.width = '50%';
      }
    } else if (teaserNumber == 5) {
      for (let i = 0; i < teaserNumber; i++) {
        teaserCollection[i].style.width = '50%';
      }
    } else if (teaserNumber == 3) {
      for (let i = 0; i < teaserNumber; i++) {
        teaserCollection[i].style.width = '33.33%';
      }
    }
  }

  function resizeTeasersMobile(teaserNumber, teaserCollection) {
    for (let i = 0; i < teaserNumber; i++) {
      teaserCollection[i].style.width = '100%';
    }
  }

  document.addEventListener('DOMContentLoaded', function() {
    if (window.innerWidth > 2024) {
      displayTeasers(boxList.childElementCount, boxList.children);
    } else if (window.innerWidth > 641) {
      resizeTeasersTablet(boxList.childElementCount, boxList.children);
    } else {
      resizeTeasersMobile(boxList.childElementCount, boxList.children);
    }
  });

  window.onresize = function() {
    if (window.innerWidth > 2024) {
      displayTeasers(boxList.childElementCount, boxList.children);
    } else if (window.innerWidth > 641) {
      resizeTeasersTablet(boxList.childElementCount, boxList.children);
    } else {
      resizeTeasersMobile(boxList.childElementCount, boxList.children);
    }
  };
});


<div id="section2" class="padding-margin-border column">
    <div class="lobby-images-wrapper small-block-grid-1 display-boxes ongoingPromo">
        <div class="display-box">
            <div class="wrapper-lobby-image-item">
                <span class="image-wrapper">
                    <a href="@@Field.Teaser_Link@@">@@MarkComponentField(FieldPath+".Teaser_Image")@@
                        <img src="@@Field.Teaser_Image@@" data-original="@@Field.Teaser_Image@@"/>
                    </a>
                </span>
            </div>
        </div>
    </div>
</div>

This is one of the 3 divs that I have since it won't let me post more code.

karagkalex
  • 93
  • 4

1 Answers1

2

There are two problems here:

  1. You've set window.onresize 3 times in a loop. Only the last assignment has an effect. You overwrite the previous two handlers. This is why your changes are only applied to your last div.

  2. Document:DOMContentLoaded event is raised when the HTML document is fully loaded and parsed, which means either:

    • Your JavaScript code is run when the document is not loaded, and so your jQuery selector will not find your divs (it seems that it is not your case). This case happens when you load the code directly in a script at the beginning of the document's body.
    • Your JavaScript code is run after the document is loaded, so you'll find all your elements, but the event is already fired and your handler is never called. This case happens when you put the code inside an onload handler.
    • Your code is run after the divs are created but before the document is fully loaded. This case happens if you run the code before the end tag of </body> for example. This is the only case that works as expected. You better not put your code at such a risk! Your code should be robust and reliable.

The Fix

Here is how you can fix your issues (please pay close attention to my comments):

// Define your utility functions at the root level

function resizeTeasersTablet(teaserCollection) {
    // No need to pass the collection size. It has a `length` property.
    let width = undefined;
    switch (teaserCollection.length) { // `swith`/`case` is simpler than those `if`s
        case 1:
            teaserCollection[0].style.width = '73.834%';
            teaserCollection[0].style.margin = '0 auto 40px';
            // The for loop is not needed. The length is 1!
            break;
        case 2:
        case 4:
        case 5:
            width = '50%';
            break;
        case 3:
            width = '33.33%';
            break;
    }
    if (width)
        for (let t of teaserCollection) // `for..of` is simpler
            t.style.width = width;
}

function resizeTeasersMobile(teaserCollection) {
    for (let t of teaserCollection)
        t.style.width = '100%';
}

// The function name is clear
function resizeBasedOnWindowWidth(boxList) {
    if (window.innerWidth > 2024)
        displayTeasers(boxList.children);
    else if (window.innerWidth > 641)
        resizeTeasersTablet(boxList.children);
    else
        resizeTeasersMobile(boxList.children);
}

// The function name is clear
function resizeAllBoxListsBasedOnWindowWidth() {
    $(".display-boxes").each(function () {
        resizeBasedOnWindowWidth(this);
    });
}

window.onresize = function () {
    this.resizeAllBoxListsBasedOnWindowWidth(); // Just call the defined function.
}

$(function () { // See here: https://api.jquery.com/ready/
    resizeAllBoxListsBasedOnWindowWidth(); // Do not repeat the code. Just call the function.
})

The principles I used in this code, are VERY important. I advise you to read the code multiple times :)

Good luck

Mohammad Dehghan
  • 16,319
  • 3
  • 50
  • 66