$ (หน้าต่าง) .width () ไม่เหมือนกับการสืบค้นสื่อ


186

ฉันใช้ 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เป็นวิธีที่จะไป อย่างไรก็ตามฉันต้องการค้นหาวิธีแก้ปัญหาที่คำนวณความกว้างของแถบเลื่อนและสอดคล้องกับข้อความค้นหาสื่อของฉัน (เช่นเมื่อทั้งสองเงื่อนไขตรวจสอบกับค่า 767) เพราะเบราว์เซอร์บางตัวอาจไม่ได้มีความกว้างของแถบเลื่อน 16px


1
ลองทำอะไรสักอย่างถ้า ($ ('html'). width () <= 767) {// ทำอะไรสักอย่าง}
Vaibs_Cool

@Vaibs_Cool ขอบคุณสำหรับคำแนะนำ แต่ฉันยังคงได้รับผลลัพธ์เดียวกัน
Pattle


ตอบฉันที่นี่ [ป้อนคำอธิบายลิงค์ที่นี่] [1] [1]: stackoverflow.com/questions/11309859//
Rantiev

"document.documentElement.clientWidth" (แทนที่จะเป็น "$ (หน้าต่าง) .width ()") ทำงานตามที่คุณต้องการหรือไม่ แก้ไข: ความผิดพลาดของฉันเพิ่งเห็นคำตอบของ Vaibs_Cool
joshhunt

คำตอบ:


293

หากคุณไม่จำเป็นต้องรองรับ IE9 คุณสามารถใช้window.matchMedia()( เอกสาร MDN )

function checkPosition() {
    if (window.matchMedia('(max-width: 767px)').matches) {
        //...
    } else {
        //...
    }
}

window.matchMediaสอดคล้องกับการสืบค้นสื่อ CSS อย่างสมบูรณ์และการสนับสนุนเบราว์เซอร์ค่อนข้างดี: http://caniuse.com/#feat=matchmedia

UPDATE:

หากคุณต้องสนับสนุนเบราว์เซอร์มากขึ้นคุณสามารถใช้วิธี mq ของ Modernizrได้ก็รองรับเบราว์เซอร์ทั้งหมดที่เข้าใจคำสั่งสื่อใน CSS

if (Modernizr.mq('(max-width: 767px)')) {
    //...
} else {
    //...
}

8
หากคุณสามารถที่จะใช้ห้องสมุด Modernizr นี่เป็นคำตอบที่ดีที่สุด
richsinn

1
วิธีนี้ดีกว่า: stackoverflow.com/a/19292035/1136132 (รหัสที่ 2) JS เท่านั้น
joseantgv

@joseantgv โซลูชันของฉันเป็น js-only เช่นกัน คุณช่วยอธิบายได้ไหมว่าทำไมโซลูชันที่คุณเชื่อมโยงถึงดีกว่า
ausi

2
@edwardm Modernizr.mqส่งคืนค่าบูลีนเท่านั้นดังนั้นคุณต้องเรียกมันด้วยตัวคุณเองในonresizeตัวจัดการเหตุการณ์
ausi

2
@Bernig window.matchMediaเป็นวิธีที่แนะนำเนื่องจากจะไม่เรียกreflowขึ้นอยู่กับความถี่ที่คุณเรียกใช้ฟังก์ชันนี้อาจทำให้เกิดปัญหาประสิทธิภาพการทำงาน หากคุณไม่ต้องการที่จะใช้ Modernizr โดยตรงคุณสามารถคัดลอกรหัสที่มาจากsrc / mq.jsและsrc / injectElementWithStyles.js
ausi

175

ตรวจสอบกฎ 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;
    }
}

9
นั่นเป็นทางออกที่สง่างามยิ่งกว่า JS hacks ที่กล่าวถึงในคำตอบอื่น
René Roth

3
+1 นี่ฉลาดแค่ ฉันชอบวิธีที่คุณต้องการเปลี่ยนเบรกพอยต์สิ่งที่คุณต้องทำคือเปลี่ยน css ไม่ใช่ javascript
JoeMoe1984

วิธีนี้ใช้ได้ดีและฉันคิดว่ามันดีกว่าแฮ็คจาวาสคริปต์ที่เสนอในคำตอบที่ได้รับการโหวตมากที่สุด
Andrés Meza-Escallón

2
หากคุณใช้ bootstrap คุณสามารถทำได้โดยไม่ต้อง<div id="xs-indicator" class="xs-visible">
กดปุ่ม

33

มันอาจจะเกิดจากการ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' ] };
}

