วิธีการตรวจหาจุดหยุดตอบสนองของ Twitter Bootstrap 3 โดยใช้ JavaScript


139

ปัจจุบัน Twitter Bootstrap 3 มีจุดพักการตอบสนองต่อไปนี้: 768px, 992px และ 1200px ซึ่งแสดงถึงอุปกรณ์ขนาดเล็กขนาดกลางและขนาดใหญ่ตามลำดับ

ฉันจะตรวจหาเบรกพอยต์เหล่านี้โดยใช้ JavaScript ได้อย่างไร

ฉันต้องการฟังด้วย JavaScript สำหรับกิจกรรมที่เกี่ยวข้องทั้งหมดที่เกิดขึ้นเมื่อหน้าจอเปลี่ยน และเพื่อให้สามารถตรวจสอบว่าหน้าจอเป็นอุปกรณ์ขนาดเล็กกลางหรือใหญ่

มีบางสิ่งที่ทำไปแล้ว? คุณมีข้อเสนอแนะอะไร?


คุณสามารถใช้IntersectionObserverเพื่อตรวจสอบเมื่อมี<div class="d-none d-?-block"></div>การเปลี่ยนแปลงการมองเห็น (แทรกเบรกพอยต์ที่คุณต้องการ) คลาส CSS เหล่านั้นใช้สำหรับ Bootstrap 4 ... ใช้งานใดก็ได้ใน Bootstrap 3 มีประสิทธิภาพมากกว่าการฟังการปรับขนาดหน้าต่าง
Matt Thomas

คำตอบ:


241

แก้ไข: ห้องสมุดนี้สามารถใช้ได้ผ่าน Bower และ NPM ดู repo GitHub สำหรับรายละเอียด

ปรับปรุงคำตอบ:

คำเตือน: ฉันเป็นผู้เขียน

นี่คือบางสิ่งที่คุณสามารถทำได้โดยใช้เวอร์ชันล่าสุด (Responsive Bootstrap Toolkit 2.5.0):

// Wrap everything in an IIFE
(function($, viewport){

    // Executes only in XS breakpoint
    if( viewport.is('xs') ) {
        // ...
    }

    // Executes in SM, MD and LG breakpoints
    if( viewport.is('>=sm') ) {
        // ...
    }

    // Executes in XS and SM breakpoints
    if( viewport.is('<md') ) {
        // ...
    }

    // Execute only after document has fully loaded
    $(document).ready(function() {
        if( viewport.is('xs') ) {
            // ...
        }
    });

    // Execute code each time window size changes
    $(window).resize(
        viewport.changed(function() {
            if( viewport.is('xs') ) {
                // ...
            }
        })
    ); 

})(jQuery, ResponsiveBootstrapToolkit);

ตั้งแต่เวอร์ชัน 2.3.0 คุณไม่จำเป็นต้องมี<div>องค์ประกอบสี่อย่างที่กล่าวถึงด้านล่าง


คำตอบเดิม:

ฉันไม่คิดว่าคุณต้องการสคริปต์หรือไลบรารีขนาดใหญ่สำหรับสิ่งนั้น มันเป็นงานที่ค่อนข้างง่าย

ใส่องค์ประกอบต่อไปนี้ก่อน</body>:

<div class="device-xs visible-xs"></div>
<div class="device-sm visible-sm"></div>
<div class="device-md visible-md"></div>
<div class="device-lg visible-lg"></div>

4 divs เหล่านี้ช่วยให้คุณตรวจสอบเบรกพอยต์ที่ใช้งานอยู่ในปัจจุบัน สำหรับการตรวจจับ JS อย่างง่ายให้ใช้ฟังก์ชันต่อไปนี้:

function isBreakpoint( alias ) {
    return $('.device-' + alias).is(':visible');
}

ตอนนี้เพื่อดำเนินการบางอย่างกับเบรกพอยต์ที่เล็กที่สุดที่คุณสามารถใช้:

if( isBreakpoint('xs') ) {
    $('.someClass').css('property', 'value');
}

การตรวจจับการเปลี่ยนแปลงหลังจาก DOM พร้อมก็ค่อนข้างง่าย สิ่งที่คุณต้องมีก็คือตัวปรับขนาดหน้าต่างเบา ๆ แบบนี้:

var waitForFinalEvent = function () {
      var b = {};
      return function (c, d, a) {
        a || (a = "I am a banana!");
        b[a] && clearTimeout(b[a]);
        b[a] = setTimeout(c, d)
      }
    }();

var fullDateString = new Date();

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

$(window).resize(function () {
    waitForFinalEvent(function(){

        if( isBreakpoint('xs') ) {
            $('.someClass').css('property', 'value');
        }

    }, 300, fullDateString.getTime())
});

3
ไม่ได้ผลสำหรับฉัน viewport.current () ให้ผลตอบแทนที่ 'ไม่รู้จัก' เสมอ ฉันกำลังทำอะไรผิดหรือเปล่า?
starbugs

คุณมีซอหรือไม่? แก้ไข: เป็นไปได้หรือไม่ที่คุณรวมสคริปต์ของคุณรวมถึง RBT ไว้ในส่วนหัวแทนที่จะเป็นเนื้อหา? ที่จะป้องกันไม่ให้มีการเพิ่ม divs การมองเห็นลงในเนื้อความ
Maciej Gurban

