วิธีรับขนาดวิวพอร์ตของเบราว์เซอร์


788

ฉันต้องการให้ผู้เยี่ยมชมสามารถดูภาพคุณภาพสูงมีวิธีใดบ้างที่ฉันสามารถตรวจสอบขนาดหน้าต่างได้

หรือดีกว่าขนาดวิวพอร์ตของเบราว์เซอร์ที่มี JavaScript ดูพื้นที่สีเขียวที่นี่:


10
สิ่งที่ฉันทำคือการตั้งองค์ประกอบมักจะ html ที่ความสูง 100% และรับความสูงของมัน ใช้งานได้ง่ายทุกที่
มูฮัมหมัดอูเมอ

1
@ Muhammad ผู้ดีจับ! หากคุณผิดหวังที่จะได้มิติข้อมูล (และคุณจะgetComputedStyleใช้htmlแท็กที่ขยายโดยที่ไม่ต้อง jQuery)
ด่าน

นอกจากนี้คุณสามารถใช้ไลบรารีWซึ่งจัดการการตรวจจับวิวพอร์ตเบราว์เซอร์แบบข้ามเบราว์เซอร์
pyrsmk

คำตอบ:


1327

ข้ามเบราว์เซอร์ @media (width)และ@media (height)ค่า 

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

  • รับCSS viewport @media (width)และ@media (height)ซึ่งรวมถึงแถบเลื่อน
  • initial-scaleและรูปแบบการซูมอาจทำให้ค่ามือถือลดระดับลงอย่างผิดพลาดกับสิ่งที่ PPK เรียกว่าวิวพอร์ตภาพและจะเล็กกว่า@mediaค่า
  • การซูมอาจทำให้ค่าปิด 1px เนื่องจากการปัดเศษแบบเนทีฟ
  • undefined ใน IE8-

document.documentElement.clientWidth และ .clientHeight

ทรัพยากร


4
@ 01100001 แทนที่ด้วย$ vergeถ้าคุณต้องการที่จะรวมเข้ากับ jQuery jQuery.extend(verge)แล้วทำ ดู: verge.airve.com/#static
ryanve

4
แค่อยากจะพูดถึงว่าใน IE8 (และบางทีคนอื่น ๆ ) คุณต้องมี<!DOCTYPE html>ที่ด้านบนของหน้าเพื่อให้รหัสทำงาน
Tzury Bar Yochay

6
ฉันไม่มีความสุขกับลูกค้าความกว้าง / ความสูงบนอุปกรณ์มือถือtripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

24
คำตอบนี้ไม่ถูกต้องเว้นแต่ว่าฉันทำอะไรหาย ใน Chrome อย่างน้อยdocument.documentElement.clientHeightผลตอบแทนสูงหน้าในขณะที่window.innerHeightผลตอบแทนสูงวิวพอร์ต แตกต่างใหญ่
เนท

2
การทดสอบตัวแปรขนาดหน้าจอที่แตกต่างกัน / วิธีแก้ปัญหาแบบสด: ryanve.com/lab/dimensions
Alex

106

ฟังก์ชันมิติ jQuery

$(window).width() และ $(window).height()


60
@allyourcode เป็นไปไม่ได้, jQuery คือคำตอบทั้งหมด
Xeoncross

21
สิ่งนี้ไม่ได้รับขนาดวิวพอร์ต แต่ขนาดเอกสารโดยรวม ลองมัน.
Alejandro García Iglesias

2
สำหรับเบราว์เซอร์ที่แสดงแถบเครื่องมือ addon เป็น HTML ที่มีการโพสต์แบบตายตัวโซลูชันนี้จะไม่ทำงานโดยเฉพาะถ้าคุณต้องการใช้ในการวางตำแหน่งและเปอร์เซ็นต์โค้ดด้านบนของคุณ
Adib Aroui

7
@AlejandroIglesias: ไม่ฉันเพิ่งทดสอบมันในหน้า SO นี้ $(window).height();ผลตอบแทน 536 ในขณะที่$("html").height();ผลตอบแทน 10599
Flimm

2
คำเตือนขนาดเหล่านี้ไม่รวมแถบเลื่อน (ซึ่งมีขนาดแตกต่างกันในเบราว์เซอร์และแพลตฟอร์มที่แตกต่างกัน) และดังนั้นพวกเขาจะไม่ตรงกับแบบสอบถามสื่อ css คำตอบอื่น ๆ ที่นี่ทำ แต่แก้ปัญหานี้
Spencer O'Reilly

75

คุณสามารถใช้window.innerWidthและwindow.innerHeightคุณสมบัติ

InnerHeight vs outerHeight


29
แม้ว่าสิ่งนี้จะไม่ทำงานใน IE +1 สำหรับไดอะแกรม: D สำหรับคำถามเช่นนี้มันควรเป็นอาชญากรรมที่จะไม่มีสิ่งเหล่านี้มากกว่านี้
allyourcode

