Làm cách nào để phát hiện các điểm dừng đáp ứng của Twitter Bootstrap 3 bằng JavaScript?


139

Hiện tại , Twitter Bootstrap 3 có các điểm dừng đáp ứng sau: 768px, 992px và 1200px, tương ứng với các thiết bị nhỏ, vừa và lớn.

Làm cách nào để phát hiện các điểm dừng này bằng JavaScript?

Tôi muốn nghe bằng JavaScript cho tất cả các sự kiện liên quan được kích hoạt khi màn hình thay đổi. Và để có thể phát hiện xem màn hình dành cho các thiết bị nhỏ, vừa hay lớn.

Có một cái gì đó đã được thực hiện? Đề xuất của bạn là gì?


Bạn có thể sử dụng IntersectionObserver để phát hiện khi <div class="d-none d-?-block"></div>thay đổi mức độ hiển thị (chèn điểm dừng mong muốn của bạn). Các lớp CSS đó dành cho Bootstrap 4 ... sử dụng bất cứ thứ gì hoạt động trong Bootstrap 3. Hiệu suất cao hơn nhiều so với nghe sự kiện thay đổi kích thước cửa sổ.
Matt Thomas

Câu trả lời:


241

Chỉnh sửa: Thư viện này hiện có sẵn thông qua Bower và NPM. Xem repo github để biết chi tiết.

CẬP NHẬT TRẢ LỜI:

Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả.

Dưới đây là một số điều bạn có thể thực hiện bằng phiên bản mới nhất (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);

Kể từ phiên bản 2.3.0, bạn không cần bốn <div>yếu tố được đề cập dưới đây.


TRẢ LỜI GỐC:

Tôi không nghĩ rằng bạn cần bất kỳ kịch bản hoặc thư viện lớn cho điều đó. Đây là một nhiệm vụ khá đơn giản.

Chèn các yếu tố sau ngay trước </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 div này cho phép bạn kiểm tra điểm dừng hiện đang hoạt động. Để phát hiện JS dễ dàng, hãy sử dụng chức năng sau:

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

Bây giờ để thực hiện một hành động nhất định chỉ trên điểm dừng nhỏ nhất bạn có thể sử dụng:

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

Phát hiện các thay đổi sau khi DOM sẵn sàng cũng khá đơn giản. Tất cả bạn cần là một cửa sổ nhẹ thay đổi kích thước người nghe như thế này:

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

Khi bạn đã được trang bị nó, bạn có thể bắt đầu lắng nghe các thay đổi và thực hiện các chức năng dành riêng cho điểm dừng như vậy:

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

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

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

3
Không làm việc cho tôi. viewport.cản () luôn mang lại 'không được nhận dạng'. Tôi có làm điều gì sai?
starbugs

Bạn có một câu đố? Chỉnh sửa: Có thể là bạn bao gồm các tập lệnh của mình, bao gồm RBT trong phần đầu, thay vì phần thân? Điều đó sẽ ngăn các div tầm nhìn được thêm vào cơ thể, do đó phá vỡ chức năng.
Maciej Gurban

@MaciejGurban Tôi cũng không thể làm cho nó hoạt động được. Tôi đang sử dụng Rails 4.2. Tôi đang bao gồm bootstrap trong đầu nhưng kịch bản của bạn trong cơ thể nhưng nó cứ nói không được nhận ra. Ok vấn đề của tôi, tôi đã thêm tất cả mọi thứ trong cơ thể. Nhưng điều này có thực sự cần thiết?
Dennis

Một lần nữa, thật khó để nói vấn đề mà không có mã mẫu hoặc mã mẫu. Bạn có thể đặt câu hỏi về nó trên SO và tham khảo nó ở đây, hoặc mở một vấn đề trên github. Bạn đã làm theo thứ tự bao gồm tất cả các phần như trên CodePen chưa? Có phải chức năng đó không hoạt động? Vấn đề có thể như thế này ?
Maciej Gurban

1
Làm thế nào điều này có thể được sử dụng với bootstrap 4?
Calonthar

64

Nếu bạn không có nhu cầu cụ thể, bạn có thể làm điều này:

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
}

Chỉnh sửa: Tôi không thấy lý do tại sao bạn nên sử dụng thư viện js khác khi bạn có thể làm điều này chỉ với jQuery đã có trong dự án Bootstrap của bạn.


