2013-08-31 48 views
23

Tôi khá bối rối và vẫn không chắc chắn cách giải thích điều này bằng các từ thích hợp. Cho đến nay tôi đã sử dụng và thiết lập các truy vấn phương tiện với Breakpoint. Biến Breakpoint được sử dụng trông giống như ví dụ:Tại sao window.width nhỏ hơn chiều rộng khung nhìn được đặt trong các truy vấn phương tiện

$menustatictofixed: min-width 900px; 

$ breakpoint-to-ems được đặt thành true. Tôi đã đặt ra trang với tất cả các biến Breakpoint của nó dựa trên các giá trị điểm ảnh của đoạn jQuery sau:

$('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); 
}); 

Mọi thứ trông đúng đắn và sạch sẽ. Nhưng trong một hoặc hai ngày qua tôi đã có vấn đề thiết lập các điểm ngắt cuối cùng cho một mẫu và để có được những thứ có thể dự đoán được. Bằng cách nào đó những thứ xuất hiện để thêm vào sạch sẽ và tốt ở nơi đầu tiên, mà tôi rất nghi ngờ về mặt logic bây giờ, là trong thực tế không đúng cách và bằng cách nào đó một mớ hỗn độn. Cuz nếu bạn nhìn vào screenshot sau đây bằng cách nào đó chiều rộng của cửa sổ (trong Chrome) khác với chiều rộng từ đoạn mã jQuery sử dụng window.width. Cũng không có sự khác biệt nếu tôi thay thế window.width bằng window.innerWidth để loại bỏ thanh cuộn cuối cùng. Cách duy nhất để nhận được kết quả thích hợp là bằng cách thêm 15 pixel để phương trình:

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

là vấn đề duy nhất trong toàn bộ phương trình mà window.width là sự lựa chọn sai chức năng và nó sẽ là tốt hơn để đi với ví dụ document.documentElement.clientWidth hoặc cái gì khác hoặc ...? Và đối với những gì 15 pixel đang đứng mà cố định vấn đề ở trên trong một cách hacky bit? Trân trọng Ralf

+0

Có thể vì thanh cuộn ở bên phải/không? –

Trả lời

24

Câu trả lời là thanh cuộn và giải pháp là khó khăn.

Truy vấn phương tiện truyền thông thú vị. Chúng không hoạt động giống hệt nhau trên trình duyệt, có nghĩa là việc sử dụng chúng đôi khi không thể dễ dàng như vậy. Ví dụ, trong -webkit/-blink trên OS X và IE10 trên Win8, các thanh cuộn được phủ lên trang. Tuy nhiên, trong -moz, các thanh cuộn là không phải được phủ lên trang. Cách tốt nhất để có được những "inch" của trang là dòng sau của vanilla JavaScript (giả sử bạn có một tài liệu HTML hợp lệ):

document.body.parentNode.clientWidth 

Điều này sẽ làm là tìm ra nguyên tố body, thấy nó là cha mẹ (trong tài liệu hợp lệ sẽ là phần tử html), và sau đó tìm chiều rộng sau khi kết xuất. Điều này sẽ cung cấp cho bạn chiều rộng mà bạn muốn xem. Đó cũng là chiều rộng vô dụng để có.

Tại sao, bạn có thể hỏi, có chiều rộng khách hàng thực sự vô dụng không? Nó không phải vì nó thay đổi từ trình duyệt đến trình duyệt, bởi vì nó. Đó là bởi vì đó không phải là những gì các truy vấn phương tiện width thực sự đang thử nghiệm! Bài kiểm tra phương tiện width truy vấn phương tiện truyền thông window.innerWidth, đó là những gì bạn đang thực chất sử dụng ngay bây giờ.

