Подтвердить что ты не робот

Почему размер окна меньше ширины видового экрана, заданного в медиа-запросах

Я довольно озадачен и до сих пор не знаю, как это объяснить правильно. До сих пор я использовал и настраивал свои медиа-запросы с помощью Breakpoint. Используемая переменная Breakpoint выглядит, например:

$menustatictofixed: min-width 900px;

$breakpoint-to-ems установлено значение true. Я выложил страницу со всеми ее переменными Breakpoint на основе значений пикселей следующего фрагмента jQuery:

$('body').append('<div style="position: fixed; bottom: 0; right: 0; display: inline-block; font-weight: bold; padding: 5px 7px; border-radius: 5px 0 0 0; background: green; color: white; z-index: 9999;">Viewport width <span id="width"></span> px</div>');
var viewportWidth = $(window).width()
$('#width').text(viewportWidth);
$(window).resize(function() {
  var viewportWidth = $(window).width();
    $('#width').text(viewportWidth);
});

Все выглядело правильно и чисто. Но за последний один или два дня у меня были проблемы с настройкой последних точек останова для шаблона и для того, чтобы заставить вещи вести себя предсказуемыми. Каким-то образом вещи, которые, казалось, складывались в чистоту и в порядке, в первую очередь, я логически сильно сомневаюсь сейчас, на самом деле являются ненадлежащими и как-то беспорядочными. Если вы посмотрите на снимок экрана, то ширина окна (в Chrome) будет отличаться от ширины с помощью фрагмента jQuery, использующего окно. ширина. Также нет разницы, если бы я заменил window.width на window.innerWidth, чтобы в конечном итоге исключить полосы прокрутки. Единственный способ получить правильные результаты - добавить 15 пикселей к уравнению:

var viewportWidth = $(window).width() + 15;

Единственная проблема во всем уравнении, что window.width - это неправильный выбор функции, и было бы лучше пойти, например. document.documentElement.clientWidth или что-то еще или...? И для чего стоят 15 пикселей, для которых проблема была решена немного хакерским способом? С наилучшими пожеланиями Ральф

4b9b3361

Ответ 1

Ответ - это полосы прокрутки, и решение сложно.

Интересны медиа-запросы. Они не ведут себя точно так же в браузере, то есть использовать их иногда не так просто. Например, в -webkit/-blink для OS X и IE10 на Win8, полосы прокрутки накладываются на страницу. Однако в -moz полосы прокрутки не накладываются на страницу. Лучший способ получить "видимую область" страницы - это следующая строка ванильного JavaScript (при условии, что у вас есть допустимый HTML-документ):

document.body.parentNode.clientWidth

Что это будет делать, это найти элемент body, найти его parent (который в действительном документе будет элементом html), а затем найти его ширину после рендеринга. Это даст вам ширину, которую вы хотите видеть. Это также бесполезная ширина, чтобы иметь.

Почему вы можете спросить, имеет ли фактическая ширина клиента бесполезно? Это не потому, что оно варьируется от браузера к браузеру, потому что это так. Это потому, что не то, что на самом деле тестируют медиа-запросы width! Тестирование width media queries test window.innerWidth, которое вы сейчас используете.

Итак, каково решение этой проблемы? Ну, я бы сказал, что решение заключается в использовании медиа-запросов на основе контента, а не на медиа-запросах на основе устройств и в порядке с некоторыми местами для маневра в ваших запросах (особенно если это пространство для маневра составляет примерно 15px). Если вы еще этого не сделали, прочитайте статьи Vexing Viewports и A Pixel Identity Кризис, чтобы понять, почему потенциальное 15px мерцание в ваших определениях MQ - не самая худшая вещь в мире (вероятно, есть большая рыба, чтобы жарить).

Итак, в заключение продолжайте использовать $breakpoint-to-ems: true и выберите свои медиа-запросы на основе того, когда контент разбивается на window.innerWidth, поскольку он является единственным нормальным способом обработки проблем с несколькими браузерами. С беглым взглядом на различные проблемы кажется, что большинство браузеров и ОС перемещаются в оверлейную полосу прокрутки (от Firefox 24 каждый браузер OS X у него будет один, Ubuntu Unity UI представил их), поэтому, чтобы быть дружелюбным к будущему, я бы посоветовал не беспокоиться о смещении полосы прокрутки и быть в порядке с сайтами, выглядящими несколько разными в браузере. Помните, как Этан Маркот так красноречиво поставил:

Веб - это неустойчивый уровень

Ответ 2

Это то, что сработало для меня: CSS-запросы и ширина окна JavaScript не соответствуют.

Вместо использования $(window).width();, который включает в себя полосы прокрутки, получите внутреннюю ширину следующим образом:

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

var vpWidth = viewport().width; // This should match your media query

Ответ 3

IT из-за scrollbar's