@ MaciejGurban ฉันไม่สามารถทำงานได้ ฉันใช้ Rails 4.2 ฉันรวมถึง bootstrap ในหัวของฉัน แต่สคริปต์ของคุณในร่างกาย แต่มันก็บอกว่าไม่รู้จัก ตกลงปัญหาของฉันฉันได้เพิ่มทุกอย่างในร่างกาย แต่สิ่งนี้จำเป็นจริงๆหรือ
เดนนิส

อีกครั้งมันเป็นเรื่องยากที่จะบอกปัญหาโดยไม่มีซอหรือโค้ดตัวอย่าง คุณสามารถถามคำถามเกี่ยวกับมันใน SO และอ้างอิงได้ที่นี่หรือเปิดปัญหาใน GitHub คุณได้ทำตามคำสั่งของรวมชิ้นส่วนทั้งหมดไว้ในCodePenหรือไม่? ฟังก์ชันนั้นใช้งานไม่ได้หรือไม่ ปัญหาอาจเป็นเช่นนี้ไหม
Maciej Gurban

1
วิธีนี้สามารถใช้กับ bootstrap 4 ได้อย่างไร
Calonthar

64

หากคุณไม่มีความต้องการเฉพาะคุณสามารถทำสิ่งนี้ได้:

if ($(window).width() < 768) {
    // do something for small screens
}
else if ($(window).width() >= 768 &&  $(window).width() <= 992) {
    // do something for medium screens
}
else if ($(window).width() > 992 &&  $(window).width() <= 1200) {
    // do something for big screens
}
else  {
    // do something for huge screens
}

แก้ไข: ฉันไม่เห็นสาเหตุที่คุณควรใช้ไลบรารี js อื่นเมื่อคุณสามารถทำได้ด้วย jQuery ที่รวมอยู่ในโครงการ Bootstrap ของคุณแล้ว


ขอขอบคุณคุณสามารถให้ผู้ฟังสำหรับกิจกรรมทั้งหมดที่เรียกใช้การเปลี่ยนแปลงขนาดหน้าจอได้หรือไม่
รูเบนส์ Mariuzzo

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

2
ฉันรู้ว่าฉันแค่มองพฤติกรรมที่คล้ายกันใน JS รับฟังการเปลี่ยนแปลงขนาดหน้าจอจริงด้วย: $(window).bind('resize')... แต่มีเหตุการณ์อื่น ๆ ที่เกี่ยวข้องกับการวางแนวหน้าจอมือถือที่ส่งผลกระทบต่อขนาดหน้าจอ
รูเบนส์ Mariuzzo

การวางแนวอุปกรณ์ยังคงเป็นคุณลักษณะทดลอง: developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEventฉันขอแนะนำให้คุณใช้.on('resize')
mtt

1
ฉันเคยได้ยินกรณีที่วิธีการตรวจสอบสถานะนี้ทำให้เกิดปัญหา มันจะเป็นการดีกว่าถ้าคุณมีบางสิ่งที่ตรวจสอบองค์ประกอบผู้ช่วยที่มองเห็นได้ - เพื่อความปลอดภัยจากทุกมุม
Manuel Arwed Schmidt

11

คุณได้ดู Response.js แล้วหรือยัง? มันถูกออกแบบมาสำหรับสิ่งนี้ รวม Response.band และ Response.resize

http://responsejs.com/

Response.resize(function() {
    if ( Response.band(1200) )
    {
       // 1200+
    }    
    else if ( Response.band(992) )
    {
        // 992+
    }
    else if ( Response.band(768) )
    {
        // 768+
    }
    else 
    {
        // 0->768
    }
});

ห้องสมุดที่น่าสนใจแม้ว่าจะไม่ได้ออกแบบด้วย Twitter Bootstrap 3 ในใจ อย่างไรก็ตามดูเหมือนว่ามันจะสามารถดัดแปลงเป็น TWBS3 ได้อย่างง่ายดาย
รูเบนส์ Mariuzzo

11

คุณสามารถใช้ขนาดหน้าต่างและรหัสฮาร์พเบรก ใช้เชิงมุม:

angular
    .module('components.responsiveDetection', [])
    .factory('ResponsiveDetection', function ($window) {
        return {
            getBreakpoint: function () {
                var w = $window.innerWidth;
                if (w < 768) {
                    return 'xs';
                } else if (w < 992) {
                    return 'sm';
                } else if (w < 1200) {
                    return 'md';
                } else {
                    return 'lg';
                }
            }
        };
    });

ฉันชอบคำตอบนี้ ไม่ต้องใช้ไลบรารีอื่น ๆ (แม้แต่ jQuery)
dprothero

11

ตรวจหาเบรกพอยต์ตอบสนองของ Twitter Bootstrap 4.1.x โดยใช้ JavaScript

Bootstrap v.4.0.0 (และรุ่นล่าสุดBootstrap 4.1.x ) แนะนำการปรับปรุงตัวเลือกตารางดังนั้นแนวคิดเดิมในการตรวจสอบอาจจะไม่ถูกนำมาใช้โดยตรง (ดูคำแนะนำการโยกย้าย ):

  • เพิ่มใหม่ smระดับกริดด้านล่าง768pxเพื่อการควบคุมที่ละเอียดยิ่งขึ้น ขณะนี้เรามีxs, sm, md, lgและxl;
  • xs คลาสกริดได้รับการแก้ไขเพื่อไม่ต้องการให้มัด

