Search code examples
javascriptjquerycssmedia-queries

How do I "refire" jQuery(window).resize(checkSize)?


I'm trying to add and remove classes depending on a CSS rule for screens 500px and smaller. In CSS, I use

@media (max-width: 500px) {
.evidence img {display:none;}
}

and this jQuery function looks for that CSS and adds and removes classes:

jQuery(document).ready(function() {
checkSize();
jQuery(window).resize(checkSize);
function checkSize(){
if (jQuery(".page-template .evidence img").css("display") == "none"){
jQuery( ".page-template .evidence .two-col").addClass("left").removeClass("two-col");
jQuery( ".page-template .evidence .right").addClass("left").removeClass("right");
} }
});

The problem is when I resize the window to more than 500px, the jQuery rule doesn't "refire" and read the CSS classes and rules again.

I've tried to "reverse" them, i.e. with

.evidence img {display:block;}

and

if (jQuery(".page-template .evidence-cards img").css("display") == "block"){
jQuery( ".page-template .evidence .two-col").addClass("two-col").removeClass("left");
jQuery( ".page-template .evidence .right").addClass("right").removeClass("left");
} }

Any ideas? How can I force jQuery(window).resize(checkSize); to fire again?

Edit 6/05/19

re: Daniel Beck's answer, the key was the fact that the classes change and are no longer there to identify the divs when resized >500px. I can't change the classes to IDs, but I added additional classes (that are not called in the stylesheet) that stay static, i.e. .change-two-col, .change-right. This works:

jQuery(document).ready(function() {
function checkSize() {
  if (jQuery(".page-template .evidence img").css("display") == "none") {
    jQuery(".page-template .evidence .change-two-col").addClass("left").removeClass("two-col");
    jQuery(".page-template .evidence .change-right").addClass("left").removeClass("right");
  } else {
    jQuery(".page-template .evidence .change-two-col").addClass("two-col").removeClass("left");
    jQuery(".page-template .evidence .change-right").addClass("right").removeClass("left");
  }
}
checkSize();
jQuery(window).resize(checkSize);
});

Solution

  • The problem isn't that the function isn't firing -- resize fires continuously whenever the window resizes -- it's that the function only makes one-way changes to the DOM; it never tries to handle the case where the image is visible.

    You're also losing track of which element is which: then the page is less than 500px wide, you remove the identifying classnames on both divs and replace them with '.left', so when the window resizes to a larger size, you're no longer able to match the individual elements using the original classnames. One way to fix this would be to add unique classnames (or, better, IDs) to the elements which won't change, so you can use those to identify the elements:

    function checkSize() {
      if (jQuery(".page-template .evidence img").css("display") == "none") {
        jQuery("#foo").addClass("left").removeClass("two-col");
        jQuery("#bar").addClass("left").removeClass("right");
      } else {
        jQuery("#foo").removeClass("left").addClass("two-col");
        jQuery("#bar").addClass("right").removeClass("left");
      }
    }
    
    checkSize();
    jQuery(window).resize(checkSize);
    @media (max-width: 500px) {
      .evidence img {
        display: none;
      }
    }
    
    .two-col {
      background-color: red
    }
    
    .left {
      background-color: blue
    }
    
    .right {
      background-color: green
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="page-template">
      <div class="evidence">
        <img src="https://placehold.it/100x100">
        <div id="foo" class="two-col">two-col</div>
        <div id="bar" class="right">right</div>
      </div>
    </div>

    (It's probably also worth noting that you'd be much better off handling all of this via media queries instead of by toggling classnames in javascript; anything that can be done by adding or removing classes could be handled via media queries instead.)