8
@CMS document.documentElement.clientWidthมีความแม่นยำมากขึ้นและได้รับการสนับสนุนอย่างกว้างขวางมากกว่าwindow.innerWidth
ryanve

6
@ryanve หาก "แม่นยำยิ่งขึ้น" คุณหมายถึง "ไม่แม้แต่ทำสิ่งเดียวกันจากระยะไกล" ถ้าใช่คุณก็จะได้รับ: P
boxed

Firefox รุ่นเบต้า? นั่นคือสิ่งที่เป็นของพิพิธภัณฑ์
Derek 朕會功夫

@boxed ใน Safari มือถือdocument.documentElement.clientWidthให้ความกว้างวิวพอร์ตแก่ฉันในขณะที่ window.innerWidth ให้ความกว้างของเอกสารแก่ฉัน ใช่แล้ว
John

33

ถ้าคุณไม่ได้ใช้ jQuery มันก็น่าเกลียด นี่คือตัวอย่างข้อมูลที่ควรใช้กับเบราว์เซอร์ใหม่ทั้งหมด ลักษณะการทำงานจะแตกต่างกันในโหมด Quirks และโหมดมาตรฐานใน IE สิ่งนี้จะดูแลมัน

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

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

8
สิ่งนี้ไม่ได้ให้ความสูงของหน้าไม่ใช่วิวพอร์ตใช่หรือไม่ นั่นคือสิ่งที่หน้านี้ดูเหมือนจะบ่งบอกถึง: developer.mozilla.org/en/DOM/element.clientHeight
allyourcode

4
คุณกำลังใช้clientHeightในdocument.documentElementองค์ประกอบที่จะให้คุณขนาดวิวพอร์ต document.body.clientHeightเพื่อให้ได้ขนาดของเอกสารที่คุณจะต้องทำ ตามที่ Chetan อธิบายพฤติกรรมนี้ใช้กับเบราว์เซอร์ที่ทันสมัย ง่ายต่อการทดสอบ เพียงเปิดคอนโซลและพิมพ์document.documentElement.clientHeightบนแท็บที่เปิดอยู่หลายแห่ง
Gajus

13

ฉันรู้ว่านี้มีคำตอบที่ยอมรับ แต่ฉันวิ่งเข้าไปในสถานการณ์ที่clientWidthไม่ได้ทำงานกับ iPhone (เหมืองอย่างน้อย) กลับ 980 ไม่ 320, window.screen.widthดังนั้นผมจึงใช้ ฉันทำงานบนไซต์ที่มีอยู่เดิมกำลังถูก "ตอบสนอง" และจำเป็นต้องบังคับให้เบราว์เซอร์ขนาดใหญ่ใช้เมตาวิวพอร์ตอื่น

หวังว่านี่จะช่วยใครซักคนมันอาจจะไม่สมบูรณ์แบบ แต่มันใช้งานได้ในการทดสอบของฉันกับ iOs และ 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

ฉันค้นหาและพบเบราว์เซอร์ข้าม:

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>


โปรดทราบว่าการใช้ iframe ของ stackoverflow รอบ ๆ ข้อมูลโค้ดทำให้เกิดความ
มิลเลอร์

11

ฉันสามารถค้นหาคำตอบที่ชัดเจนใน JavaScript: The Definitive Guide, 6th Edition โดย O'Reilly, p. 391:

โซลูชันนี้ทำงานได้แม้ในโหมด Quirks ในขณะที่โซลูชันของ ryanve และ ScottEvernden ไม่สามารถทำได้

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

}

ยกเว้นความจริงที่ว่าฉันสงสัยว่าทำไมสายif (document.compatMode == "CSS1Compat")ไม่ได้if (d.compatMode == "CSS1Compat")ทุกอย่างดูดี


คุณกำลังพูดถึงจอแสดงผล Retina หรือแนวนอนหรือแนวตั้งหรือแท็กวิวพอร์ตเมตา คุณไม่ได้หมายถึงพิกเซลเสมือนจริงเหมือนในsnowdragonledhk.com/… ?
nonopolarity

1) เมื่อพูดถึงสูง DPI แสดงผมหมายถึงพิกเซลเสมือนอธิบายที่นี่: stackoverflow.com/a/14325619/139361 หน้าจอ iPhone ทุกหน้ากว้าง 320 พิกเซลเสมือนจริง 2) ฉันบอกว่า: a) documentElement.clientWidthไม่ตอบสนองต่อการเปลี่ยนแนวอุปกรณ์บน iOS ข) แสดงพิกเซลทางกายภาพ count (ไร้ประโยชน์จริง) แทนพิกเซลเสมือน
แดน

11

หากคุณกำลังมองหาวิธีแก้ปัญหาที่ไม่ใช่ jQuery ที่ให้ค่าที่ถูกต้องในพิกเซลเสมือนบนมือถือและคุณคิดว่าธรรมดาwindow.innerHeightหรือdocument.documentElement.clientHeightสามารถแก้ปัญหาของคุณโปรดศึกษาลิงค์นี้ก่อน: https://tripleodeon.com/assets/2011/12/ table.html

