$(window).width()与媒体查询不一样
我在一个项目上使用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
是要走的路。 但理想情况下,我想find一个解决scheme,计算滚动条的宽度,这是符合我的媒体查询(例如,两个条件检查值767)。 因为肯定不是所有的浏览器将有一个16px的滚动条宽度?
如果你不需要支持IE9,你可以使用window.matchMedia()
( MDN文档 )。
function checkPosition() { if (window.matchMedia('(max-width: 767px)').matches) { //... } else { //... } }
window.matchMedia
与CSS媒体查询完全一致,浏览器支持相当不错: http : //caniuse.com/#feat=matchmedia
更新:
如果你必须支持更多的浏览器,你可以使用Modernizr的mq方法 ,它支持所有理解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' ] }; }
以上代码来源
是的,这是由于滚动条。 正确答案来源: 在这里input链接描述
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查询所做的某种改变。 用这个方法你可以确定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"); ... });
使用
window.innerWidth
这解决了我的问题
我最近也面临同样的问题 – 也是Bootstrap 3。
$ .width()和$ .innerWidth()都不会为你工作。
我想出了最好的解决scheme – 专门为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元素。 您可以将任何string或数字添加到伪元素的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指出:
Window.outerWidth获取浏览器窗口外部的宽度。 它代表整个浏览器窗口的宽度,包括边栏(如果展开),窗口镶边和窗口大小的边框/句柄。
javascript的状态是这样的,每个平台上的每个浏览器都不能依赖于outerWidth的具体含义。
旧版移动浏览器不支持 outerWidth
,尽pipe它支持主要桌面浏览器和大多数新型智能手机浏览器。
正如ausi所指出的, matchMedia
将是一个很好的select,因为CSS更好地标准化(matchMedia使用JS来读取CSS检测到的视口值)。 但是,即使在公认的标准下,浏览器仍然存在,忽略它们(在这种情况下,IE <10,这使得匹配媒体不是非常有用,至less在XP死亡之前)。
总之 ,如果你只是开发桌面浏览器和更新的移动浏览器,outerWidth应该给你你正在寻找的,有一些注意事项 。
这是处理媒体查询的一个较less涉及的技巧。 跨浏览器支持是有点限制,因为它不支持移动IE。
if (window.matchMedia('(max-width: 694px)').matches) { //do desired changes }
请参阅Mozilla文档以获取更多细节。
解决方法始终有效,并与CSS媒体查询同步。
添加一个div到正文
<body> ... <div class='check-media'></div> ... </body>
添加样式并通过input特定媒体查询来更改它们
.check-media{ display:none; width:0; } @media screen and (max-width: 768px) { .check-media{ width:768px; } ... }
然后在JS检查你正在改变的风格,进入媒体查询
if($('.check-media').width() == 768){ console.log('You are in (max-width: 768px)'); }else{ console.log('You are out of (max-width: 768px)'); }
因此,通常您可以通过进入特定的媒体查询来检查正在更改的任何样式。
最好的跨浏览器解决scheme是使用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。
实现光滑的滑块,并根据分辨率(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 }
更多参考请点击这里