CSS-медиа-запросы и ширина окна JavaScript не совпадают

Для адаптивного шаблона у меня есть медиа-запрос в моем CSS:

@media screen and (max-width: 960px) {
 body{
 /*  something */
 background:red;
 }
}

И я создал функцию jQuery при изменении размера для ширины журнала:

$(window).resize(function() {
 console.log($(window).width());
 console.log($(document).width()); /* same result */
 /* something for my js navigation */
}

И есть разница с обнаружением CSS и результатом JS, у меня есть эта мета:

<meta content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width" name="viewport"/> 

Я полагаю, это связано с полосой прокрутки (15 пикселей). Как я могу сделать это лучше?

Ответы

Ответ 1

Вы правы в полосе прокрутки, потому что CSS использует ширину устройства, но JS использует ширину документа.

Что вам нужно сделать, это измерить ширину видового экрана в вашем JS-коде вместо использования функции ширины jQuery.

Этот код от http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}

Ответ 2

Я нашел следующий код на http://www.w3schools.com/js/js_window.asp:

var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

Практически он работает так же, как ответ в ответ на @Michael Bird, но его легче читать.

Изменить: Я искал метод, который дает точно такую ​​же ширину, что и для медиа-запросов css. Извините, но предложенный не работает на Safari с прокруткой. Я закончил использование modernizr.js в одной центральной функции, а в остальной части кода я просто проверяю, является ли тип отображения мобильным, планшетом или рабочим столом. Поскольку меня не интересует ширина, это отлично работает для меня:

getDisplayType = function () {
  if (Modernizr.mq('(min-width: 768px)')){
    return 'desktop';
  }
  else if (Modernizr.mq('(min-width: 480px)')){
    return 'tablet'
  }
  return 'mobile';
};

Ответ 3

window.innerWidth - это то, что вам нужно.

if (window.innerWidth < 768) работает для точки прерывания 768 в CSS

Ответ 4

Мой опыт заключался в том, что ширина запроса на медиа-контент отслеживает document.body.clientWidth. Из-за вертикальной полосы прокрутки, идущей и идущей, проверка ширины документа, окна или видового экрана() может привести к тому, что мой Javascript запустится поздно - после изменения правила медиа-запроса в зависимости от высоты окна.

Проверка document.body.clientWidth позволяла моему коду script выполняться последовательно, в то время как правило медиа-запросов вступало в силу.

@media (min-width: 873px) {
      // некоторые правила
  }
...

if (document.body.clientWidth >= 873) {
       //некоторый код
  }

Код Энди Лангтона поставил меня на это - спасибо!

Ответ 5

Привет, я использую этот небольшой трюк, чтобы заставить JS и CSS работать вместе на быстро реагирующих страницах:

Проверьте видимость отображаемого элемента или нет в условии CSS @media size. Использование bootstrap CSS я проверяет видимость элемента класса hidden-xs

var msg = "a message for U";

/* At window load check initial size  */
if ( $('#test-xsmall').is(':hidden')  ) {
  /* This is a CSS Xsmall situation ! */
  msg = "@media CSS < 768px. JS width = " + $(window).width() + " red ! ";
  $('.redthing-on-xsmall').addClass('redthing').html(msg);

} else {
  /* > 768px according to CSS  */
  msg = "@media CSS > 767px. JS width = " + $(window).width() + " not red ! ";
  $('.redthing-on-xsmall').removeClass('redthing').html(msg);
}


/* And again when window resize  */

$(window).on('resize', function() {
  if ($('#test-xsmall').is(':hidden')) {
    msg = "@media CSS < 768px. JS width = " + $(window).width() + " red ! ";
    $('.redthing-on-xsmall').addClass('redthing').html(msg);
  } else {
    msg = "@media CSS > 767px. JS width = " + $(window).width() + " not red ! ";
    $('.redthing-on-xsmall').removeClass('redthing').html(msg);
  }
});
@media (min-width: 768px) {
  .hidden-xs {
    display: block !important;
  }
}
@media (max-width: 767px) {
  .hidden-xs {
    display: none !important;
  }
}
.redthing-on-xsmall {
  /* need a scrollbar to show window width diff between JS and css */
  min-height: 1500px;
}
.redthing {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- the CSS managed Element that is tested by JS --> 
<!-- class hidden-xs hides on xsmall screens (bootstrap) -->

<span id="test-xsmall" class="hidden-xs">THIS ELEMENT IS MANAGED BY CSS  HIDDEN on @media lower than 767px</span>


<!-- the responsive element managed by Jquery  -->
<div class="redthing-on-xsmall">THIS ELEMENT IS MANAGED BY JQUERY RED on @media max width 767px </div>

Ответ 6

Обходной путь, который всегда работает и синхронизируется с запросами мультимедиа CSS.

Добавить div в тело

<body>
    ...
    <div class='check-media'></div>
    ...
</body>

Добавьте стиль и измените их, введя конкретный мультимедийный запрос

.check-media{
    display:none;
    width:0;
}
@media screen and (max-width: 768px) {
    .check-media{
         width:768px;
    }
    ...
}

Затем в стиле проверки JS, который вы меняете, введя запрос на медиа

if($('.check-media').width() == 768){
    console.log('You are in (max-width: 768px)');
}else{
    console.log('You are out of (max-width: 768px)');
}

Как правило, вы можете проверить любой стиль, который изменяется, введя конкретный мультимедийный запрос.

Ответ 7

Ссылочный запрос Css равен window.innerWidth. Css Media Запросы также вычисляют полосу прокрутки.