รับความกว้างของอุปกรณ์ในจาวาสคริปต์


129

มีวิธีรับความกว้างอุปกรณ์ของผู้ใช้ซึ่งต่างจากความกว้างของวิวพอร์ตโดยใช้จาวาสคริปต์หรือไม่

แบบสอบถามสื่อ CSS เสนอสิ่งนี้อย่างที่ฉันพูดได้

@media screen and (max-width:640px) {
    /* ... */
}

และ

@media screen and (max-device-width:960px) {
    /* ... */
}

สิ่งนี้มีประโยชน์หากฉันกำหนดเป้าหมายสมาร์ทโฟนในแนวนอน ตัวอย่างเช่นบน iOS การประกาศว่า max-width:640pxจะกำหนดเป้าหมายทั้งโหมดแนวนอนและแนวตั้งแม้ใน iPhone 4 นี่ไม่ใช่กรณีสำหรับ Android เท่าที่ฉันสามารถบอกได้ดังนั้นการใช้ความกว้างของอุปกรณ์ในอินสแตนซ์นี้จะกำหนดเป้าหมายทั้งสองทิศทางได้สำเร็จ โดยไม่กำหนดเป้าหมายอุปกรณ์เดสก์ท็อป

อย่างไรก็ตามหากฉันเรียกใช้การรวมจาวาสคริปต์ตามความกว้างของอุปกรณ์ดูเหมือนว่าฉันจะถูก จำกัด ให้ทดสอบความกว้างของวิวพอร์ตซึ่งหมายถึงการทดสอบเพิ่มเติมดังต่อไปนี้

if ($(window).width() <= 960 && $(window).height <= 640) { /* ... */ }

สิ่งนี้ดูไม่สวยสำหรับฉันเนื่องจากคำใบ้ว่าความกว้างของอุปกรณ์พร้อมใช้งานสำหรับ css


4
ลองใช้เว็บไซต์นี้เพื่อทราบขนาดที่ถูกต้องของอุปกรณ์ของคุณ responsejs.com/labs/dimensions
Alpesh Darji

Modernizrสามารถช่วยคุณทำ "วิธีที่สะอาด & ​​ทั่วไป" ได้: stackoverflow.com/questions/25935686/… . เกี่ยวกับความคิดเห็นที่ 1: คุณอาจต้องการ Google "Modernizr vs <otherLib> media query" เพื่อค้นหาสิ่งที่ดีที่สุดสำหรับกรณีการใช้งานของคุณ
Adrien Be

คำตอบ:


214

คุณสามารถรับความกว้างของหน้าจออุปกรณ์ผ่านคุณสมบัติ screen.width
บางครั้งการใช้ window.innerWidth ก็มีประโยชน์เช่นกัน (โดยทั่วไปจะไม่พบในอุปกรณ์พกพา) แทนความกว้างของหน้าจอเมื่อจัดการกับเบราว์เซอร์เดสก์ท็อปซึ่งขนาดหน้าต่างมักจะน้อยกว่าขนาดหน้าจอของอุปกรณ์

โดยปกติเมื่อจัดการกับโทรศัพท์มือถือและเบราว์เซอร์เดสก์ท็อปฉันใช้สิ่งต่อไปนี้:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;

5
ฉันสังเกตว่าสิ่งนี้ไม่ได้ผลตามที่คาดไว้ในเบราว์เซอร์เนทีฟ Android 2.2 หากฉันไม่ได้อยู่ในระดับ 1: 1 ก็สามารถรายงานความกว้างที่กว้างกว่ามาก (กว้างที่สุดเท่าที่จะทำได้) ซึ่งน่าหงุดหงิดเล็กน้อย
Chris Bosco

4
สิ่งนี้ส่งคืน 980 บน Chrome Beta บน Android และ 1024 บนเบราว์เซอร์ Android บน HTC vivid
Alex

4
@Alex นี่คือความกว้างของวิวพอร์ตเริ่มต้นของเบราว์เซอร์ หากคุณใช้เมตาแท็กของวิวพอร์ตwidth=device-widthคุณควรได้รับค่าที่แท้จริง
Brian Nickel