Vậy giải pháp cho vấn đề này là gì? Tôi muốn nói giải pháp là sử dụng truy vấn phương tiện dựa trên nội dung thay vì truy vấn phương tiện dựa trên thiết bị và được OK với một số phòng lung lay trong truy vấn của bạn (đặc biệt là nếu căn phòng lung lay đó xấp xỉ 15px). Nếu bạn chưa đọc, hãy đọc các bài viết Vexing ViewportsA Pixel Identity Crisis để biết được lý do tại sao một ánh sáng lung linh 15px tiềm năng trong định nghĩa MQ của bạn không phải là điều tồi tệ nhất trên thế giới (có thể là cá lớn hơn để chiên).

Vì vậy, trong kết luận tiếp tục sử dụng $breakpoint-to-ems: true và chọn truy vấn phương tiện của bạn dựa trên thời điểm nội dung ngắt thành window.innerWidth vì đó là cách duy nhất để xử lý các vấn đề liên quan đến trình duyệt. Từ một cái nhìn lướt qua các vấn đề khác nhau, có vẻ như hầu hết các trình duyệt và hệ điều hành đang di chuyển đến một thanh cuộn lớp phủ (như Firefox 24 mọi trình duyệt OS X sẽ có một, Giao diện người dùng thống nhất của Ubuntu introduced them), vì vậy trong tương lai, tôi 'd đề nghị không đáng lo ngại về thanh cuộn bù đắp và được OK với các trang web tìm kiếm hơi khác nhau trên trình duyệt. Hãy nhớ rằng, như Ethan Marcotte rất hùng hồn đưa:

Web là một trung Bẩm ổn định

+0

cảm ơn rất nhiều vì lời giải thích sâu rộng cũng như cho hai lần đọc tiếp. Việc đầu tiên tôi đã biết nhưng lần thứ hai về cuộc khủng hoảng nhận dạng pixel không. Cả hai đều đọc tốt. Cảm ơn! Bên cạnh đó tôi đã trao đổi $ (window) .width() từ ví dụ của tôi ở trên với (window) .innerWidth(). Và quá trình bạn đã đề xuất cuối cùng chính là cách tôi muốn và đã xử lý mọi thứ. Phần thứ hai trong phần bình luận tiếp theo. – rpk

+0

Bây giờ tôi có một điểm ngắt nơi nav của tôi chuyển từ menu chuyển đổi sang hiển thị nội tuyến. Trong Breakpoint tôi đã đặt 900px nhưng tiện ích cho thấy rằng sự cố xảy ra đã ở 885px. Bây giờ tôi thay đổi điểm ngắt thành 885px dựa trên giá trị innerWidth. Sau đó, nav phá vỡ ở 870px. Quá trình đó có thể cứ tiếp tục và kéo dài. Điều này trái ngược với kịch bản được đề xuất của bạn nơi window.innerWidth và biến breakpoint phải bằng nhau. Tôi chỉ có thể bỏ qua nó nếu tôi làm như sau $ (cửa sổ) .innerWidth() + 15; . Sau đó window.innerWidth và break cụ thể là giống hệt nhau. :/ – rpk

+0

Bạn đang sử dụng trình duyệt và hệ điều hành nào? Bạn đã kiểm tra CSS đầu ra của mình để đảm bảo các truy vấn phương tiện đang được in là những truy vấn bạn mong đợi? – Snugug

5

là CNTT vì sự scrollbar's

Các giải pháp đúng nhất mà tôi tìm thấy là sử dụng các truy vấn phương tiện truyền thông để vượt qua kích thước cửa sổ thực tế để Javascript. Bạn cần phải làm theo các bước sau:

  • Thêm một yếu tố ẩn vào trang của bạn,
  • Sử dụng truy vấn phương tiện để thay đổi max-width tài sản của yếu tố đó,
  • đọc lại max-width tài sản của yếu tố đó thông qua Javascript.

Ví dụ, thêm các yếu tố sau đây vào trang của bạn:

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

Sau đó viết các quy tắc CSS sau:

#currentMedia { 
    display: none; 
} 

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

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

Sau đó, từ phía Javascript, bạn có thể viết:

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

Và nó sẽ chính xác bất kể sc kích thước thanh cuộn, vì giá trị đến từ cùng một truy vấn phương tiện kích hoạt sự biến mất của băng chuyền.

