Почему размер 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 пикселей к уравнению:
- jQuery модальный диалог и jqGrid
- как удалить только одно свойство стиля с помощью jquery
- Как предотвратить прыжок на якорный щелчок?
- JSON: Как сделать междоменный вызов JSON
- jQuery, если div содержит этот текст, замените ту часть текста
var viewportWidth = $(window).width() + 15;
Единственная проблема во всем уравнении, что window.width является неправильным выбором функции, и было бы лучше пойти, например, document.documentElement.clientWidth или что-то еще или …? И для чего стоят 15 пикселей, для которых проблема была решена немного хакерским способом? С наилучшими пожеланиями Ральф
- Загрузка не выполняется, когда пользователь перетаскивает и удаляет вложение с почтового клиента
- Селекторы jQuery с переменными
- Как отлаживать привязки событий JavaScript / jQuery к Firebug или аналогичным инструментам?
- изменение источника iframe с помощью jquery
- Подстановочные знаки в селекторах jQuery
- Простой jQuery Ajax вызывает утечку памяти в Internet Explorer
- JQGrid: Как обновить выпадающий список после редактирования?
- Получение курсора браузера от «wait» до «auto» без перемещения пользователем мыши
Ответ – полоса прокрутки, и решение сложно.
Интересны медиа-запросы. Они не ведут себя точно так же в браузере, то есть использовать их иногда не так просто. Например, в -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'))
Я тоже рекомендую его вам.