นักพัฒนาซอฟต์แวร์ทำการทดสอบที่ดีซึ่งเผยให้เห็นปัญหา: คุณสามารถรับค่าที่ไม่คาดคิดสำหรับ Android / iOS, แนวนอน / แนวตั้ง, การแสดงความหนาแน่นปกติ / สูง

คำตอบปัจจุบันของฉันยังไม่ได้เป็น bullet เงิน (// todo) แต่เป็นคำเตือนสำหรับผู้ที่กำลังจะคัดลอกวางโซลูชันที่กำหนดอย่างรวดเร็วจากชุดข้อความนี้ไปยังรหัสการผลิต

ผมกำลังมองหาความกว้างหน้าพิกเซลเสมือนจริงบนมือถือและฉันได้พบรหัสเท่านั้นทำงาน window.outerWidth(โดยไม่คาดคิด!) ฉันจะตรวจสอบตารางนี้ในภายหลังเพื่อหาวิธีการแก้ปัญหาที่ถูกต้องซึ่งให้ความสูงไม่รวมแถบนำทางเมื่อฉันมีเวลา


10

รหัสนี้มาจากhttp://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/

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

หมายเหตุ: ในการอ่านความกว้างให้ใช้ console.log('viewport width'+viewport().width);


9

มีความแตกต่างระหว่างการเป็นและwindow.innerHeight document.documentElement.clientHeightครั้งแรกรวมถึงความสูงของแถบเลื่อนแนวนอน


1
คุณทดสอบคำตอบของคุณข้าม OS, บนจอแสดงผล Retina และในโหมดแนวนอน / แนวตั้งหรือไม่? ลิงก์นี้ครอบคลุมระบบที่ค่อนข้างล้าสมัย แต่มันพิสูจน์ว่ารหัสของคุณใช้งานไม่ได้: tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

6

วิธีแก้ปัญหาที่สอดคล้องกับมาตรฐาน W3C คือการสร้าง div ที่โปร่งใส (เช่นไดนามิกกับ JavaScript) ตั้งค่าความกว้างและความสูงเป็น 100vw / 100vh (หน่วย Viewport) จากนั้นรับ offsetWidth และ offsetHeight หลังจากนั้นองค์ประกอบสามารถลบออกได้อีกครั้ง สิ่งนี้จะไม่ทำงานในเบราว์เซอร์รุ่นเก่าเพราะหน่วยวิวพอร์ตค่อนข้างใหม่ แต่ถ้าคุณไม่สนใจพวกเขา แต่เกี่ยวกับมาตรฐาน (ใกล้จะ) แทนคุณสามารถไปทางนี้ได้:

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

แน่นอนคุณสามารถตั้งค่า objNode.style.position = "fixed" แล้วใช้ 100% เป็น width / height - นี่ควรมีผลเช่นเดียวกันและปรับปรุงความเข้ากันได้ในระดับหนึ่ง นอกจากนี้การกำหนดตำแหน่งให้คงที่อาจเป็นความคิดที่ดีโดยทั่วไปเพราะไม่เช่นนั้น div จะมองไม่เห็น แต่ใช้พื้นที่บางส่วนซึ่งจะทำให้แถบเลื่อนปรากฏขึ้นเป็นต้น


แต่น่าเสียดายที่ในความเป็นจริงทำลาย "W3C - โซลูชั่นมาตรฐาน" ของคุณ: 1) caniuse.com/viewport-units 2) caniuse.com/#feat=css-fixed สิ่งที่นักพัฒนาต้องการคือโซลูชันที่ใช้งานได้จริงไม่ใช่ "ควรทำงานได้ดีในทางทฤษฎี"
Dan

หากเราสามารถพึ่งพามาตรฐานได้เราก็ไม่จำเป็นต้องใช้โซลูชันเบราว์เซอร์ข้ามทั้งหมดเหล่านั้นด้วยซ้ำ โซลูชันที่ตอบกลับข้อมูลจำเพาะไม่ใช่โซลูชัน
Derek 朕會功夫

3

นี่คือวิธีที่ฉันทำฉันลองใน IE 8 -> 10, FF 35, Chrome 40 มันจะทำงานได้อย่างราบรื่นมากในเบราว์เซอร์ที่ทันสมัยทั้งหมด (ตามที่กำหนดไว้ใน window.innerWidth) และใน IE 8 (ไม่มีหน้าต่าง InnerWidth) มันทำงานได้อย่างราบรื่นเช่นกันปัญหาใด ๆ (เช่นกระพริบเพราะล้น: "ซ่อน") โปรดรายงาน ฉันไม่ได้สนใจความสูงของวิวพอร์ตเนื่องจากฉันสร้างฟังก์ชันนี้เพื่อแก้ไขเครื่องมือตอบสนองบางอย่าง แต่อาจนำไปใช้งานได้ หวังว่าจะช่วยได้ฉันขอขอบคุณความคิดเห็นและข้อเสนอแนะ

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)
  );
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.