ฉันเขียนฟังก์ชั่นยูทิลิตี้ขนาดเล็กที่เคารพชื่อตารางคลาสที่ได้รับการปรับปรุงและระดับกริดใหม่:

/**
 * Detect the current active responsive breakpoint in Bootstrap
 * @returns {string}
 * @author farside {@link https://stackoverflow.com/users/4354249/farside}
 */
function getResponsiveBreakpoint() {
    var envs = {xs:"d-none", sm:"d-sm-none", md:"d-md-none", lg:"d-lg-none", xl:"d-xl-none"};
    var env = "";

    var $el = $("<div>");
    $el.appendTo($("body"));

    for (var i = Object.keys(envs).length - 1; i >= 0; i--) {
        env = Object.keys(envs)[i];
        $el.addClass(envs[env]);
        if ($el.is(":hidden")) {
            break; // env detected
        }
    }
    $el.remove();
    return env;
};

ตรวจหาเบรกพอยต์ตอบสนองของ Bootstrap v4-beta โดยใช้ JavaScript

Bootstrap v4 อัลฟาและเงินทุน v4 เบต้ามีวิธีการที่แตกต่างกันในจุดพักตารางเพื่อให้ที่นี่เป็นวิธีการแบบเดิมของการบรรลุเดียวกัน:

/**
 * Detect and return the current active responsive breakpoint in Bootstrap
 * @returns {string}
 * @author farside {@link https://stackoverflow.com/users/4354249/farside}
 */
function getResponsiveBreakpoint() {
    var envs = ["xs", "sm", "md", "lg"];
    var env = "";

    var $el = $("<div>");
    $el.appendTo($("body"));

    for (var i = envs.length - 1; i >= 0; i--) {
        env = envs[i];
        $el.addClass("d-" + env + "-none");;
        if ($el.is(":hidden")) {
            break; // env detected
        }
    }
    $el.remove();
    return env;
}

ฉันคิดว่ามันจะมีประโยชน์เพราะมันง่ายที่จะรวมเข้ากับโครงการใด ๆ มันใช้คลาสการแสดงผลตอบสนองดั้งเดิมของ Bootstrap เอง


7

นี่คือทางออกที่เรียบง่ายของฉันเอง:

jQuery:

function getBootstrapBreakpoint(){
    var w = $(document).innerWidth();
    return (w < 768) ? 'xs' : ((w < 992) ? 'sm' : ((w < 1200) ? 'md' : 'lg'));
}

VanillaJS:

function getBootstrapBreakpoint(){
    var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    return (w < 768) ? 'xs' : ((w < 992) ? 'sm' : ((w < 1200) ? 'md' : 'lg'));
}

5

การใช้วิธีการนี้กับResponse.jsดีกว่า Response.resize ทริกเกอร์ในทุกหน้าต่างปรับขนาดที่ครอสโอเวอร์จะถูกทริกเกอร์หากเปลี่ยนจุดพัก

Response.create({
    prop : "width",
    breakpoints : [1200, 992, 768, 480, 320, 0]
});

Response.crossover('width', function() {
    if (Response.band(1200)) {
        // 1200+

    } else if (Response.band(992)) {
        // 992+

    } else if (Response.band(768)) {
        // 768+

    } else if (Response.band(480)) {
        //480+

    } else {
        // 0->320

    }
});

Response.ready(function() {
    $(window).trigger('resize');
});

4

ไม่ควรมีปัญหากับการใช้งานด้วยตนเองเช่นเดียวกับที่กล่าวถึงโดย @oozic

นี่คือ libs สองสามข้อที่คุณสามารถดูได้:

  • Response.js - jQuery plugin - ใช้ประโยชน์จากคุณสมบัติข้อมูล html และยังมี js api
  • enquire.js - enquire.js เป็นไลบรารี่ JavaScript ที่มีน้ำหนักเบาและบริสุทธิ์เพื่อตอบสนองต่อการสืบค้นสื่อ CSS
  • SimpleStateManager - ผู้จัดการรัฐ javascript สำหรับเว็บไซต์ที่ตอบสนอง มันถูกสร้างขึ้นให้มีน้ำหนักเบาไม่มีการพึ่งพา

โปรดทราบว่า libs เหล่านี้ออกแบบมาเพื่อทำงานโดยอิสระจาก bootstrap, รากฐาน ฯลฯ คุณสามารถกำหนดค่าเบรกพอยต์ของคุณเองและสนุกสนาน


3
Enquire.js ดูมีแนวโน้ม
รูเบนส์ Mariuzzo

4

คุณอาจต้องการเพิ่มสิ่งนี้ลงในโครงการ bootstrap ของคุณเพื่อตรวจสอบเบรกพอยต์ที่ใช้งานอยู่

    <script type='text/javascript'>

        $(document).ready(function () {

            var mode;

            $('<div class="mode-informer label-info" style="z-index:1000;position: fixed;bottom:10px;left:10px">%mode%</div>').appendTo('body');


            var checkMode = function () {

                if ($(window).width() < 768) {
                    return 'xs';
                }
                else if ($(window).width() >= 768 && $(window).width() < 992) {
                    return 'sm';
                }
                else if ($(window).width() >= 992 && $(window).width() < 1200) {
                    return 'md';
                }
                else {
                    return 'lg';
                }
            };

            var compareMode = function () {
                if (mode !== checkMode()) {
                    mode = checkMode();

                    $('.mode-informer').text(mode).animate({
                        bottom: '100'
                    }, 100, function () {
                        $('.mode-informer').animate({bottom: 10}, 100)
                    });
                }
            };

            $(window).on('resize', function () {
                compareMode()
            });

            compareMode();

        });

    </script>

