Kyle Underhill
Kyle Underhill

Reputation: 109

jQuery - if / else on window resize (how to bind 2 or more events in jQuery)

The code changes the background-color of the .box if the window is <= 479 && hasClass("active"). The problem is the else doesn't work when the window is resized >=479.

Whether it's on load or if the window is resized after load, I want the else statement to be true unless the if conditions are met. In other words, the if statement is only true when the conditions are met, otherwise else is always the true state of the box.

$(".button").on("click", function() {
  const dataClose = $(this).attr("data-close");
  const elem = $('[data-id="' + dataClose + '"]').length ?
    $('[data-id="' + dataClose + '"]') :
    $(dataClose);
  if (elem.hasClass("active") && elem.is(":visible")) {
    elem.removeClass("active");
  } else {
    const id = $(this).prop("id");
    $(".modal").each(function() {
      $(this).toggleClass("active", $(this).data("id") == id);
    });
  }
  if ($(window).width() <= 479 && elem.hasClass("apple-modal") && elem.hasClass("active")) {
    $(".box").css("background", "blue");
  } else {
    $(".box").css("background", "");
  }
});

$(document).on("click", function(e) {
  if (
    $(".apple-modal, .google-modal").hasClass("active") &&
    !$(".modal, .modal *, .button").is(e.target)
  ) {
    $(".modal").removeClass("active");
  }
});
.box {
  height: 200px;
  width: 200px;
  border: 2px solid;
}

.buttons {
  display: flex;
  align-items: center;
}

.button {
  height: 30px;
  cursor: pointer;
  border: 2px solid;
  padding: 1rem;
  font-size: 28px;
}

#icon {
  color: silver;
}

.header {
  height: 15px;
  background: #eee;
}

.modal {
  position: fixed;
  top: 72px;
  right: 15px;
  z-index: 6;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.5);
  transform-origin: top right;
  transition: 0.15s;
  box-shadow: 0 1.5px 4px rgba(0, 0, 0, 0.24), 0 1.5px 6px rgba(0, 0, 0, 0.12);
}

.modal:after {
  content: "";
  width: 15px;
  height: 15px;
  background: inherit;
  position: absolute;
  background: #eee;
  top: -6px;
  right: 8px;
  opacity: 0;
  visibility: hidden;
  transform: rotate(45deg) scale(0.5);
  transition: 0.15s;
}

.modal.active {
  opacity: 1;
  visibility: visible;
  transform: scale(1);
}