Cảm ơn, bạn cũng có thể cung cấp cho người nghe tất cả các sự kiện kích hoạt thay đổi kích thước màn hình không?
Rubens Mariuzzo

Tôi không nghĩ có sự kiện thay đổi kích thước màn hình. Mọi thứ liên quan đến kích thước màn hình (truy vấn phương tiện) đều có trong biểu định kiểu.
mtt

2
Tôi biết rằng, tôi chỉ đang tìm kiếm một hành vi tương tự trong JS. Thực tế lắng nghe thay đổi kích thước màn hình với: $(window).bind('resize')... nhưng có những sự kiện khác liên quan đến hướng màn hình di động tác động đến kích thước màn hình.
Rubens Mariuzzo

Định hướng thiết bị vẫn là một tính năng thử nghiệm: developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent Tôi khuyên bạn nên sử dụng.on('resize')
mtt

1
Tôi đã nghe nói về các trường hợp cách phát hiện trạng thái này gây ra vấn đề. Tốt hơn hết là bạn nên kiểm tra các yếu tố trợ giúp hữu hình imho - để an toàn trước mọi trường hợp góc.
Manuel Arwed Schmidt

11

Bạn đã xem qua Feedback.js chưa? Nó được thiết kế cho loại điều này. Kết hợp Phản hồi.band và Phản hồi.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
    }
});

Thư viện thú vị, mặc dù nó không được thiết kế với Twitter Bootstrap 3. Dù sao, có vẻ như nó có thể dễ dàng thích nghi với TWBS3.
Rubens Mariuzzo

11

Bạn có thể sử dụng kích thước cửa sổ và mã cứng các điểm dừng. Sử dụng góc:

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

Tôi thích câu trả lời này. Không có thư viện khác (thậm chí không phải jQuery).
dprothero

11

Phát hiện điểm dừng đáp ứng của Twitter Bootstrap 4.1.x bằng JavaScript

Các Bootstrap v.4.0.0 (và phiên bản mới nhất Bootstrap 4.1.x ) đã giới thiệu cập nhật tùy chọn lưới , vì vậy khái niệm cũ trên phát hiện có thể không trực tiếp được áp dụng (xem các hướng dẫn di chuyển ):

  • Đã thêm một smlớp lưới mới bên dưới 768pxđể kiểm soát chi tiết hơn. Bây giờ chúng ta có xs, sm, md, lg, và xl;
  • xs các lớp lưới đã được sửa đổi để không yêu cầu infix.

Tôi đã viết hàm tiện ích nhỏ tôn trọng các tên lớp lưới được cập nhật và một lớp lưới mới:

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

Phát hiện điểm dừng đáp ứng của Bootstrap v4-beta bằng JavaScript

Các Bootstrap v4-alphaBootstrap v4-beta có cách tiếp cận khác nhau trên breakpoint lưới, vì vậy đây là cách di sản của việc đạt được như nhau:

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

Tôi nghĩ nó sẽ hữu ích, vì nó dễ dàng tích hợp vào bất kỳ dự án nào. Nó sử dụng các lớp hiển thị đáp ứng riêng của chính Bootstrap.


7

Đây là giải pháp đơn giản của riêng tôi:

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

Sử dụng phương pháp này với Feedback.js là tốt hơn. Feedback.resize kích hoạt trên mỗi cửa sổ thay đổi kích thước nơi giao nhau sẽ chỉ được kích hoạt nếu điểm dừng được thay đổi

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

Không có vấn đề gì với việc thực hiện thủ công như cách được đề cập bởi @oozic.

Dưới đây là một vài libs bạn có thể xem qua:

  • Feedback.js - Plugin jQuery - sử dụng các thuộc tính dữ liệu html và cũng có api js.
  • enquire.js - enquire.js là một thư viện JavaScript thuần túy, nhẹ để đáp ứng các truy vấn phương tiện CSS
  • SimpleStateManager - một trình quản lý trạng thái javascript cho các trang web phản hồi. Nó được xây dựng để có trọng lượng nhẹ, không có phụ thuộc.

Lưu ý rằng các lib này được thiết kế để hoạt động độc lập với bootstrap, nền tảng, v.v. Bạn có thể định cấu hình các điểm dừng của riêng mình và vui chơi.


