$(окно.)width () не совпадает с запросом media

Я использую Twitter Bootstrap в проекте. А также Стили начальной загрузки по умолчанию, которые я также добавил некоторые из моих собственных

//My styles
@media (max-width: 767px)
{
    //CSS here
}

Я также использую jQuery для изменения порядка определенных элементов на странице, когда ширина окна просмотра меньше 767px.

$(document).load($(window).bind("resize", checkPosition));

function checkPosition()
{
    if($(window).width() < 767)
    {
        $("#body-container .main-content").remove().insertBefore($("#body-container .left-sidebar"));
    } else {
        $("#body-container .main-content").remove().insertAfter($("#body-container .left-sidebar"));
    }
}

проблема, с которой я сталкиваюсь, заключается в том, что ширина, рассчитанная $(window).width() и ширина, вычисленная CSS, не кажется одинаковой. Когда $(window).width() возвращает 767 css вычисляет его ширина просмотра 751 так кажется 16px и разных.

кто-нибудь знает, что вызывает это и как я могу решить проблему? Люди предположили, что ширина полосы прокрутки не принимается во внимание и использовать $(window).innerWidth() < 751 - это путь. Однако в идеале я хочу найти решение, которое вычисляет ширину полосы прокрутки и которое согласуется с моим медиа-запросом (e.g где оба условия сверяются со значением 767). Ведь наверняка не все браузеры будут иметь ширину полосы прокрутки 16px?

14 ответов


Если вам не нужно поддерживать IE9, вы можете просто использовать window.matchMedia() (документация MDN).

function checkPosition() {
    if (window.matchMedia('(max-width: 767px)').matches) {
        //...
    } else {
        //...
    }
}

window.matchMedia полностью соответствует запросам css media, и поддержка браузера довольно хороша:http://caniuse.com/#feat=matchmedia

обновление:

Если вам нужно поддерживать больше браузеров, вы можете использовать Modernizr это МQ, Она поддерживает все браузеры, которые понимают медиа-запросы в CSS.

if (Modernizr.mq('(max-width: 767px)')) {
    //...
} else {
    //...
}

Проверьте правило CSS, которое изменяется медиа-запрос. Это гарантированно всегда работает.

http://www.fourfront.us/blog/jquery-window-width-and-media-queries

HTML-код:

<body>
    ...
    <div id="mobile-indicator"></div>
</body>

Javascript:

function isMobileWidth() {
    return $('#mobile-indicator').is(':visible');
}

CSS:

#mobile-indicator {
    display: none;
}

@media (max-width: 767px) {
    #mobile-indicator {
        display: block;
    }
}

это может быть из-за scrollbar используйте innerWidth вместо width как

if($(window).innerWidth() <= 751) {
   $("#body-container .main-content").remove()
                                .insertBefore($("#body-container .left-sidebar"));
} else {
   $("#body-container .main-content").remove()
                                .insertAfter($("#body-container .left-sidebar"));
}

также вы можете получить viewport как

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' ] };
}

выше код источник


да, это связано с полосой прокрутки. Правильный ответ источник: Введите описание ссылки здесь

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' ] };
}

возможно, лучше не использовать JS-область ширины документа, но какое-то изменение, сделанное css @media query. С помощью этого метода вы можете быть уверены, что функция JQuery и изменение css происходят одновременно.

css:

#isthin {
    display: inline-block;
    content: '';
    width: 1px;
    height: 1px;
    overflow: hidden;
}

@media only screen and (max-width: 990px) {
    #isthin {
        display: none;
    }
}

jquery:

$(window).ready(function(){
    isntMobile = $('#isthin').is(":visible");
    ...
});

$(window).resize(function(){
    isntMobile = $('#isthin').is(":visible");
    ...
});

недавно я столкнулся с той же проблемой - также с Bootstrap 3.

ни $.width () nor $.innerWidth() будет работать на вас.

лучшее решение, которое я придумал - и специально адаптировано к BS3 -
это проверьте ширину .container элемент.

как вы, вероятно, знаете, как .container элемент работает,
это единственный элемент, который даст вам текущую ширину, установленную BS css правила.

Итак, это что-то вроде

bsContainerWidth = $("body").find('.container').width()
if (bsContainerWidth <= 768)
    console.log("mobile");
else if (bsContainerWidth <= 950)
    console.log("small");
else if (bsContainerWidth <= 1170)
    console.log("medium");
else
    console.log("large");

использовать


вот альтернатива методам, упомянутым ранее, которые полагаются на изменение чего-то через CSS и чтение его через Javascript. Этот метод не нуждается window.matchMedia или Modernizr. Ему также не нужен дополнительный HTML-элемент. Он работает с помощью псевдо-элемента HTML для "хранения" информации о точке останова:

body:after {
  visibility: hidden;
  height: 0;
  font-size: 0;
}

@media (min-width: 20em) {
  body:after {
    content: "mobile";
  }
}

@media (min-width: 48em) {
  body:after {
    content: "tablet";
  }
}

@media (min-width: 64em) {
  body:after {
    content: "desktop";
  }
}

Я body в качестве примера для этого можно использовать любой HTML-элемент. Вы можете добавить любую строку или число, которое вы хотите в content псевдо-элемент. Не должно быть "мобильный" и так далее.

теперь мы можем прочитать эту информацию из Javascript следующим образом:

var breakpoint = window.getComputedStyle(document.querySelector('body'), ':after').getPropertyValue('content').replace(/"/g,'');

if (breakpoint === 'mobile') {
    doSomething();
}

таким образом, мы всегда уверены, что информация о точке останова верна, так как она поступает непосредственно из CSS, и нам не нужно хлопотать с получением правильной ширины экрана через Javascript.


Javascript предоставляет более одного метода для проверки ширины окна просмотра. Как вы заметили, innerWidth не включает ширину панели инструментов, а ширина панели инструментов будет отличаться в разных системах. Существует также outerWidth опция, которая будет включать ширину панели инструментов. The Mozilla Javascript API гласит:


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

     if (window.matchMedia('(max-width: 694px)').matches)
    {
        //do desired changes
    }

посмотреть документация Mozilla для получения более подробной информации.


обходной путь, который всегда работает и синхронизируется с медиа-запросами 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 проверьте стиль, который вы меняете, введя в media query

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

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


лучшее кросс-браузерное решение-использовать Modernizr.mq

ссылки: https://modernizr.com/docs/#mq

модернизация.mq позволяет программно проверить, соответствует ли текущее состояние окна браузера медиа-запросу.

var query = Modernizr.mq('(min-width: 900px)');
if (query) {
   // the browser window is larger than 900px
}

Примечание браузер не поддерживает медиа-запросы (например, старый IE) mq всегда будет возвращать false.


реализация слайдера slick и отображение различного количества слайдов в блоке в зависимости от разрешения (jQuery)

   if(window.matchMedia('(max-width: 768px)').matches) {
      $('.view-id-hot_products .view-content').slick({
        infinite: true,
        slidesToShow: 3,
        slidesToScroll: 3,
        dots: true,
      });
    }

    if(window.matchMedia('(max-width: 1024px)').matches) {
      $('.view-id-hot_products .view-content').slick({
        infinite: true,
        slidesToShow: 4,
        slidesToScroll: 4,
        dots: true,
      });
    }

попробуй такое

if (document.documentElement.clientWidth < 767) {
   // scripts
}

для получения дополнительной информации нажмите кнопку здесь