นี่คือBOOTPLY


4

การสร้างตามคำตอบของ Maciej Gurban (ซึ่งยอดเยี่ยม ... ถ้าคุณชอบสิ่งนี้โปรดแค่โหวตให้เขาตอบ) หากคุณกำลังสร้างบริการเพื่อสอบถามคุณสามารถคืนบริการที่ใช้งานในปัจจุบันด้วยการตั้งค่าด้านล่าง สิ่งนี้สามารถแทนที่ไลบรารีการตรวจหาเบรกพอยต์อื่น ๆ ทั้งหมด (เช่น enquire.js หากคุณใส่ในบางเหตุการณ์)โปรดทราบว่าฉันได้เพิ่มคอนเทนเนอร์ที่มี ID ในองค์ประกอบ DOM เพื่อเพิ่มความเร็วในการแวะผ่าน DOM

HTML

<div id="detect-breakpoints">
    <div class="breakpoint device-xs visible-xs"></div>
    <div class="breakpoint device-sm visible-sm"></div>
    <div class="breakpoint device-md visible-md"></div>
    <div class="breakpoint device-lg visible-lg"></div>
</div>

COFFEESCRIPT (AngularJS แต่แปลงได้อย่างง่ายดาย)

# this simple service allows us to query for the currently active breakpoint of our responsive app
myModule = angular.module('module').factory 'BreakpointService', ($log) ->

  # alias could be: xs, sm, md, lg or any over breakpoint grid prefix from Bootstrap 3
  isBreakpoint: (alias) ->
    return $('#detect-breakpoints .device-' + alias).is(':visible')

  # returns xs, sm, md, or lg
  getBreakpoint: ->
    currentBreakpoint = undefined
    $visibleElement = $('#detect-breakpoints .breakpoint:visible')
    breakpointStringsArray = [['device-xs', 'xs'], ['device-sm', 'sm'], ['device-md', 'md'], ['device-lg', 'lg']]
    # note: _. is the lodash library
    _.each breakpointStringsArray, (breakpoint) ->
      if $visibleElement.hasClass(breakpoint[0])
        currentBreakpoint = breakpoint[1]
    return currentBreakpoint

JAVASCRIPT (AngularJS)

var myModule;

myModule = angular.module('modules').factory('BreakpointService', function($log) {
  return {
    isBreakpoint: function(alias) {
      return $('#detect-breakpoints .device-' + alias).is(':visible');
    },
    getBreakpoint: function() {
      var $visibleElement, breakpointStringsArray, currentBreakpoint;
      currentBreakpoint = void 0;
      $visibleElement = $('#detect-breakpoints .breakpoint:visible');
      breakpointStringsArray = [['device-xs', 'xs'], ['device-sm', 'sm'], ['device-md', 'md'], ['device-lg', 'lg']];
      _.each(breakpointStringsArray, function(breakpoint) {
        if ($visibleElement.hasClass(breakpoint[0])) {
          currentBreakpoint = breakpoint[1];
        }
      });
      return currentBreakpoint;
    }
  };
});

3

แทนที่จะใช้ $ (เอกสาร) .width () คุณควรตั้งกฎ CSS ที่ให้ข้อมูลนี้แก่คุณ

ฉันเพิ่งเขียนบทความเพื่อให้มันถูกต้อง ดูได้ที่นี่: http://www.xurei-design.be/2013/10/how-to-accurately-detect-responsive-breakpoints/


นี่เป็นวิธีที่ดีที่สุดในมุมมองของฉันตามที่อธิบายไว้ในคำตอบนี้: stackoverflow.com/a/22885503/439427
Rubens Mariuzzo

3

ทำไมไม่ใช้ jQuery เพื่อตรวจสอบความกว้าง css ปัจจุบันของคลาส bootstrap

คือ ..

if( parseInt($('#container').css('width')) > 1200 ){
  // do something for desktop screens
}

คุณสามารถใช้ $ (หน้าต่าง). resize () เพื่อป้องกันเลย์เอาต์ของคุณจาก "สกปรกบนเตียง" ถ้ามีคนปรับขนาดหน้าต่างเบราว์เซอร์


3

แทนที่จะแทรกข้างล่างหลาย ๆ ครั้งลงในแต่ละหน้า ...

<div class="device-xs visible-xs"></div>
<div class="device-sm visible-sm"></div>
<div class="device-md visible-md"></div>
<div class="device-lg visible-lg"></div>