Самое правильное решение, которое я нашел, - использовать медиа-запросы для передачи фактического размера окна в Javascript. Вы должны выполнить следующие действия:

  • Добавьте скрытый элемент на свою страницу,
  • Использование медиа-запросов для изменения свойства max-width этого элемента,
  • Считайте свойство max-width этого элемента через Javascript.

Например, добавьте на страницу следующий элемент:

<div id="currentMedia"></div>

Затем напишите следующие правила CSS:

#currentMedia {
    display: none;
}

@media (max-width: 720px) {
    // Make arrows in the carousel disappear...

    #currentMedia {
        max-width: 720px;
    }
}

Затем со стороны Javascript вы можете написать:

if (parseInt(jQuery("#currentMedia").css("max-width"), 10) <= 720) {
    // Code HERE..
}

И это будет точно, независимо от размера полосы прокрутки, поскольку значение происходит от того же медиа-запроса, который вызывает исчезновение карусели.

Я тестировал это решение во всех основных последних браузерах и дал правильные результаты.

Вы найдете большое резюме о том, какие свойства поддерживаются в браузерах на этой странице на quirksmode.org.

Лучше всего, чтобы захватить элемент на странице (используя document.body, где поддерживается, или document.getElementById или что-то еще), пройдите по цепочке offsetParent, чтобы найти самый верхний элемент, затем проверьте этот элемент clientWidth и clientHeight.

innerWidth документация

.innerWidth() метод не применим к объектам window и document; Для этого используйте .width().

Ответ 4

@Snugug answer дает действительно хорошее объяснение, почему это происходит, и @TusharGupta также имеет хорошее решение, которое ссылается на ширину распознаваемой медиатекста на javascript. Ниже решения идет наоборот, используя ширину, определяемую javascript, чтобы вызвать изменения компоновки.

Если вам нужно синхронизировать медиа-запросы с помощью определения ширины пикселя javascript, одним из способов приблизиться к проблеме является запуск изменений CSS-макета на основе классов, которые вы добавляете с помощью javascript.

Итак, вместо написания медиазаписей напишите те декларации, вложенные под класс, скажем:

html.myMobileBP { ... }

И в вашем javascript/jQuery добавьте этот класс:

if ($(window).width() < myMobileBPPixelSize) {
    $("html").addClass("myMobileBP");
}

Чтобы продвинуть это еще дальше, вам может потребоваться отсутствие поддержки javascript. Определите медиа файлы, которые, кроме того, завернуты в класс html.no-js, затем с помощью javascript удалите класс .no-js и примените указанное выше решение добавления точек останова через классы javascript.

Ответ 5

Подобно @Snugugs, но лучше работал для моего использования:

CSS (Примечание. Я использую LESS, поэтому @tabletMin и @desktopMin переводят на переменные точки останова, которые я установил в другом месте:

    #cssWidth {
        display:none;
        content:'mobile';
    }

    /* Responsive styles (Tablet) */
    @media (min-width: @tabletMin) {
        #cssWidth {
            content:'tablet';
        }
        /* Other tablet CSS... */
    }
    /* Responsive styles (Desktop) */
    @media (min-width: @desktopMin) {
        #cssWidth {
            content:'desktop';
        }
        /* Other Desktop CSS... */
    }

И затем в JS:

    getView = function() {
        // If #cssWidth element does not exist, create it and prepend it do body
        if ($('#cssWidth').length === 0) {
            $('body').prepend($(document.createElement('div')).attr('id', 'cssWidth'));
        }
        // Return the value of the elements 'content' property
        return $('#cssWidth').css('content');
    };

Функция getView() вернет строку "мобильный", "планшет" или "рабочий стол" в зависимости от ширины запросов к медиа файлам.

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

Ответ 6

перейдите по этой ссылке

function getWindowWidth() {
    var windowWidth = 0;
    if (typeof(window.innerWidth) == 'number') {
        windowWidth = window.innerWidth;
    }
    else {
        if (document.documentElement && document.documentElement.clientWidth) {
            windowWidth = document.documentElement.clientWidth;
        }
        else {
            if (document.body && document.body.clientWidth) {
                windowWidth = document.body.clientWidth;
            }
        }
    }
    return windowWidth;
}

Ответ 7

Используйте классы в теле, чтобы определить, используете ли вы на мобильных устройствах, планшетах или настольных компьютерах вместо пикселей.

Для меня это не сработало document.body.clientWidth или innerWidth. Моя функциональность падает между 1023-1040px, даже если мой js-код должен выполнить эту инструкцию:

if($(window).width()<1024)

Решение заключалось в том, чтобы надеть новый класс класса менее 1024 и назвать его "small-res" и использовать его, чем в моем коде вместо проверки пикселей:

if($(body).hasClass('small-res')) 

Я тоже рекомендую его вам.