$(окно.)ширина() не совпадает с запросом мультимедиа


Я использую 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 - это путь. Однако в идеале я хочу найти решение, которое вычисляет ширину полосы прокрутки и которое согласуется с моим медиа-запросом (например, где оба условия проверяют значение 767). Потому что наверняка не все браузеры будут иметь ширину полосы прокрутки 16px?

14 160

14 ответов:

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

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

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

обновление:

Если вам нужно поддерживать больше браузеров, вы можете использовать метод MQ Modernizr, Она поддерживает все браузеры, которые понимают медиа-запросы в 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.

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

лучшее решение, которое я придумал - и специально адаптирован к BS3 -
это к проверьте ширину a .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 опция, которая будет включать в себя ширину панели инструментов. Элемент Mozilla Javascript API гласит:

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

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

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

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

добавить 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

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

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

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

реализация slick slider и отображение различного количества слайдов в блоке в зависимости от разрешения (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
}

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