Jebathon
Jebathon

Reputation: 4561

Trying to determine Device Type using CSS and Jquery not working as intended

I am trying to detect the clients device dimensions using a mixture between CSS and Javascript. [From this tutorial] I created an element that I appended to the body and assigned it a class that holds a value called "z-index" that determines the device type. However when running the following code I get "undefined" as the response.

How can I get a numeric value instead of undefined?

$(document).ready(function() {

  var indicator = document.createElement('div');
  indicator.className = 'state-indicator';
  document.getElementsByTagName('body')[0].appendChild(indicator);

  function getDeviceState() {
    var index = parseInt(window.getComputedStyle(indicator).getPropertyValue('z-index'), 10);

    var states = {
      0: 'desktop',
      1: 'small-desktop',
      2: 'large-tablet',
      3: 'medium-tablet',
      4: 'phone'
    };

    return states[index];
  }

  console.log(getDeviceState());

});
/*default */

.state-indicator {
  z-index: 0;
}
@media all and (max-width: 1200px) {
  /* start of small desktop */
  .state-indicator {
    z-index: 1;
  }
}
/* end of desktop styles */

@media screen and (max-width: 991px) {
  /* start of large tablet styles */
  .state-indicator {
    z-index: 2;
  }
}
@media screen and (max-width: 767px) {
  /* start of medium tablet styles */
  .state-indicator {
    z-index: 3;
  }
}
@media screen and (max-width: 479px) {
  /* start of phone styles */
  .state-indicator {
    z-index: 4;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Upvotes: 0

Views: 170

Answers (2)

charlietfl
charlietfl

Reputation: 171669

z-index only works on positioned elements, if you check what the actual value is it is auto and states[parseInt('auto')] is undefined

Css adjustment that fixes immediate issue:

.state-indicator {
  z-index: 0;
  position:relative;
}

Since you are using jQuery here's a slightly simpler version that also removes the element once the needed value is obtained

$(function() {      

    function getDeviceState() {        
        var $indicator = $('<div>', {'class': 'state-indicator'});
        $('body').append($indicator);

        var index = $indicator.css('z-index');
        // got the value, so remove the test element
        $indicator.remove();
        // technically js property names can not be numeric, and will get cast to string but not all browsers will
        var states = {
          '0': 'desktop',
          '1': 'small-desktop',
          '2': 'large-tablet',
          '3': 'medium-tablet',
          '4': 'phone'
        };

        return states[index];
      }

      console.log(getDeviceState());
});

DEMO

Upvotes: 2

Daniel
Daniel

Reputation: 631

The problem is z-indexwhich is auto can not be parsed to a number. The resolution of this code is to find NaN property of states object and the right answer is undefined.

So, right question is why does window.getComputedStyle(indicator).getPropertyValue('z-index') returns auto and how to make it works.

The main problem is to find right media-query resolution from whithin JS.

There is a lot of good example how to combine JS and media query work. Try this one:

http://theme.co/blog/cubit-a-more-flexible-media-query/

http://thenewcode.com/948/Triggering-JavaScript-Actions-With-CSS-Media-Queries

You can improve this code with ideas inside links I gave you.

Upvotes: 1

Related Questions