เหนือรหัสแหล่งที่มา


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

1
ใช่ใช้innerWidth()หรือคุณสามารถใช้มันได้เหมือน$('body').innerWidth();ดูstackoverflow.com/questions/8339377/
Rohan Kumar

3
คุณหมายถึง window.innerWidth ไม่ใช่ในวัตถุ jQuery $ (หน้าต่าง), $ (หน้าต่าง). width () ส่งคืนอย่างไม่ถูกต้อง
EJanuszewski

1
window.innerWidthไม่สอดคล้องกับข้อความค้นหาสื่อ CSS ใน Safari 8 หากมีการเปิดใช้งานแถบเลื่อนในการตั้งค่าระบบ OSX
ausi


4

อาจเป็นวิธีปฏิบัติที่ดีกว่าไม่ให้ JS- ขอบเขตความกว้างของเอกสาร แต่การเปลี่ยนแปลงบางอย่างที่ทำโดย css @media query ด้วยวิธีนี้คุณสามารถมั่นใจได้ว่าฟังก์ชั่น 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");
    ...
});

3

ฉันกำลังเผชิญปัญหาเดียวกันเมื่อเร็ว ๆ นี้ - ด้วย Bootstrap 3

$ .width () และ $ .innerWidth () จะใช้งานได้สำหรับคุณ

ทางออกที่ดีที่สุดที่ฉันได้รับ - และได้รับการปรับแต่งให้เหมาะกับ 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");


3

นี่คือทางเลือกของวิธีการที่กล่าวถึงข้างต้นซึ่งต้องอาศัยการเปลี่ยนแปลงบางอย่างผ่าน CSS และอ่านผ่าน Javascript วิธีนี้ไม่จำเป็นต้องใช้window.matchMediaหรือ Modernizr นอกจากนี้ยังต้องการองค์ประกอบ HTML พิเศษอีกด้วย ใช้งานได้โดยใช้องค์ประกอบหลอก HTML เพื่อจุดพักข้อมูล 'store':

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 ใด ๆ สำหรับสิ่งนี้ คุณสามารถเพิ่มสตริงหรือหมายเลขใด ๆ ที่คุณต้องการในcontentองค์ประกอบหลอก ไม่จำเป็นต้องเป็น 'มือถือ' และอื่น ๆ

ตอนนี้เราสามารถอ่านข้อมูลนี้จาก Javascript ด้วยวิธีต่อไปนี้:

