Làm thế nào để có được kích thước khung nhìn trình duyệt?


789

Tôi muốn cung cấp cho khách truy cập của mình khả năng xem hình ảnh với chất lượng cao, có cách nào để tôi có thể phát hiện kích thước cửa sổ không?

Hoặc tốt hơn, kích thước khung nhìn của trình duyệt với JavaScript? Xem khu vực xanh ở đây:


10
Những gì tôi làm là, đặt một phần tử thường là html thành 100% chiều cao và lấy chiều cao của nó. Công việc đơn giản ở mọi nơi.
Muhammad Umer

1
@MuhammadUmer bắt tốt! Nếu bạn cảm thấy thất vọng khi lấy kích thước (và bạn sẽ, trên điện thoại di động không có jQuery), bạn có thể getComputedStylemở rộng htmlthẻ.
Dan

Ngoài ra, bạn có thể sử dụng thư viện W , nơi xử lý phát hiện chế độ xem đa trình duyệt;)
pyrsmk

Câu trả lời:


1328

Trình duyệt chéo @media (width)@media (height)các giá trị 

const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);

window.innerWidth.innerHeight

  • có được khung nhìn CSS @media (width)@media (height)bao gồm các thanh cuộn
  • initial-scalecác biến thể thu phóng có thể khiến các giá trị di động thu nhỏ sai thành PPK gọi là khung nhìn trực quan và nhỏ hơn các @mediagiá trị
  • thu phóng có thể khiến các giá trị bị tắt 1px do làm tròn tự nhiên
  • undefined trong IE8-

document.documentElement.clientWidth.clientHeight

Tài nguyên


4
@ 01100001 Thay thế $bằng verge. Nếu bạn muốn tích hợp vào jQuery thì hãy làm jQuery.extend(verge). Xem: verge.airve.com/#static
ryanve

4
Chỉ muốn đề cập rằng trong IE8 (và có lẽ những người khác), bạn phải có <!DOCTYPE html>phần đầu trang để mã hoạt động.
Tzury Bar Yochay

6
Tôi không hài lòng với clientWidth / Chiều cao trên thiết bị di động, thực sự là tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

24
Trừ khi tôi thiếu một cái gì đó, câu trả lời này là sai. Trong Chrome, ít nhất, document.documentElement.clientHeighttrả về chiều cao trang , trong khi window.innerHeighttrả về chiều cao của chế độ xem . Sự khác biệt lớn.
Nate

2
kiểm tra trực tiếp các biến / kích thước màn hình khác nhau: ryanve.com/lab/dimensions
Alex Pandrea

106

Hàm thứ nguyên jQuery

$(window).width()$(window).height()


60
@allyourcode, không thể, jQuery là câu trả lời cho tất cả .
Xeoncross

21
Điều này không có kích thước khung nhìn, nhưng kích thước tài liệu tổng thể. Thử nó.
Alejandro García Iglesias

2
Đối với các trình duyệt hiển thị thanh công cụ bổ trợ của họ dưới dạng HTML với chức năng gửi bài cố định, giải pháp này không hoạt động, đặc biệt nếu bạn muốn sử dụng trong vị trí và tỷ lệ phần trăm hàng đầu mã của mình.
Adib Aroui

7
@AlejandroIglesias: Không, tôi vừa thử nó trên trang SO này. $(window).height();trả về 536, trong khi $("html").height();trả về 10599
Flimm

2
Cảnh báo các kích thước này không bao gồm các thanh cuộn (có kích thước khác nhau trong các trình duyệt và nền tảng khác nhau) và do đó chúng sẽ không khớp với các truy vấn phương tiện css mà các câu trả lời khác ở đây không giải quyết được vấn đề này.
Spencer O'Reilly

75

Bạn có thể sử dụng window.innerWidthwindow.innerHeight tài sản.

bên trongHeight vs bên ngoài


29
Mặc dù điều này không hoạt động trong IE +1 cho sơ đồ: D. Đối với một câu hỏi như thế này, đó là một tội ác không có nhiều trong số này.
mã allyour

8
@CMS document.documentElement.clientWidthchính xác hơn và được hỗ trợ rộng rãi hơnwindow.innerWidth
ryanve

6
@ryanve Nếu "chính xác hơn", bạn có nghĩa là "thậm chí không làm điều tương tự từ xa" thì có: P
đóng hộp

Firefox Beta? Đó là thứ thuộc về bảo tàng.
Derek 朕 會

@boxed Trong Safari di động, document.documentElement.clientWidthcung cấp cho tôi chiều rộng khung nhìn trong khi window.innerWidth cho tôi chiều rộng tài liệu. Vâng, theo cách đó.
John

33

Nếu bạn không sử dụng jQuery, nó sẽ rất tệ. Đây là một đoạn nên hoạt động trên tất cả các trình duyệt mới. Hành vi là khác nhau trong chế độ Quirks và chế độ tiêu chuẩn trong IE. Điều này chăm sóc nó.

var elem = (document.compatMode === "CSS1Compat") ? 
    document.documentElement :
    document.body;

var height = elem.clientHeight;
var width = elem.clientWidth;

