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

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

$menustatictofixed: min-width 900px; 

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

 $('body').append('
Viewport width px
'); var viewportWidth = $(window).width() $('#width').text(viewportWidth); $(window).resize(function() { var viewportWidth = $(window).width(); $('#width').text(viewportWidth); });

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

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

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

Ответ – полоса прокрутки, и решение сложно.

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

 document.body.parentNode.clientWidth 

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

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

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

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

Интернет – это нестабильная среда

Это то, что сработало для меня: CSS-медиа-запросы и ширина windows 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 

Это из-за scrollbar's

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

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

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

 

Затем напишите следующие правила 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() не применим к объектам window и document ; для них вместо этого используйте .width() .

Подобно ответу @ 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 с другими значениями.

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

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

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

 html.myMobileBP { ... } 

И в javascript / jQuery добавьте этот class:

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

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

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

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

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

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

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

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

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

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

  • jQuery получить значение выбранного переключателя
  • Twitter Bootstrap - вкладки - URL-адрес не изменяется
  • Неудача успеха Параметр в jQuery.ajax?
  • Анимация scrollTop не работает в firefox
  • Как связать всплывающие подсказки Twitter Bootstrap с динамически создаваемыми элементами?
  • addClass каждый n-й
  • Простой скрипт проверки формы jQuery
  • Передайте массив в ajax-запрос в $ .ajax ()
  • jQuery Validate - требует, по крайней мере, одного поля в заполняемой группе
  • Значение времени ожидания по умолчанию для jQuery ajax
  • Привязать событие к щелчку правой кнопкой мыши
  • Давайте будем гением компьютера.