เพียงใช้ JavaScript เพื่อแทรกมันแบบไดนามิกในทุก ๆ หน้า (โปรดทราบว่าฉันได้อัปเดตให้ทำงานกับ Bootstrap 3 ด้วย.visible-*-block:

// Make it easy to detect screen sizes
var bootstrapSizes = ["xs", "sm", "md", "lg"];
for (var i = 0; i < bootstrapSizes.length; i++) {
    $("<div />", {
        class: 'device-' + bootstrapSizes[i] + ' visible-' + bootstrapSizes[i] + '-block'
    }).appendTo("body");
}

2

ฉันไม่มีคะแนนชื่อเสียงพอที่จะแสดงความคิดเห็น แต่สำหรับผู้ที่มีปัญหาในการ "ไม่รู้จัก" เมื่อพวกเขาลองใช้ ResponsiveToolKit ของ Maciej Gurban ฉันยังได้รับข้อผิดพลาดนั้นจนกว่าฉันจะสังเกตเห็นว่า Maciej อ้างอิงชุดเครื่องมือจากด้านล่างของ หน้าใน CodePen ของเขา

ฉันลองทำมันและมันก็ใช้งานได้! ดังนั้นให้ใช้ ResponsiveToolkit แต่ใส่ลิงค์ของคุณไว้ที่ด้านล่างของหน้า:

ฉันไม่รู้ว่าทำไมมันถึงสร้างความแตกต่าง แต่มันก็เป็นเช่นนั้น


2

นี่เป็นอีกวิธีหนึ่งในการตรวจสอบวิวพอร์ตปัจจุบันโดยไม่ต้องใส่หมายเลขขนาดวิวพอร์ตในจาวาสคริปต์ของคุณ

ดูตัวอย่างโค้ด css และ javascript ได้ที่นี่: https://gist.github.com/steveh80/288a9a8bd4c3de16d799

หลังจากเพิ่มข้อมูลโค้ดลงในไฟล์ css และ javascript ของคุณคุณสามารถตรวจสอบวิวพอร์ตปัจจุบันเช่นนี้:

viewport.is('xs') // returns boolean

หากคุณต้องการตรวจจับช่วงวิวพอร์ตให้ใช้เช่นนี้

viewport.isEqualOrGreaterThan('sm') // returns true for sm, md and lg

2

Bootstrap's CSS สำหรับ.containerคลาสดูเหมือนว่า:

.container {
    padding-right: 15px;
    padding-left: 15px;
    margin-right: auto;
    margin-left: auto;
}
@media (min-width: 768px) {
    .container {
        width: 750px;
    }
}
@media (min-width: 992px) {
    .container {
        width: 970px;
    }
}
@media (min-width: 1200px) {
    .container {
        width: 1170px;
    }
}

ดังนั้นวิธีการนี้อย่างปลอดภัยเราสามารถพึ่งพาในการตรวจสอบจุดพักได้โดยไม่ต้องเสียของการพึ่งพาjQuery('.container').css('width')jQuery(window).width()

เราสามารถเขียนฟังก์ชันดังนี้:

function detectBreakpoint() {
    // Let's ensure we have at least 1 container in our pages.
    if (jQuery('.container').length == 0) {
        jQuery('body').append('<div class="container"></div>');
    }

    var cssWidth = jQuery('.container').css('width');

    if (cssWidth === '1170px') return 'lg';
    else if (cssWidth === '970px') return 'md';
    else if (cssWidth === '750px') return 'sm';

    return 'xs';
}

จากนั้นทดสอบเหมือนกัน

jQuery(document).ready(function() {
    jQuery(window).resize(function() {
        jQuery('p').html('current breakpoint is: ' + detectBreakpoint());
    });

    detectBreakpoint();
});

สิ่งนี้จะทำงานที่ความกว้างที่ระบุเท่านั้น สิ่งใดในระหว่างจะล้มเหลว มันอาจเป็นการดีที่สุดที่: ก่อนอื่นแยกวิเคราะห์ใน cssWidth var cssWidth = parseInt( jQuery('.container').css('width') ); วินาทีใช้ช่วง if ( cssWidth < 768) { return 'xs'; } else if (cssWidth >= 768 && cssWidth <= 992) { return 'sm'; } else if (cssWidth > 992 && cssWidth <= 1200) { return 'md'; } else { return 'lg'; }
kakoma

2

ใช้ CSS :beforeและcontentคุณสมบัติเพื่อพิมพ์สถานะเบรกพอยต์ใน<span id="breakpoint-js">ดังนั้น JavaScript จึงต้องอ่านข้อมูลนี้เพื่อเปลี่ยนเป็นตัวแปรที่จะใช้ภายในฟังก์ชันของคุณ

(เรียกใช้ส่วนย่อยเพื่อดูตัวอย่าง)

หมายเหตุ: ฉันเพิ่ม CSS ไม่กี่บรรทัดเพื่อใช้<span>เป็นธงสีแดงที่มุมด้านบนของเบราว์เซอร์ของฉัน เพียงตรวจสอบให้แน่ใจว่าได้เปลี่ยนกลับเป็นdisplay:none;ก่อนที่จะเผยแพร่ข้อมูลของคุณสู่สาธารณะ

// initialize it with jquery when DOM is ready
$(document).on('ready', function() {
    getBootstrapBreakpoint();
});

// get bootstrap grid breakpoints
var theBreakpoint = 'xs'; // bootstrap336 default = mobile first
function getBootstrapBreakpoint(){
   theBreakpoint = window.getComputedStyle(document.querySelector('#breakpoint-js'),':before').getPropertyValue('content').replace(/['"]+/g, '');
   console.log('bootstrap grid breakpoint = ' + theBreakpoint);
}
#breakpoint-js {
  /* display: none; //comment this while developping. Switch back to display:NONE before commit */
  /* optional red flag layout */
  position: fixed;
  z-index: 999;
  top: 0;
  left: 0;
  color: white;
  padding: 5px 10px;
  background-color: red;
  opacity: .7;
  /* end of optional red flag layout */
}
#breakpoint-js:before {
  content: 'xs'; /* default = mobile first */
}
@media screen and (min-width: 768px) {
  #breakpoint-js:before {
    content: 'sm';
  }
}
@media screen and (min-width: 992px) {
  #breakpoint-js:before {
    content: 'md';
  }
}
@media screen and (min-width: 1200px) {
  #breakpoint-js:before {
    content: 'lg';
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

<div class="container">
  <span id="breakpoint-js"></span>
  <div class="page-header">
    <h1>Bootstrap grid examples</h1>
    <p class="lead">Basic grid layouts to get you familiar with building within the Bootstrap grid system.</p>
  </div>
</div>


1

ฉันได้ทำวิธี jQuery ดั้งเดิมสำหรับการตรวจจับขนาดหน้าจอ Twitter Bootstrap ที่นี่คือ:

// Screen size ID will be stored in this variable (global var for JS)
var CurrentBootstrapScreenSize = 'unknown';

$(document).ready(function () {

    // <div> objects for all screen sizes required for screen size detection.
    // These <div> is hidden for users eyes.
    var currentScreenSizeDetectorObjects = $('<div>').css({
            'position':'absolute',
            'top':'-200px'
        }).addClass('current-screen-size').append([
            $('<div>').addClass('device-xs visible-xs').html('&nbsp;'),
            $('<div>').addClass('device-sm visible-sm').html('&nbsp;'),
            $('<div>').addClass('device-md visible-md').html('&nbsp;'),
            $('<div>').addClass('device-lg visible-lg').html('&nbsp;')
        ]);

    // Attach <div> objects to <body>
    $('body').prepend(currentScreenSizeDetectorObjects);

    // Core method for detector
    function currentScreenSizeDetectorMethod() {
        $(currentScreenSizeDetectorObjects).find('div').each(function() {
            var className = $(this).attr('class');
            if($(this).is(':visible')) {
                if(String(className).match(/device-xs/)) CurrentBootstrapScreenSize = 'xs';
                else if(String(className).match(/device-sm/)) CurrentBootstrapScreenSize = 'sm';
                else if(String(className).match(/device-md/)) CurrentBootstrapScreenSize = 'md';
                else if(String(className).match(/device-lg/)) CurrentBootstrapScreenSize = 'lg';
                else CurrentBootstrapScreenSize = 'unknown';
            };
        })
        console.log('Current Bootstrap screen size is: '+CurrentBootstrapScreenSize);
        $('.CurrentBootstrapScreenSize').first().html('Bootstrap current screen size: <b>' + CurrentBootstrapScreenSize + '</b>' );
    }

    // Bind screen size and orientation change
    $(window).bind("resize orientationchange", function() {
        // Execute screen detection
        currentScreenSizeDetectorMethod();
    });

    // Execute screen detection on page initialize
    currentScreenSizeDetectorMethod();

});

JSFillde: https://jsfiddle.net/pstepniewski/7dz6ubus/

JSFillde เป็นตัวอย่างแบบเต็มหน้าจอ: https://jsfiddle.net/pstepniewski/7dz6ubus/embedded/result/


1

สำหรับผู้ที่สนใจในสิ่งนี้ฉันเขียนการตรวจจับเบรกพอยต์ตามจุดพัก CSS โดยใช้ TypeScript และ Observables มันไม่ยากที่จะทำให้ ES6 ออกมาถ้าคุณลบประเภท ในตัวอย่างของฉันฉันใช้ Sass แต่มันก็ง่ายที่จะลบ

นี่คือ JSFiddle ของฉัน: https://jsfiddle.net/StefanJelner/dorj184g/

HTML:

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.7/Rx.min.js"></script>
<div id="result"></div>

SCSS:

body::before {
  content: 'xs';
  display: none;

  @media screen and (min-width: 480px) {
    content: 's';
  }

  @media screen and (min-width: 768px) {
    content: 'm';
  }

  @media screen and (min-width: 1024px) {
    content: 'l';
  }

  @media screen and (min-width: 1280px) {
    content: 'xl';
  }
}

typescript:

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';

class BreakpointChangeService {
    private breakpointChange$: BehaviorSubject<string>;

    constructor(): BehaviorSubject<string> {
        // initialize BehaviorSubject with the current content of the ::before pseudo element
        this.breakpointChange$ = new Rx.BehaviorSubject(this.getBreakpoint());

        // observe the window resize event, throttle it and combine it with the BehaviorSubject
        Rx.Observable
            .fromEvent(window, 'resize')
            .throttleTime(0, Rx.Scheduler.animationFrame)
            .withLatestFrom(this.breakpointChange$)
            .subscribe(this.update.bind(this))
        ;

        return this.breakpointChange$;
    }

    // method to get the content of the ::before pseudo element
    private getBreakpoint(): string {
        // see https://www.lullabot.com/articles/importing-css-breakpoints-into-javascript
        return window.getComputedStyle(document.body, ':before').getPropertyValue('content').replace(/[\"\']/g, '');
    }

    private update(_, recent): void {
        var current = this.getBreakpoint();
        if(recent !== current) { this.breakpointChange$.next(current); }
    }
}

// if the breakpoint changes, react on it
var $result = document.getElementById('result');
new BreakpointChangeService().subscribe(breakpoint => {
    $result.innerHTML = Date.now()+': '+breakpoint;
});

ฉันหวังว่านี่จะช่วยให้ใครบางคน


1

Bootstrap4 พร้อม jQuery โซลูชันที่ง่ายขึ้น

<div class="device-sm d-sm-none"></div>
<div class="device-md d-md-none"></div>
<div class="device-lg d-lg-none"></div>
<div class="device-xl d-xl-none"></div>
<script>
var size = $('.device-xl').is(':hidden') ? 'xl' : ($('.device-lg').is(':hidden') ? 'lg'
    : ($('.device-md').is(':hidden') ? 'md': ($('.device-sm').is(':hidden') ? 'sm' : 'xs')));
alert(size);
</script>

1

ฉันไม่พอใจกับคำตอบที่ได้รับซึ่งดูเหมือนจะซับซ้อนเกินกว่าจะใช้กับฉันดังนั้นฉันจึงเขียนวิธีแก้ปัญหาของตัวเอง อย่างไรก็ตามในขณะนี้ขึ้นอยู่กับขีดล่าง / lodash ในการทำงาน

https://github.com/LeShrimp/GridSizeEvents

คุณสามารถใช้สิ่งนี้:

GridSizeEvents.addListener(function (newSize, oldSize) {
    // Will output eg. "xs -> sm"
    console.log(oldSize + ' -> ' + newSize);
});

วิธีนี้ใช้งานได้กับ Box สำหรับ Bootstrap 3 เนื่องจากเบรกพอยต์นั้นเขียนรหัสไว้ที่ 768px, 992px และ 1200px สำหรับรุ่นอื่นคุณสามารถปรับเปลี่ยนรหัสได้อย่างง่ายดาย

ภายในนี้ใช้matchMedia ()และควรรับประกันว่าจะให้ผลลัพธ์ที่สอดคล้องกับ Bootstrap


1

บางทีมันอาจช่วยคุณได้บ้าง แต่ก็มีปลั๊กอินที่ช่วยให้คุณตรวจจับจุดพักBootstrap v4 ที่คุณเห็น: https://www.npmjs.com/package/bs-breakpoints

ใช้งานง่าย (สามารถใช้โดยมีหรือไม่มี jQuery):

$(document).ready(function() {
  bsBreakpoints.init()
  console.warn(bsBreakpoint.getCurrentBreakpoint())

  $(window).on('new.bs.breakpoint', function (event) {
    console.warn(event.breakpoint)
  })
})

1

นี่คือทางออกของฉัน (Bootstrap 4):

<div class="alert alert-warning row">
    <div class="col">
        Bootstrap breakpoint is
    </div>
    <div class="col">
        <div class="d-block d-sm-none">
            XS
        </div>
        <div class="d-none d-sm-block d-md-none">
            SM
        </div>
        <div class="d-none d-md-block d-lg-none">
            MD
        </div>
        <div class="d-none d-lg-block d-xl-none">
            MD
        </div>
        <div class="d-none d-xl-block">
            MD
        </div>
    </div>
</div>

0

สำหรับใครก็ตามที่ใช้knockout.jsฉันต้องการคุณสมบัติที่น่าติดตามที่น่าติดตามซึ่งจะบอกฉันเมื่อเบรกพอยต์ถูกโจมตี ฉันเลือกที่จะใช้การสนับสนุนของ Modernizr สำหรับการสืบค้นสื่อ css-styleดังนั้นตัวเลขจึงตรงกับคำจำกัดความ bootstrap และเพื่อให้ได้ประโยชน์จากความเข้ากันได้ของ modernizr โมเดลมุมมองที่น่าพิศวงของฉันเป็นดังนี้:

var viewModel = function() {
    // depends on jquery, Modernizr
    var self = this;
    self.widthXsOrLess = ko.observable();
    self.widthSmOrLess = ko.observable();
    self.widthMdOrLess = ko.observable();
    var setWindowSizeVars = function() {
        self.widthXsOrLess(!Modernizr.mq('(min-width: 768px)'));
        self.widthSmOrLess(!Modernizr.mq('(min-width: 992px)'));
        self.widthMdOrLess(!Modernizr.mq('(min-width: 1200px)'));
    };
    $(window).resize(setWindowSizeVars);
    setWindowSizeVars();
};

0

นี่เป็นวิธีที่ดีในการตรวจจับ (อาจตลก แต่ใช้ได้ผล) และคุณสามารถใช้องค์ประกอบที่จำเป็นเพื่อให้รหัสชัดเจน:

ตัวอย่าง: css:

@media (max-width: 768px) {
    #someElement
    {
         background: pink
    }
}

และในเอกสารโดย jQuery:

if($('#someElement').css('background') == 'pink')
{
    doWhatYouNeed();
}

แน่นอนคุณสมบัติ CSS คือใด ๆ


0

เนื่องจาก bootstrap 4 จะออกเร็ว ๆ นี้ฉันคิดว่าฉันจะแบ่งปันฟังก์ชั่นที่รองรับ (ตอนนี้ xl กลายเป็นเรื่อง) และดำเนินการ jQuery ขั้นต่ำเพื่อให้งานเสร็จ

/**
 * Get the Bootstrap device size
 * @returns {string|boolean} xs|sm|md|lg|xl on success, otherwise false if Bootstrap is not working or installed
 */
function findBootstrapEnvironment() {
    var environments = ['xs', 'sm', 'md', 'lg', 'xl'];
    var $el = $('<span />');
    $el.appendTo($('body'));
    for (var i = environments.length - 1; i >= 0; i--) {
        var env = environments[i];
        $el.addClass('hidden-'+env);
        if ($el.is(':hidden')) {
            $el.remove();
            return env;
        }
    }
    $el.remove();
    return false;
}

0

Bootstrap 4

setResponsiveDivs();

function setResponsiveDivs() {
    var data = [
        {id: 'visible-xs', class: 'd-block d-sm-none'},
        {id: 'visible-sm', class: 'd-none d-sm-block d-md-none'},
        {id: 'visible-md', class: 'd-none d-md-block d-lg-none'},
        {id: 'visible-lg', class: 'd-none d-lg-block d-xl-none'},
        {id: 'visible-xl', class: 'd-none d-xl-block'}
    ];

    for (var i = 0; i < data.length; i++) {
        var el = document.createElement("div");
        el.setAttribute('id', data[i].id);
        el.setAttribute('class', data[i].class);
        document.getElementsByTagName('body')[0].appendChild(el);
    }
}

function isVisible(type) {
    return window.getComputedStyle(document.getElementById('visible-' + type), null).getPropertyValue('display') === 'block';
}

// then, at some point
window.onresize = function() {
    console.log(isVisible('xs') === true ? 'xs' : '');
    console.log(isVisible('sm') === true ? 'sm' : '');
    console.log(isVisible('md') === true ? 'md' : '');
    console.log(isVisible('lg') === true ? 'lg' : '');
    console.log(isVisible('xl') === true ? 'xl' : '');
};

หรือย่อให้เล็กลง

function setResponsiveDivs(){for(var e=[{id:"visible-xs","class":"d-block d-sm-none"},{id:"visible-sm","class":"d-none d-sm-block d-md-none"},{id:"visible-md","class":"d-none d-md-block d-lg-none"},{id:"visible-lg","class":"d-none d-lg-block d-xl-none"},{id:"visible-xl","class":"d-none d-xl-block"}],s=0;s<e.length;s++){var l=document.createElement("div");l.setAttribute("id",e[s].id),l.setAttribute("class",e[s]["class"]),document.getElementsByTagName("body")[0].appendChild(l)}}function isVisible(e){return"block"===window.getComputedStyle(document.getElementById("visible-"+e),null).getPropertyValue("display")}setResponsiveDivs();


0

หากคุณใช้สิ่งที่น่าพิศวงคุณสามารถใช้การโยงแบบกำหนดเองต่อไปนี้เพื่อผูกเบรกพอยต์จุดชมวิวปัจจุบัน (xs, sm, md หรือ lg) กับสิ่งที่สังเกตได้ในแบบจำลองของคุณ ความผูกพัน ...

  • แรป 4 divsกับvisible-??การเรียนใน div กับรหัสdetect-viewportและเพิ่มเข้าไปใน body หากยังไม่มีอยู่ (ดังนั้นคุณสามารถนำการผูกนี้มาใช้ใหม่โดยไม่ต้องทำซ้ำ div เหล่านี้)
  • ตั้งค่าเบรกพอยต์ viewport ปัจจุบันเป็นขอบเขตที่สังเกตได้โดยการสอบถามว่า divs ใดที่สามารถมองเห็นได้
  • อัพเดตจุดพัก viewport ปัจจุบันเมื่อปรับขนาดหน้าต่าง

ko.bindingHandlers['viewport'] = {
    init: function(element, valueAccessor) {
        if (!document.getElementById('detect-viewport')) {
            let detectViewportWrapper = document.createElement('div');
            detectViewportWrapper.id = 'detect-viewport';
            
            ["xs", "sm", "md", "lg"].forEach(function(breakpoint) {
                let breakpointDiv = document.createElement('div');
                breakpointDiv.className = 'visible-' + breakpoint;
                detectViewportWrapper.appendChild(breakpointDiv);
            });

            document.body.appendChild(detectViewportWrapper);
        }

        let setCurrentBreakpoint = function() {
            valueAccessor()($('#detect-viewport div:visible')[0].className.substring('visible-'.length));
        }
      
        $(window).resize(setCurrentBreakpoint);
        setCurrentBreakpoint();
    }
};

ko.applyBindings({
  currentViewPort: ko.observable()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div data-bind="viewport: currentViewPort"></div>
<div>    
    Current viewport breakpoint: <strong data-bind="text: currentViewPort"></strong>
</div>
<div>
    (Click the <em>full page</em> link of this snippet to test the binding with different window sizes)
</div>


0

เป็นเวลานานแล้วตั้งแต่ OP แต่นี่คือวิธีแก้ปัญหาของฉันสำหรับการใช้ Bootstrap 3 ในกรณีที่ใช้งานของฉันฉันเป็นเพียงการกำหนดเป้าหมายแถว แต่สามารถนำไปใช้กับคอนเทนเนอร์ได้เช่นเดียวกัน

เพียงแค่เปลี่ยนไปยังสิ่งที่คุณต้องการ

jQuery(document).ready(function ($) {

    var alterClass = function () {

        var ww = document.body.clientWidth;

        if (ww < 768) {

            $('.row').addClass('is-xs').removeClass('is-sm').removeClass('is-lg').removeClass('is-md');

        } else if (ww >= 768 && ww < 992) {

            $('.row').addClass('is-sm').removeClass('is-xs').removeClass('is-lg').removeClass('is-md');

        } else if (ww >= 992 && ww < 1200) {

            $('.row').addClass('is-md').removeClass('is-xs').removeClass('is-lg').removeClass('is-sm');

        } else if (ww >= 1200) {

            $('.row').addClass('is-lg').removeClass('is-md').removeClass('is-sm').removeClass('is-xs');

        };
    };

    // Make Changes when the window is resized
    $(window).resize(function () {
        alterClass();
    });

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