var breakpoint = window.getComputedStyle(document.querySelector('body'), ':after').getPropertyValue('content').replace(/"/g,'');

if (breakpoint === 'mobile') {
    doSomething();
}

วิธีนี้เรามั่นใจเสมอว่าข้อมูลจุดพักถูกต้องเนื่องจากมาโดยตรงจาก CSS และเราไม่ต้องวุ่นวายกับการใช้ความกว้างของหน้าจอที่ถูกต้องผ่าน Javascript


คุณไม่จำเป็นต้องใช้หรือquerySelector() getPropertyValue()คุณสามารถค้นหาคำพูดเดียวใน regex ด้วย (เนื่องจากไม่สอดคล้องกัน) สิ่งนี้: window.getComputedStyle(document.body, ':after').content.replace(/"|'/g, ''). และเพื่อให้มีราคาถูกลงคุณสามารถห่อด้วยการขีดเส้นใต้ / lodash ._debounce()ด้วยการรอประมาณ 100ms ในที่สุดการต่อท้าย attribs ไปยัง <html> ทำให้สามารถใช้งานได้กับสิ่งอื่น ๆ เช่นคำแนะนำเครื่องมือปิดการใช้งานคำสั่งมองหาธง / ข้อมูลดิบนอก vars ตัวอย่าง: gist.github.com/dhaupin/f01cd87873092f4fe2fb8d802f9514b1
dhaupin

2

Javascript มีวิธีการมากกว่าหนึ่งวิธีในการตรวจสอบความกว้างวิวพอร์ต ดังที่คุณสังเกตเห็น InnerWidth ไม่ได้รวมความกว้างของแถบเครื่องมือและความกว้างของแถบเครื่องมือจะแตกต่างกันไปตามระบบ นอกจากนี้ยังมีตัวเลือกouterWidthซึ่งจะรวมความกว้างของแถบเครื่องมือ Mozilla Javascript APIฯ :

Window.outerWidth รับความกว้างด้านนอกของหน้าต่างเบราว์เซอร์ มันหมายถึงความกว้างของหน้าต่างเบราว์เซอร์ทั้งหมดรวมถึงแถบด้านข้าง (ถ้าขยาย), โครเมี่ยมหน้าต่างและการปรับขนาดเส้นขอบ / จัดการหน้าต่าง

สถานะของจาวาสคริปต์นั้นไม่สามารถพึ่งพาความหมายเฉพาะสำหรับ outerWidth ในทุกเบราว์เซอร์ในทุกแพลตฟอร์ม

outerWidthจะได้รับการสนับสนุนอย่างดีในเก่าเบราว์เซอร์มือถือแม้ว่ามันจะสนุกกับการสนับสนุนเบราว์เซอร์สก์ท็อปที่สำคัญและโทรศัพท์ส่วนใหญ่ที่ใหม่กว่าเบราว์เซอร์สมาร์ท

ดังที่ ausi ชี้ให้เห็นmatchMediaจะเป็นตัวเลือกที่ดีเนื่องจาก CSS เป็นมาตรฐานที่ดีกว่า (matchMedia ใช้ JS เพื่ออ่านค่าวิวพอร์ตที่ตรวจพบโดย CSS) แต่ถึงแม้จะมีมาตรฐานที่ยอมรับแล้ว แต่เบราว์เซอร์ที่ผ่านการชะลอยังคงมีอยู่ซึ่งไม่สนใจ (IE <10 ในกรณีนี้ซึ่งทำให้ matchMedia ไม่มีประโยชน์อย่างน้อยจนถึง XP เสียชีวิต)

ในสรุปถ้าคุณเป็นเพียงการพัฒนาเบราว์เซอร์เบราว์เซอร์สก์ท็อปและโทรศัพท์มือถือรุ่นใหม่ outerWidth ควรให้สิ่งที่คุณกำลังมองหาที่มีบางประการ


1

นี่คือเคล็ดลับที่เกี่ยวข้องน้อยกว่าในการจัดการกับข้อความค้นหาสื่อ การสนับสนุนข้ามเบราว์เซอร์ค่อนข้าง จำกัด เนื่องจากไม่รองรับ IE มือถือ

     if (window.matchMedia('(max-width: 694px)').matches)
    {
        //do desired changes
    }

ดูเอกสาร Mozillaสำหรับรายละเอียดเพิ่มเติม


1

ลองนี้

getData(){
    if(window.innerWidth <= 768) {
      alert('mobile view')
      return;
    }

   //else function will work

    let body= {
      "key" : 'keyValue'
    }
    this.dataService.getData(body).subscribe(
      (data: any) => {
        this.myData = data
      }
    )
}

0

วิธีแก้ปัญหาที่ใช้งานได้ตลอดและซิงค์กับคิวรีสื่อบันทึก CSS

เพิ่ม div เข้ากับร่างกาย

<body>
    ...
    <div class='check-media'></div>
    ...
</body>

เพิ่มสไตล์และเปลี่ยนพวกเขาโดยป้อนลงในแบบสอบถามสื่อเฉพาะ

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

โดยทั่วไปแล้วคุณสามารถตรวจสอบสไตล์ที่กำลังเปลี่ยนแปลงโดยการป้อนลงในคิวรีสื่อเฉพาะ


0

โซลูชันข้ามเบราว์เซอร์ที่ดีที่สุดคือการใช้ 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 จะส่งคืนค่าเท็จเสมอ


0
if(window.matchMedia('(max-width: 768px)').matches)
    {
        $(".article-item").text(function(i, text) {

            if (text.length >= 150) {
                text = text.substring(0, 250);
                var lastIndex = text.lastIndexOf(" ");     
                text = text.substring(0, lastIndex) + '...'; 
            }

            $(this).text(text);

        });

    }

0

สิ่งที่ฉันทำ ;

<body>
<script>
function getWidth(){
return Math.max(document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth);
}
var aWidth=getWidth();
</script>
...

และเรียกตัวแปร aWidth ที่ใดก็ได้หลังจากนั้น

คุณต้องวาง getWidth () ไว้ในเนื้อความเอกสารของคุณเพื่อให้แน่ใจว่านับความกว้างของแถบเลื่อนมิฉะนั้นความกว้างของแถบเลื่อนของเบราว์เซอร์จะถูกลบออกจาก getWidth ()


-1

การใช้งานตัวเลื่อนลื่นและแสดงจำนวนของภาพนิ่งที่แตกต่างกันในบล็อกขึ้นอยู่กับความละเอียด (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,
      });
    }

-2

ลองสิ่งนี้

if (document.documentElement.clientWidth < 767) {
   // scripts
}

สำหรับการอ้างอิงเพิ่มเติมคลิกที่นี่


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