2
window.innerWidth กำลังส่งคืน 980 บน Iphone (Chrome / Safari) นั้นเป็นอย่างไร? <meta name = "viewport" content = "width = device-width" /> ไม่แตกต่าง
Joao Leme

13
วิธีนี้มีการโหวตเพิ่มจำนวนมากได้อย่างไร? var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;ส่งคืน 667 บน iphone 6 และ 6 Plus โซลูชันนี้ทำงานไม่ถูกต้อง
Ian S

60

ปัญหาหนึ่งของคำตอบที่เป็นประโยชน์ของ Bryan Rieger คือบนหน้าจอความหนาแน่นสูงอุปกรณ์ Apple จะรายงานหน้าจอความกว้างเป็น dips ในขณะที่อุปกรณ์ Android รายงานเป็นพิกเซลทางกายภาพ (ดูhttp://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html ) ฉันขอแนะนำให้ใช้if (window.matchMedia('(max-device-width: 960px)').matches) {}บนเบราว์เซอร์ที่รองรับ matchMedia


1
ดูเหมือนว่าจะเป็นทางออกที่ดีกว่ามากและใช้คิวรีสื่อ CSS ฉันสงสัยว่าการรองรับเบราว์เซอร์สำหรับสิ่งนี้ในแพลตฟอร์มมือถือคืออะไร?
Carl Zulauf

1
นี่จะเป็นการใช้งานที่ถูกต้องหรือไม่? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
norsewulf

3
ฉันไม่แน่ใจว่ามันจะใช้งานได้หรือไม่หากไม่มีการตั้งมาตราส่วนเป็น 1: 1 เป็นฐาน ...var isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960;
Tracker1

3
สำหรับเบราว์เซอร์ที่ไม่รองรับmatchMedia()จะมี polyfill: github.com/paulirish/matchMedia.js
AvL

4
อ้างอิงจากcaniuse.comแทบทุกเบราว์เซอร์รวมถึงมือถือสนับสนุน window.matchMedia ()
Mark Langer

14

ฉันเพิ่งมีความคิดนี้ดังนั้นอาจจะเป็นการมองสั้น แต่ดูเหมือนว่าจะทำงานได้ดีและอาจจะสอดคล้องกันมากที่สุดระหว่าง CSS และ JS ของคุณ

ใน CSS ของคุณคุณตั้งค่าความกว้างสูงสุดสำหรับ html ตามค่าหน้าจอ @media:

@media screen and (max-width: 480px) and (orientation: portrait){

    html { 
        max-width: 480px;
    }

    ... more styles for max-width 480px screens go here

}

จากนั้นใช้ JS (อาจใช้กรอบเช่น JQuery) คุณจะตรวจสอบค่าความกว้างสูงสุดของแท็ก html:

maxwidth = $('html').css('max-width');

ตอนนี้คุณสามารถใช้ค่านี้เพื่อทำการเปลี่ยนแปลงตามเงื่อนไข:

If (maxwidth == '480px') { do something }

หากการใส่ค่าความกว้างสูงสุดในแท็ก html ดูน่ากลัวคุณอาจใส่แท็กอื่นซึ่งใช้เพื่อจุดประสงค์นี้เท่านั้น สำหรับจุดประสงค์ของฉันแท็ก html ทำงานได้ดีและไม่มีผลต่อมาร์กอัปของฉัน


มีประโยชน์หากคุณใช้ Sass ฯลฯ : หากต้องการส่งคืนค่าที่เป็นนามธรรมมากขึ้นเช่นชื่อเบรกพอยต์แทนที่จะเป็นค่า px คุณสามารถทำสิ่งต่อไปนี้

  1. สร้างองค์ประกอบที่จะเก็บชื่อเบรกพอยต์เช่น <div id="breakpoint-indicator" />
  2. การใช้คิวรีสื่อ css จะเปลี่ยนคุณสมบัติเนื้อหาสำหรับองค์ประกอบนี้เช่น "large" หรือ "mobile" เป็นต้น (วิธีการสืบค้นสื่อพื้นฐานเช่นเดียวกับด้านบน แต่ตั้งค่าคุณสมบัติ 'content' css แทน 'max-width')
  3. รับค่าคุณสมบัติเนื้อหา css โดยใช้ js หรือ jquery (jquery เช่น $('#breakpoint-indicator').css('content'); ) ซึ่งส่งคืน "large" หรือ "mobile" เป็นต้นขึ้นอยู่กับคุณสมบัติเนื้อหาที่กำหนดโดยคิวรีสื่อ
  4. ดำเนินการกับค่าปัจจุบัน

ตอนนี้คุณสามารถดำเนินการกับชื่อเบรกพอยต์เดียวกันกับที่คุณทำใน sass เช่น sass: @include respond-to(xs)และ jsif ($breakpoint = "xs) {}js

สิ่งที่ฉันชอบเป็นพิเศษเกี่ยวกับเรื่องนี้คือฉันสามารถกำหนดชื่อเบรกพอยต์ของฉันทั้งหมดใน css และในที่เดียว (น่าจะเป็นเอกสาร scss ของตัวแปร) และ js ของฉันสามารถดำเนินการกับพวกเขาได้อย่างอิสระ


8

var width = Math.max(window.screen.width, window.innerWidth);

สิ่งนี้ควรจัดการกับสถานการณ์ส่วนใหญ่


Math.max (window.innerWidth); จะให้ความกว้างแก่คุณรวมถึงแถบเลื่อนใน FireFox, Edge และ Chrome document.documentElement.clientWidth; จะให้ความกว้างภายในแถบเลื่อนในเบราว์เซอร์เหล่านั้น ใน IE 11 ทั้งสองจะแสดงความกว้างรวมทั้งแถบเลื่อน ..
RationalRabbit

7

คุณควรใช้

document.documentElement.clientWidth

ถือเป็นการใช้งานข้ามเบราว์เซอร์และเป็นวิธีเดียวกับที่ jQuery (window) .width (); การใช้งาน

สำหรับข้อมูลโดยละเอียดสามารถดูได้ที่: https://ryanve.com/lab/dimensions/


5

ฉันคิดว่าการใช้window.devicePixelRatioนั้นหรูหรากว่าการwindow.matchMediaแก้ปัญหา:

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}


5

คุณสามารถใช้งานได้อย่างง่ายดาย

document.documentElement.clientWidth


3
โดยทั่วไปคำตอบจะมีประโยชน์มากขึ้นหากมีคำอธิบายว่าโค้ดมีจุดประสงค์เพื่อทำอะไรและทำไมจึงแก้ปัญหาได้โดยไม่ต้องแนะนำผู้อื่น
Tim Diekmann

3

โทรศัพท์ Lumia ให้หน้าจอไม่ถูกต้องความกว้าง (อย่างน้อยก็ในโปรแกรมจำลอง) ดังนั้นอาจMath.min(window.innerWidth || Infinity, screen.width)จะใช้งานได้กับทุกอุปกรณ์?

หรือสิ่งที่บ้าคลั่งกว่า:

for (var i = 100; !window.matchMedia('(max-device-width: ' + i + 'px)').matches; i++) {}
var deviceWidth = i;

2

Ya mybe คุณสามารถใช้ document.documentElement.clientWidth เพื่อรับความกว้างของอุปกรณ์ไคลเอนต์และติดตามความกว้างของอุปกรณ์โดยใส่ setInterval

เหมือนกับ

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);

เพียงใช้ onresize ตัวอย่างเช่น document.getElementsByTagName ("BODY") [0] .onresize = function ()
RationalRabbit

0

เช่นเดียวกับ FYI มีไลบรารีที่เรียกว่าเบรกพอยต์ซึ่งตรวจจับความกว้างสูงสุดตามที่ตั้งไว้ใน CSS และอนุญาตให้คุณใช้ในเงื่อนไข JS if-else โดยใช้เครื่องหมาย <=, <,>,> = และ == ฉันพบว่ามันมีประโยชน์มากทีเดียว ขนาดน้ำหนักบรรทุกต่ำกว่า 3 KB

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