8
Điều này không cung cấp cho bạn chiều cao của trang chứ không phải chế độ xem? Đó là những gì trang này dường như chỉ ra: developer.mozilla.org/en/DOM/element.clientHeight
allyourcode

4
Bạn đang sử dụng clientHeighttrên document.documentElementphần tử, sẽ cung cấp cho bạn kích thước khung nhìn. Để có được kích thước tài liệu, bạn sẽ cần phải làm document.body.clientHeight. Như Chetan giải thích, hành vi này áp dụng cho các trình duyệt hiện đại. Nó rất dễ dàng để kiểm tra. Chỉ cần mở một giao diện điều khiển và gõ document.documentElement.clientHeightvào một số tab đang mở.
Gajus

13

Tôi biết điều này có một câu trả lời chấp nhận được, nhưng tôi đã gặp phải tình huống clientWidthkhông hoạt động, vì iPhone (ít nhất là của tôi) đã trả về 980, chứ không phải 320, vì vậy tôi đã sử dụng window.screen.width. Tôi đã làm việc trên trang web hiện tại, được thực hiện "đáp ứng" và cần buộc các trình duyệt lớn hơn sử dụng chế độ xem meta khác nhau.

Hy vọng điều này sẽ giúp được ai đó, nó có thể không hoàn hảo, nhưng nó hoạt động trong thử nghiệm của tôi trên iOs và Android.

//sweet hack to set meta viewport for desktop sites squeezing down to mobile that are big and have a fixed width 
  //first see if they have window.screen.width avail
  (function() {
    if (window.screen.width)
    {
      var setViewport = {
        //smaller devices
        phone: 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no',
        //bigger ones, be sure to set width to the needed and likely hardcoded width of your site at large breakpoints  
        other: 'width=1045,user-scalable=yes',
        //current browser width
        widthDevice: window.screen.width,
        //your css breakpoint for mobile, etc. non-mobile first
        widthMin: 560,
        //add the tag based on above vars and environment 
        setMeta: function () {
          var params = (this.widthDevice <= this.widthMin) ? this.phone : this.other; 
          var head = document.getElementsByTagName("head")[0];
          var viewport = document.createElement('meta');
          viewport.setAttribute('name','viewport');
          viewport.setAttribute('content',params);
          head.appendChild(viewport);
        }
      }
      //call it 
      setViewport.setMeta();
    }
  }).call(this);

13

Tôi đã xem và tìm thấy một cách trình duyệt chéo:

function myFunction(){
  if(window.innerWidth !== undefined && window.innerHeight !== undefined) { 
    var w = window.innerWidth;
    var h = window.innerHeight;
  } else {  
    var w = document.documentElement.clientWidth;
    var h = document.documentElement.clientHeight;
  }
  var txt = "Page size: width=" + w + ", height=" + h;
  document.getElementById("demo").innerHTML = txt;
}
<!DOCTYPE html>
<html>
  <body onresize="myFunction()" onload="myFunction()">
   <p>
    Try to resize the page.
   </p>
   <p id="demo">
    &nbsp;
   </p>
  </body>
</html>


lưu ý rằng việc stackoverflow sử dụng iframe xung quanh đoạn mã làm rối kết quả
Miller

11

Tôi đã có thể tìm thấy một câu trả lời dứt khoát trong JavaScript: Hướng dẫn dứt khoát, Ấn bản thứ 6 của O'Reilly, tr. 391:

Giải pháp này hoạt động ngay cả trong chế độ Quirks, trong khi giải pháp hiện tại của ryanve và ScottEvernden thì không.

function getViewportSize(w) {

    // Use the specified window or the current window if no argument
    w = w || window;

    // This works for all browsers except IE8 and before
    if (w.innerWidth != null) return { w: w.innerWidth, h: w.innerHeight };

    // For IE (or any browser) in Standards mode
    var d = w.document;
    if (document.compatMode == "CSS1Compat")
        return { w: d.documentElement.clientWidth,
           h: d.documentElement.clientHeight };

    // For browsers in Quirks mode
    return { w: d.body.clientWidth, h: d.body.clientHeight };

}

ngoại trừ thực tế là tôi tự hỏi tại sao dòng if (document.compatMode == "CSS1Compat")này không if (d.compatMode == "CSS1Compat"), mọi thứ đều tốt.


bạn đang nói về màn hình Retina hay Cảnh vs Chân dung hoặc thẻ meta viewport? Bạn không có nghĩa là điểm ảnh ảo như trong snowdragonledhk.com/... ?
phân cực

1) Khi nói về màn hình DPI cao, ý tôi là các pixel ảo được giải thích ở đây: stackoverflow.com/a/14325619/139361 . Mỗi màn hình iPhone có độ rộng chính xác là 320 pixel. 2) Tôi nói rằng: a) documentElement.clientWidthkhông phản hồi về thay đổi hướng thiết bị trên iOS. b) hiển thị số pixel vật lý (thực tế vô dụng) thay vì pixel ảo
Dan

11