Tôi đã thử nghiệm giải pháp này trên tất cả các trình duyệt chính gần đây và cung cấp kết quả chính xác.

Bạn sẽ tìm thấy bản tóm tắt lớn về những thuộc tính nào được hỗ trợ trên trình duyệt nào on this page on quirksmode.org.

Đặt cược tốt nhất của bạn có lẽ là lấy một phần tử trong trang (sử dụng document.body ở nơi được hỗ trợ hoặc tài liệu.getElementById hoặc bất kỳ thứ gì), hãy đi bộ chuỗi offsetParent của nó để tìm phần tử trên cùng, sau đó kiểm tra clientWidth và clientHeight của phần tử đó.

innerWidth tài liệu

.innerWidth() phương pháp là không áp dụng đối với windowdocument đối tượng; thay vào đó, hãy sử dụng .width().

+1

Đây là một câu trả lời tuyệt vời và sẽ hoạt động với nhiều quy tắc kích thước như bạn cảm thấy muốn áp dụng cho nó. Không chắc chắn tại sao điều này không được xếp hạng cao hơn. –

43

Đây là những gì làm việc cho tôi: CSS media queries and JavaScript window width do not match.

Thay vì sử dụng $(window).width(); trong đó bao gồm thanh cuộn có chiều rộng bên trong như thế này:

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 
0

câu trả lời @Snugug 's đưa ra một lời giải thích thực sự tốt là tại sao điều này xảy ra, và @TusharGupta có một giải pháp tốt cũng tham chiếu đến chiều rộng được phát hiện mediaquery tới javascript. Giải pháp dưới đây đi theo cách khác xung quanh bằng cách sử dụng javascript phát hiện chiều rộng để kích hoạt thay đổi bố trí.

Trong trường hợp bạn cần đồng bộ hóa mediaqueries với phát hiện chiều rộng pixel javascript, một cách tiếp cận vấn đề là kích hoạt thay đổi bố cục css dựa trên các lớp bạn thêm bằng javascript.

Vì vậy, thay vì viết mediaqueries, hãy viết những tờ khai lồng nhau dưới một lớp học, nói:

html.myMobileBP { ... } 

Và trong javascript của bạn/jQuery, thêm lớp này như:

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

Để lái xe này hơn nữa, bạn có thể muốn xem xét việc thiếu hỗ trợ javascript. Xác định mediaqueries được thêm vào trong một lớp html.no-js, sau đó với javascript loại bỏ lớp .no-js và áp dụng giải pháp trên để thêm điểm ngắt thông qua các lớp javascript.

1

Tương tự như @ câu trả lời của Snugugs nhưng làm việc tốt hơn đối với trường hợp sử dụng của tôi:

CSS (Lưu ý Tôi đang sử dụng LESS để @tabletMin và @desktopMin dịch để breakpoint biến tôi đã thiết lập ở nơi khác:

#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... */ 
    } 

Và sau đó trong 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'); 
    }; 

các getView() chức năng sau đó sẽ trả về chuỗi 'di động', 'tablet' hoặc 'máy tính để bàn 'phụ thuộc vào chiều rộng truy vấn phương tiện phương tiện truyền thông xem.

Điều này có thể được mở rộng để phù hợp với nhiều chiều rộng khung nhìn hơn, chỉ cần thêm các quy tắc khác trong CSS với các giá trị khác.

0

follow this link

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

Sử dụng các lớp học trên cơ thể để xác định nếu bạn đang ở trên điện thoại di động, tablet hay máy tính để bàn thay vì sử dụng pixel.

Đối với tôi, nó không hoạt động document.body.clientWidth hoặc innerWidth. treo chức năng My giữa 1023-1040px thậm chí nếu mã js tôi phải làm tuyên bố này:

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

Giải pháp là để đưa vào cơ thể một lớp học mới cho ít hơn 1024 và đặt tên là "nhỏ-res" và sử dụng nó trong mã của tôi thay vì xác minh pixel:

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

Tôi cũng khuyên bạn nên sử dụng nó.

Các vấn đề liên quan