.modal.active:after {
  opacity: 1;
  visibility: visible;
  transform: rotate(45deg) scale(1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="buttons">
  <img src="https://www.dignitasteam.com/wp-content/uploads/2015/09/3050613-inline-i-2-googles-new-logo-copy.png" class="button" id="google" data-close="google" />
  <img src="https://www.arabianbusiness.com/sites/default/files/styles/full_img/public/images/2017/01/17/apple-logo-rainbow.jpg" class="button" id="apple" data-close="apple" />
  <div class="button" id="icon" data-close="icon">
    <i class="fas fa-bell"></i>
  </div>
</div>
<div class="modal google-modal" data-id="google">
  <div class="header">Google</div>
  <ul>
    <li>
      First
    </li>
    <li>
      Second
    </li>
    <li>
      Third
    </li>
  </ul>
</div>
<div class="modal apple-modal" data-id="apple">
  <div class="header">Apple</div>
  <ul>
    <li>
      First
    </li>
    <li>
      Second
    </li>
    <li>
      Third
    </li>
  </ul>
</div>
<div class="modal icon-modal" data-id="icon">
  <div class="header">Icon</div>
  <ul>
    <li>
      First
    </li>
    <li>
      Second
    </li>
    <li>
      Third
    </li>
  </ul>
</div>
<div class="box"></div>

Upvotes: 1

Views: 479

Answers (2)

Atul Rajput
Atul Rajput

Reputation: 4178

As per your requirements, you need to check if modal is active on window load and window size is less than or equal to 479,

in this case, you need to bind these 2 events, window.load and window.resize

Check the example below,

$(window).bind("load resize", function() {
    var modalDiv = $('.modal');
    var isModalActive = modalDiv.hasClass('active');
    var windowWidth = $(window).width();
    if(isModalActive && windowWidth <= 479){
       console.log("modal active");
       $(".box").css("background", "blue");
    }else {
       $(".box").css("background", "red");
    }
});

as per your question I have added that event in code, I am attaching a codepen as well so you can resize the window and check the result.

as per your question and comments,

  1. your box will not have any background color
  2. if the window width is less than 479 and modal is active then it will be blue
  3. if you resize the window and if it goes above 479 then again no background color.

if you need something else, please let me know, we will discuss and make it happen.

NOTE: to check the result resize the window by open the modal and without opening it, in both the cases, check console as well.

Upvotes: 2

Desmond Cheong
Desmond Cheong

Reputation: 836

So If I understand your question correctly, you want the following behaviours:

  1. At any time, if your element with class "apple-modal" is active, and the window width is less than 479, colour the box blue.

  2. If, at any time, the window is resized and the width is now > 479, even if the element with the class "apple-modal" is still active, remove the background colour of the box.

First let us refactor the box colouring code. We define a function update_color() that will loop through each button and check if its corresponding element is active, and the window width is less than 479. If any of these conditions are true, we colour the box accordingly and break from the loop. i.e.

function update_color() {
    $('.button').each(function(i, button) {
        let dataClose = $(button).attr("data-close");
        let elem = $('[data-id="' + dataClose + '"]').length ?
            $('[data-id="' + dataClose + '"]') :
            $(dataClose);
        if ($(window).width() <= 479 && elem.hasClass("apple-modal") && elem.hasClass("active")) {
            $(".box").css("background", "blue");
            return false;
        } else {
            $(".box").css("background", "");
        }
    });
}

Next, we simply call update_color() at three points:

  1. After it's defined, so that the box is coloured appropriately on load. i.e. update_color();

  2. After every window resize event to check if the box should be coloured differently. i.e. $(window).on("resize", update_color);

  3. After every button click to check if the active states have changed. i.e.

    $(".button").on("click", function(e) {
        const dataClose = $(this).attr("data-close");
        const elem = $('[data-id="' + dataClose + '"]').length ?
              $('[data-id="' + dataClose + '"]') :
              $(dataClose);
        if (elem.hasClass("active") && elem.is(":visible")) {
            elem.removeClass("active");
        } else {
            const id = $(this).prop("id");
            $(".modal").each(function() {
                $(this).toggleClass("active", $(this).data("id") == id);
            });
        }
        update_color();
    });
    

Overall, the following code snippet should produce the desired behaviour.

function update_color() {
    $('.button').each(function(i, button) {
        let dataClose = $(button).attr("data-close");
        let elem = $('[data-id="' + dataClose + '"]').length ?
            $('[data-id="' + dataClose + '"]') :
            $(dataClose);
        if ($(window).width() <= 479 && elem.hasClass("apple-modal") && elem.hasClass("active")) {
            $(".box").css("background", "blue");
            return false;
        } else {
            $(".box").css("background", "");
        }
    });
}

update_color();

$(window).on("resize", update_color);

$(".button").on("click", function(e) {
    const dataClose = $(this).attr("data-close");
    const elem = $('[data-id="' + dataClose + '"]').length ?
          $('[data-id="' + dataClose + '"]') :
          $(dataClose);
    if (elem.hasClass("active") && elem.is(":visible")) {
        elem.removeClass("active");
    } else {
        const id = $(this).prop("id");
        $(".modal").each(function() {
            $(this).toggleClass("active", $(this).data("id") == id);
        });
    }
    update_color();
});

$(document).on("click", function(e) {
    if (
        $(".apple-modal, .google-modal").hasClass("active") &&
            !$(".modal, .modal *, .button").is(e.target)
    ) {
        $(".modal").removeClass("active");
    }
});
.box {
  height: 200px;
  width: 200px;
  border: 2px solid;
}

.buttons {
  display: flex;
  align-items: center;
}

.button {
  height: 30px;
  cursor: pointer;
  border: 2px solid;
  padding: 1rem;
  font-size: 28px;
}

#icon {
  color: silver;
}

.header {
  height: 15px;
  background: #eee;
}

.modal {
  position: fixed;
  top: 72px;
  right: 15px;
  z-index: 6;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.5);
  transform-origin: top right;
  transition: 0.15s;
  box-shadow: 0 1.5px 4px rgba(0, 0, 0, 0.24), 0 1.5px 6px rgba(0, 0, 0, 0.12);
}

.modal:after {
  content: "";
  width: 15px;
  height: 15px;
  background: inherit;
  position: absolute;
  background: #eee;
  top: -6px;
  right: 8px;
  opacity: 0;
  visibility: hidden;
  transform: rotate(45deg) scale(0.5);
  transition: 0.15s;
}

.modal.active {
  opacity: 1;
  visibility: visible;
  transform: scale(1);
}

.modal.active:after {
  opacity: 1;
  visibility: visible;
  transform: rotate(45deg) scale(1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="buttons">
  <img src="https://www.dignitasteam.com/wp-content/uploads/2015/09/3050613-inline-i-2-googles-new-logo-copy.png" class="button" id="google" data-close="google" />
  <img src="https://www.arabianbusiness.com/sites/default/files/styles/full_img/public/images/2017/01/17/apple-logo-rainbow.jpg" class="button" id="apple" data-close="apple" />
  <div class="button" id="icon" data-close="icon">
    <i class="fas fa-bell"></i>
  </div>
</div>
<div class="modal google-modal" data-id="google">
  <div class="header">Google</div>
  <ul>
    <li>
      First
    </li>
    <li>
      Second
    </li>
    <li>
      Third
    </li>
  </ul>
</div>
<div class="modal apple-modal" data-id="apple">
  <div class="header">Apple</div>
  <ul>
    <li>
      First
    </li>
    <li>
      Second
    </li>
    <li>
      Third
    </li>
  </ul>
</div>
<div class="modal icon-modal" data-id="icon">
  <div class="header">Icon</div>
  <ul>
    <li>
      First
    </li>
    <li>
      Second
    </li>
    <li>
      Third
    </li>
  </ul>
</div>
<div class="box"></div>

Upvotes: 1

Related Questions