Toggle class on orientation change in javascript

Viewed 1100

How can we toggle class of an element based on orientation of device.

Example:

<div class="landscape"></div>
@media (orientation: portrait) {
.landscape: {...}
}

I can change landscape css properties. but I want to avoid this.

Instead, I would like to change the class itself thus, it would look like

<div class="portrait"></div> // if orientation is portrait
<div class="landscape"></div> // if orientation is landscape

Any suggestions for this!

Note: Would accept answer for vue as well

Update: screen.orientation doesn't work on safari. solution should work on safari too.

thanks for your appretiatable answers.

5 Answers

Check out this code using matchMedia. But maybe I made a mistake somewhere in this code. But the essence and structure are correct.

window.matchMedia('(orientation: portrait)').addListener(function(m) {
       let div_class = document.querySelector('.landscape');
       if (m.matches) {
                div_class.className = 'portrait';
            } else {
                div_class.className = 'landscape';
            }
    });
window.addEventListener("orientationchange", function (event) {
  const { angle } = event.target.screen.orientation; // orientation angle
  let orientation = angle === 90 || angle === -90 ? "landscape" : "portrait";

  const element = document.getElementById("#customElement");
  
  element.classList.remove(['landscape', "portrait"]);
  element.classList.add(orientation);
});

a nice way to do this would be to give the element and id say "orient" ALSO: safari doesn't use window.screen.orientation, but window.orientation

<div class="" id="orient"></div>
const orient = document.querySelector("#orient")

//add the current orientation as a class
if(!window.orentation){
    orient.classList.add(window.screen.orientation===0 ||  window.screen.orientation===180 ? "portrait":"landscape")
}else{
    orient.classList.add(window.orientation===0 ||  window.orientation===180 ? "portrait":"landscape") //for safari
}

//now check for when orientation changes and toggle on/off as required
//safari uses window.orientation instead :(
window.addEventListener("orientationchange", (e)=>{
        orient.classList=""; //empty class list
        if(!window.orientation){
            orient.classList.add(window.screen.orientation===0 || window.screen.orientation===180 ? "portrait":"landscape"); //add the correct value back
        }else{
            orient.classList.add(window.orientation===0 || window.orientation===180 ? "portrait":"landscape"); //for safari :(
        }
});

How I implemented, based on accepted solution.

    window.matchMedia('(orientation: portrait)').addListener(function(event) {
      if (event.matches) {
        const landscapeClassElements = document.querySelectorAll('.landscape');
        landscapeClassElements.forEach(element => {
          element.classList.remove('landscape')
          element.classList.add('portrait')
        });
      } else {
        const portraitClassElements = document.querySelectorAll('.portrait');
        portraitClassElements.forEach(element => {
          element.classList.remove('portrait')
          element.classList.add('landscape')
        });
      }
    });

matchMedia('(orientation: portrait)').matches returns true for portrait

window.matchMedia is simple and works on safari as well!

You can use css to accomplish this!

.portrait { display: none; }
.landscape { display: block; }

@media (orientation: portrait) {
  .portrait { display: block; }
  .landscape { display: none; }
}
Related