Nếu bạn đang tìm kiếm giải pháp không phải jQuery cung cấp các giá trị chính xác bằng pixel ảo trên thiết bị di động và bạn nghĩ rằng đơn giản window.innerHeighthoặc document.documentElement.clientHeightcó thể giải quyết vấn đề của mình, vui lòng nghiên cứu liên kết này trước: https://tripleodeon.com/assets/2011/12/ bảng.html

Nhà phát triển đã thực hiện thử nghiệm tốt cho thấy vấn đề: bạn có thể nhận được các giá trị không mong muốn cho Android / iOS, màn hình ngang / dọc, bình thường / mật độ cao.

Câu trả lời hiện tại của tôi chưa phải là viên đạn bạc (// todo), mà là một cảnh báo cho những người sẽ nhanh chóng sao chép-dán bất kỳ giải pháp đã cho nào từ chuỗi này vào mã sản xuất.

Tôi đang tìm kiếm chiều rộng trang bằng pixel ảo trên thiết bị di động và tôi đã tìm thấy mã làm việc duy nhất là (thật bất ngờ!) window.outerWidth. Sau này tôi sẽ kiểm tra bảng này để biết giải pháp chính xác cho chiều cao không bao gồm thanh điều hướng, khi tôi có thời gian.



9

Có một sự khác biệt giữa window.innerHeightdocument.documentElement.clientHeight. Đầu tiên bao gồm chiều cao của thanh cuộn ngang.


1
Bạn đã kiểm tra câu trả lời của mình trên các hệ điều hành, trên màn hình Retina và ở chế độ ngang / dọc? Liên kết này bao gồm các hệ thống khá lỗi thời, nhưng nó chứng minh rằng mã của bạn không hoạt động: tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

6

Một giải pháp phù hợp với tiêu chuẩn W3C sẽ là tạo một div trong suốt (ví dụ như động với JavaScript), đặt chiều rộng và chiều cao của nó thành 100vw / 100vh (đơn vị Viewport) và sau đó lấy offsetWidth và offsetHeight của nó. Sau đó, phần tử có thể được loại bỏ một lần nữa. Điều này sẽ không hoạt động trong các trình duyệt cũ hơn vì các đơn vị khung nhìn tương đối mới, nhưng nếu bạn không quan tâm đến chúng nhưng thay vào đó là các tiêu chuẩn (sắp có), bạn chắc chắn có thể đi theo cách này:

var objNode = document.createElement("div");
objNode.style.width  = "100vw";
objNode.style.height = "100vh";
document.body.appendChild(objNode);
var intViewportWidth  = objNode.offsetWidth;
var intViewportHeight = objNode.offsetHeight;
document.body.removeChild(objNode);

Tất nhiên, bạn cũng có thể đặt objNode.style.poseition = "fixed" và sau đó sử dụng 100% làm chiều rộng / chiều cao - điều này sẽ có tác dụng tương tự và cải thiện khả năng tương thích ở một mức độ nào đó. Ngoài ra, cài đặt vị trí thành cố định có thể là một ý tưởng tốt nói chung, vì nếu không, div sẽ vô hình nhưng tiêu tốn một số không gian, điều này sẽ dẫn đến các thanh cuộn xuất hiện, v.v.


Thật không may, thực tế phá hủy hoàn toàn "giải pháp tiêu chuẩn W3C" của bạn: 1) caniuse.com/viewport-units , 2) caniuse.com/#feat=css-fixed . Những gì các nhà phát triển cần là giải pháp hoạt động, chứ không phải "nên hoạt động trên lý thuyết".
Dan

Nếu chúng ta có thể dựa vào các tiêu chuẩn thì chúng ta thậm chí không cần tất cả các giải pháp trình duyệt chéo đó. Một giải pháp trả lời trên spec không phải là một giải pháp.
Derek 朕 會

3

Đây là cách tôi làm, tôi đã thử nó trong IE 8 -> 10, FF 35, Chrome 40, nó sẽ hoạt động rất trơn tru trong tất cả các trình duyệt hiện đại (như window.innerWidth được xác định) và trong IE 8 (không có cửa sổ. InternalWidth) nó cũng hoạt động trơn tru, bất kỳ vấn đề nào (như nhấp nháy vì tràn: "ẩn"), vui lòng báo cáo nó. Tôi không thực sự quan tâm đến chiều cao của khung nhìn khi tôi thực hiện chức năng này chỉ để khắc phục một số công cụ phản hồi, nhưng nó có thể được triển khai. Hy vọng nó sẽ giúp, tôi đánh giá cao ý kiến ​​và đề xuất.

function viewportWidth () {
  if (window.innerWidth) return window.innerWidth;
  var
  doc = document,
  html = doc && doc.documentElement,
  body = doc && (doc.body || doc.getElementsByTagName("body")[0]),
  getWidth = function (elm) {
    if (!elm) return 0;
    var setOverflow = function (style, value) {
      var oldValue = style.overflow;
      style.overflow = value;
      return oldValue || "";
    }, style = elm.style, oldValue = setOverflow(style, "hidden"), width = elm.clientWidth || 0;
    setOverflow(style, oldValue);
    return width;
  };
  return Math.max(
    getWidth(html),
    getWidth(body)
  );
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.