3
Enquire.js có vẻ đầy hứa hẹn.
Rubens Mariuzzo

4

Bạn có thể muốn thêm phần này vào dự án bootstrap của mình để kiểm tra điểm dừng hoạt động một cách trực quan

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

Đây là BOOTPLY


4

Dựa trên câu trả lời của Maciej Gurban (thật tuyệt vời ... nếu bạn thích điều này, xin vui lòng bỏ phiếu cho câu trả lời của anh ấy). Nếu bạn đang xây dựng một dịch vụ để truy vấn, bạn có thể trả lại dịch vụ hiện đang hoạt động với cài đặt bên dưới. Điều này có thể thay thế hoàn toàn các thư viện phát hiện điểm dừng khác (như enquire.js nếu bạn đặt trong một số sự kiện). Lưu ý rằng tôi đã thêm một thùng chứa ID vào các thành phần DOM để tăng tốc độ truyền tải 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, nhưng điều này có thể chuyển đổi dễ dàng)

# 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

Tại sao không sử dụng jQuery để phát hiện chiều rộng css hiện tại của lớp container bootstrap?

I E..

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

Bạn cũng có thể sử dụng $ (window) .resize () để ngăn bố cục của bạn "làm bẩn giường" nếu ai đó thay đổi kích thước cửa sổ trình duyệt.


3

Thay vì chèn nhiều lần bên dưới vào mỗi trang ...

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

Chỉ cần sử dụng JavaScript để tự động chèn nó vào mỗi trang (lưu ý rằng tôi đã cập nhật nó để hoạt động với Bootstrap 3 với .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

Tôi không có đủ điểm danh tiếng để bình luận nhưng đối với những người gặp vấn đề với việc "không nhận ra" khi họ thử sử dụng ResponsiveToolKit của Maciej Gurban, tôi cũng đã nhận được lỗi đó cho đến khi tôi nhận thấy rằng Maciej thực sự tham khảo bộ công cụ từ dưới cùng của trang trong CodePen của mình

Tôi đã thử làm điều đó và đột nhiên nó làm việc! Vì vậy, hãy sử dụng ResponsiveToolkit nhưng đặt các liên kết của bạn ở cuối trang:

Tôi không biết tại sao nó làm cho một sự khác biệt nhưng nó làm.


2

Đây là một cách khác để phát hiện chế độ xem hiện tại mà không cần đặt số kích thước chế độ xem trong javascript của bạn.

Xem đoạn trích css và javascript tại đây: https://gist.github.com/steveh80/288a9a8bd4c3de16d799

Sau khi thêm đoạn mã đó vào tệp css và javascript của bạn, bạn có thể phát hiện chế độ xem hiện tại như sau:

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

Nếu bạn muốn phát hiện phạm vi khung nhìn, hãy sử dụng nó như thế này

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

2

CSS của Bootstrap cho .containerlớp trông như thế:

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

Vì vậy, điều này có nghĩa là chúng ta có thể dựa vào một cách an toàn jQuery('.container').css('width')để phát hiện các điểm dừng mà không có nhược điểm của việc dựa vào jQuery(window).width().

Chúng ta có thể viết một hàm như thế này:

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

Và sau đó kiểm tra nó như thế nào

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

    detectBreakpoint();
});

Điều này sẽ chỉ hoạt động ở độ rộng quy định; bất cứ điều gì ở giữa sẽ thất bại. Có thể là tốt nhất để: Đầu tiên, phân tích cú pháp trên cssWidth var cssWidth = parseInt( jQuery('.container').css('width') ); Thứ hai, sử dụng phạm vi 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

Sử dụng CSS :beforevà thuộc contenttính để in trạng thái điểm dừng trong<span id="breakpoint-js"> để JavaScript chỉ cần đọc dữ liệu này để biến nó thành một biến để sử dụng trong hàm của bạn.

(chạy đoạn trích để xem ví dụ)

LƯU Ý: Tôi đã thêm một vài dòng CSS để sử dụng <span>làm cờ đỏ ở góc trên của trình duyệt. Chỉ cần đảm bảo chuyển nó trở lại display:none;trước khi công khai công cụ của bạn.

// 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

Tôi đã tạo một phương thức jQuery gốc để phát hiện kích thước màn hình Twitter Bootstrap. Đây là:

// 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/

Ví dụ toàn màn hình của JSFillde: https://jsfiddle.net/pstepniewski/7dz6ubus/embedded/result/


1

Đối với bất kỳ ai quan tâm đến điều này, tôi đã viết một phát hiện điểm dừng dựa trên các điểm dừng CSS bằng TypeScript và Observables. không khó để tạo ES6 từ nó, nếu bạn loại bỏ các loại. Trong ví dụ của tôi, tôi sử dụng Sass, nhưng cũng dễ dàng loại bỏ điều này.

Đây là JSFiddle của tôi: 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;
});

Tôi hi vọng nó sẽ giúp ích cho mọi người.


1

Bootstrap4 với jQuery, giải pháp đơn giản hóa

<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

Tôi không thực sự hài lòng với các câu trả lời đã cho, có vẻ quá phức tạp để sử dụng cho tôi, vì vậy tôi đã viết giải pháp của riêng mình. Tuy nhiên, hiện tại điều này phụ thuộc vào dấu gạch dưới / lodash để hoạt động.

https://github.com/LeShaleigh/GridSizeEvents

Bạn có thể sử dụng nó như thế này:

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

Điều này hoạt động ngoài Box for Bootstrap 3, vì các điểm dừng được mã hóa cứng thành 768px, 992px và 1200px. Đối với các phiên bản khác, bạn có thể dễ dàng điều chỉnh mã.

Trong nội bộ, điều này sử dụng matchMedia () và do đó sẽ đảm bảo tạo ra kết quả đồng bộ với Bootstrap.


1

Có thể nó sẽ giúp một số bạn, nhưng có một plugin giúp bạn phát hiện điểm dừng Bootstrap v4 hiện tại mà bạn đang thấy: https://www.npmjs.com/package/bs-breakpoint

Sử dụng đơn giản (có thể được sử dụng có hoặc không có jQuery):

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

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

1

Đây là giải pháp của tôi (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

Đối với bất kỳ ai sử dụng knoutout.js , tôi muốn một số thuộc tính có thể quan sát được của knockout.js sẽ cho tôi biết khi nào các điểm dừng được nhấn. Tôi đã chọn sử dụng hỗ trợ của Modernizr cho các truy vấn phương tiện theo kiểu css để các số khớp với định nghĩa bootstrap và để có được lợi ích tương thích của Modernizr . Mô hình xem loại trực tiếp của tôi như sau:

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

Đây là cách tốt để phát hiện nó (có thể buồn cười, nhưng hoạt động) và Bạn có thể sử dụng yếu tố cần thiết để mã rõ ràng:

Ví dụ: css:

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

và trong tài liệu của jQuery:

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

Tất nhiên tài sản css là bất kỳ.


0

Vì bootstrap 4 sẽ sớm ra mắt, tôi nghĩ rằng tôi sẽ chia sẻ một chức năng hỗ trợ nó (xl giờ là một thứ) và thực hiện jQuery tối thiểu để hoàn thành công việc.

/**
 * 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' : '');
};

hoặc rút gọn

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

Nếu bạn sử dụng Knockout , thì bạn có thể sử dụng liên kết tùy chỉnh sau để liên kết điểm dừng chế độ xem hiện tại (xs, sm, md hoặc lg) thành một mô hình có thể quan sát được trong mô hình của bạn. Các ràng buộc...

  • kết thúc 4 divsvới visible-??lớp trong một div với iddetect-viewport và thêm nó vào phần thân nếu nó chưa tồn tại (vì vậy bạn có thể sử dụng lại ràng buộc này mà không cần sao chép các div này)
  • đặt điểm dừng của chế độ xem hiện tại thành có thể quan sát được bằng cách truy vấn các div nào có thể nhìn thấy
  • cập nhật điểm dừng chế độ xem hiện tại khi cửa sổ được thay đổi kích thước

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

Đã được một thời gian kể từ OP, nhưng đây là giải pháp của tôi cho việc sử dụng Bootstrap 3. Trong trường hợp sử dụng của tôi, tôi chỉ nhắm mục tiêu các hàng, nhưng điều tương tự có thể được áp dụng cho container, v.v.

Chỉ cần thay đổi .row thành bất cứ điều gì bạn muốn.

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