简体   繁体   English

如何使用JavaScript检测Twitter Bootstrap 3的响应断点?

[英]How to detect responsive breakpoints of Twitter Bootstrap 3 using JavaScript?

Currently , Twitter Bootstrap 3 have the following responsive breakpoints: 768px, 992px and 1200px, representing small, medium and large devices respectively. 目前 ,Twitter Bootstrap 3具有以下响应断点:768px,992px和1200px,分别代表小型,中型和大型设备。

How can I detect these breakpoints using JavaScript? 如何使用JavaScript检测这些断点?

I would like to listen with JavaScript for all related events triggered when the screen change. 我想用JavaScript监听屏幕变化时触发的所有相关事件。 And to be able to detect if the screen is for small, medium or large devices. 并能够检测屏幕是用于小型,中型还是大型设备。

Is there something already done? 已经做过什么了吗? What are your suggestions? 您有什么建议?

Edit: This library is now available through Bower and NPM. 编辑:现在可以通过Bower和NPM使用此库。 See github repo for details. 有关详细信息,请参见github repo。

UPDATED ANSWER: 更新的答案:

Disclaimer: I'm the author. 免责声明:我是作者。

Here's a few things you can do using the latest version (Responsive Bootstrap Toolkit 2.5.0): 您可以使用最新版本(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);

As of version 2.3.0, you don't need the four <div> elements mentioned below. 从2.3.0版开始,您不需要下面提到的四个<div>元素。


ORIGINAL ANSWER: 原始答案:

I don't think you need any huge script or library for that. 我认为您不需要任何庞大的脚本或库。 It's a fairly simple task. 这是一个相当简单的任务。

Insert the following elements just before </body> : </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>

These 4 divs allow you check for currently active breakpoint. 这4个div允许您检查当前活动的断点。 For an easy JS detection, use the following function: 为了轻松进行JS检测,请使用以下功能:

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

Now to perform a certain action only on the smallest breakpoint you could use: 现在,仅在最小的断点上执行某些操作即可:

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

Detecting changes after DOM ready is also fairly simple. 在DOM准备就绪后检测更改也非常简单。 All you need is a lightweight window resize listener like this one: 您只需要一个像这样的轻量级窗口调整大小侦听器:

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

Once you're equipped with it, you can start listening for changes and execute breakpoint-specific functions like so: 一旦配备了它,就可以开始侦听更改并执行特定于断点的功能,如下所示:

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

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

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

If you don't have specific needs you can just do this: 如果您没有特定需求,可以执行以下操作:

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
}

Edit: I don't see why you should use another js library when you can do this just with jQuery already included in your Bootstrap project. 编辑:我不明白为什么仅当Bootstrap项目中已经包含jQuery时才能使用另一个js库。

Have you taken a look at Response.js? 您是否看过Response.js? It's designed for this kind of thing. 专为这种事情而设计。 Combine Response.band and Response.resize. 组合Response.band和Response.resize。

http://responsejs.com/ 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
    }
});

You could use the window size and hard code the breakpoints. 您可以使用窗口大小并对断点进行硬编码。 Using Angular: 使用Angular:

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

Detect responsive breakpoint of Twitter Bootstrap 4.1.x using JavaScript 使用JavaScript检测Twitter Bootstrap 4.1.x的响应断点

The Bootstrap v.4.0.0 (and the latest version Bootstrap 4.1.x ) introduced the updated grid options , so the old concept on detection may not directly be applied (see the migration instructions ): Bootstrap v.4.0.0 (和最新版本的Bootstrap 4.1.x )引入了更新的网格选项 ,因此检测的旧概念可能无法直接应用(请参阅迁移说明 ):

  • Added a new sm grid tier below 768px for more granular control. 768px以下添加了一个新的sm网格层,以进行更精细的控制。 We now have xs , sm , md , lg , and xl ; 现在我们有了xssmmdlgxl
  • xs grid classes have been modified to not require the infix. xs网格类已被修改为不需要infix。

I written the small utility function that respects an updated grid class names and a new grid tier: 我编写了一个小实用程序函数,该函数尊重更新的网格类名称和新的网格层:

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

Detect responsive breakpoint of Bootstrap v4-beta using JavaScript 使用JavaScript检测Bootstrap v4-beta的响应断点

The Bootstrap v4-alpha and Bootstrap v4-beta had different approach on grid breakpoints, so here's the legacy way of achieving the same: Bootstrap v4-alphaBootstrap v4-beta在网格断点上具有不同的方法,因此这是实现相同功能的传统方法:

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

I think it would be useful, as it's easy to integrate to any project. 我认为这将很有用,因为它很容易集成到任何项目中。 It uses native responsive display classes of the Bootstrap itself. 它使用Bootstrap本身的本机响应显示类

Here my own simple solution: 这是我自己的简单解决方案:

jQuery: jQuery的:

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

VanillaJS: VanillaJS:

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

Using this approach with Response.js is better. 将此方法与Response.js结合使用会更好。 Response.resize triggers on every window resize where crossover will only be triggered if breakpoint is changed 在每个窗口调整大小时,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');
});

There should be no problem with some manual implementation like the one mentioned by @oozic. 像@oozic提到的那样,一些手动实现应该没有问题。

Here are a couple of libs you could take a look at: 这里有几个库,您可以看看:

  • Response.js - jQuery plugin - make use of html data attributes and also has a js api. Response.js -jQuery插件-使用html数据属性,并且还具有js API。
  • enquire.js - enquire.js is a lightweight, pure JavaScript library for responding to CSS media queries enquire.js -enquire.js是一个轻量级的纯JavaScript库,用于响应CSS媒体查询
  • SimpleStateManager - sa javascript state manager for responsive websites. SimpleStateManager-一个用于响应式网站的javascript状态管理器。 It is built to be light weight, has no dependencies. 它被构建为重量轻,没有依赖性。

Note that these libs are designed to work independently of bootstrap, foundation, etc. You can configure your own breakpoints and have fun. 请注意,这些库旨在独立于引导程序,基础等工作。您可以配置自己的断点并从中获得乐趣。

You may want to add this to your bootstrap project to check active breakpoint visually 您可能需要将此添加到引导项目中,以可视方式检查活动断点

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

Here is the BOOTPLY 这是引导

Building on Maciej Gurban's answer (which is fantastic... if you like this, please just up vote his answer). 以Maciej Gurban的答案为基础(太棒了……如果您喜欢这个,请直接投票给他)。 If you're building a service to query you can return the currently active service with the setup below. 如果您要构建要查询的服务,则可以使用以下设置返回当前处于活动状态的服务。 This could replace other breakpoint detection libraries entirely (like enquire.js if you put in some events). 这可以完全替代其他断点检测库(如果您添加了一些事件,则可以像enquire.js)。 Note that I've added a container with an ID to the DOM elements to speed up DOM traversal. 请注意,我已经向DOM元素添加了具有ID的容器,以加快DOM遍历的速度。

HTML 的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, but this is easily convertible) 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) 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;
    }
  };
});

Instead of using $(document).width(), you should get set a CSS rule that gives you this information. 代替使用$(document).width(),您应该设置一个CSS规则来提供此信息。

I just wrote an article to get it accurately. 我只是写了一篇文章以使其准确无误。 See it here : http://www.xurei-design.be/2013/10/how-to-accurately-detect-responsive-breakpoints/ 在这里查看: http : //www.xurei-design.be/2013/10/how-to-accurately-detect-sensitive-breakpoints/

Why not just use jQuery to detect the current css width of the bootstrap container class? 为什么不只使用jQuery来检测引导容器类的当前CSS宽度?

ie.. 即..

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

You could also use $(window).resize() to prevent your layout from "soiling the bed" if someone resizes the browser window. 如果有人调整浏览器窗口的大小,也可以使用$(window).resize()防止布局“弄脏床”。

Instead of inserting the below many times into each page... 而不是将以下内容多次插入每个页面中...

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

Just use JavaScript to dynamically insert it into every page (note that I have updated it to work with Bootstrap 3 with .visible-*-block : 只需使用JavaScript将其动态插入到每个页面中即可(请注意,我已经对其进行了更新,以与带有.visible-*-block Bootstrap 3配合使用:

// 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");
}

I don't have enough reputation points to comment but for those who are having problems with getting "unrecognized" when they try using Maciej Gurban's ResponsiveToolKit, I was also getting that error until I noticed that Maciej actually references the toolkit from the bottom of the page in his CodePen 我没有足够的口碑来发表评论,但是对于那些在尝试使用Maciej Gurban的ResponsiveToolKit时遇到“无法识别”的问题的人,我也收到了该错误,直到我注意到Maciej实际上从工具箱的底部引用了该工具箱。他的CodePen中的页面

I tried doing that and suddenly it worked ! 我尝试这样做,但突然奏效了! So, use the ResponsiveToolkit but put your links in the bottom of the page: 因此,使用ResponsiveToolkit,但将链接放在页面底部:

I don't know why it makes a difference but it does. 我不知道为什么会有所作为,但确实如此。

Here is another way to detect the current viewport without putting the viewport size numbers in your javascript. 这是检测当前视口的另一种方法, 而无需在JavaScript中放置视口大小数字。

See css and javascript snippets here: https://gist.github.com/steveh80/288a9a8bd4c3de16d799 在此处查看CSS和javascript代码段: https : //gist.github.com/steveh80/288a9a8bd4c3de16d799

After adding that snippets to your css and javascript files you can detect the current viewport like this: 将这些片段添加到CSS和javascript文件后,您可以像这样检测当前视口:

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

If you want to detect a viewport range use it like this 如果要检测视口范围,请像这样使用它

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

Bootstrap's CSS for the .container class looks like that: .container类的Bootstrap CSS如下所示:

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

So this means we can safely rely on jQuery('.container').css('width') to detect breakpoints without the drawbacks of relying on jQuery(window).width() . 因此,这意味着我们可以安全地依赖jQuery('.container').css('width')来检测断点,而无需依赖jQuery(window).width()的缺点。

We can write a function like this: 我们可以这样写一个函数:

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

And then test it like 然后像测试

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

    detectBreakpoint();
});

Use CSS :before and content property to print the breakpoint state in the <span id="breakpoint-js"> so the JavaScript just have to read this data to turn it as a variable to use within your function. 使用CSS :beforecontent属性在<span id="breakpoint-js">打印断点状态,因此JavaScript只需读取此数据即可将其作为在函数中使用的变量。

(run the snippet to see the example) (运行代码段以查看示例)

NOTE: I added a few line of CSS to use the <span> as a red flag in the upper corner of my browser. 注意: 我添加了几行CSS,以将<span>用作浏览器右上角的红色标记。 Just make sure to switch it back to display:none; 只要确保将其切换回display:none; before pushing your stuff public. 在将您的资料公开之前。

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

I've made a native jQuery method for Twitter Bootstrap screen size detection. 我为Twitter Bootstrap屏幕尺寸检测制作了本机jQuery方法。 Here is: 这是:

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

JSFillde as fullscreen example: https://jsfiddle.net/pstepniewski/7dz6ubus/embedded/result/ JSFillde作为全屏示例: https ://jsfiddle.net/pstepniewski/7dz6ubus/embedded/result/

For anyone interested in this, i wrote a breakpoint detection based on CSS breakpoints using TypeScript and Observables. 对于对此感兴趣的人,我使用TypeScript和Observables编写了基于CSS断点的断点检测。 it is not very hard to make ES6 out of it, if you remove the types. 如果删除类型,使用ES6并不是很难。 In my example i use Sass, but it is also easy to remove this. 在我的示例中,我使用了Sass,但是删除它也很容易。

Here is my JSFiddle: https://jsfiddle.net/StefanJelner/dorj184g/ 这是我的JSFiddle: https ://jsfiddle.net/StefanJelner/dorj184g/

HTML: HTML:

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

SCSS: 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;
});

I hope this helps somebody. 希望对您有所帮助。

Bootstrap4 with jQuery, simplified solution 带有jQuery的Bootstrap4,简化的解决方案

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

I was not really satisfied with the given answers, which seem overly complicated to use to me, so I wrote my own solution. 我对给出的答案并不真正满意,因为使用起来似乎太复杂了,所以我写了自己的解决方案。 However, for the time being this relies on underscore/lodash to work. 但是,暂时这取决于下划线/破折号。

https://github.com/LeShrimp/GridSizeEvents https://github.com/LeShrimp/GridSizeEvents

You can use it like this: 您可以像这样使用它:

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

This works out of the Box for Bootstrap 3, as the breakpoints are hard coded to 768px, 992px and 1200px. 这对于Bootstrap 3来说是开箱即用的,因为断点被硬编码为768px,992px和1200px。 For other versions you could easily adapt the code. 对于其他版本,您可以轻松修改代码。

Internally this uses matchMedia() and should thus guarantee to produce results that are in synch with Bootstrap. 在内部,它使用matchMedia()并因此应保证产生与Bootstrap同步的结果。

Maybe it'll help some of you, but there is a plugin which help you to detect on which current Bootstrap v4 breakpoint you are see: https://www.npmjs.com/package/bs-breakpoints 也许会对某些人有所帮助,但是有一个插件可以帮助您检测到哪个当前的Bootstrap v4断点: https : //www.npmjs.com/package/bs-breakpoints

Simple to use (can be used with or without jQuery): 使用简单(可与jQuery一起使用或不与jQuery一起使用):

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

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

For anyone using knockout.js , I wanted some knockout.js observable properties that would tell me when the breakpoints are hit. 对于任何使用kickout.js的人 ,我想要一些可观察到的属性 ,它们可以告诉我何时击中断点。 I opted to use Modernizr's support for css-style media queries so the numbers matched the bootstrap definitions, and to get modernizr's compatibility benefits. 我选择对CSS样式的媒体查询使用Modernizr的支持,以便数字与引导程序定义相匹配,并获得Modernizr的兼容性。 My knockout view model is as follows: 我的剔除视图模型如下:

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

Here is good way to detect it (maybe funny, but works) and You can use necessary element so code is clear: 这是一种检测它的好方法(也许很有趣,但是可行),并且您可以使用必要的元素以使代码清晰:

Example: css: 示例: css:

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

and in document by jQuery: 并在jQuery文档中:

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

of course css property is any. 当然,css属性是任意的。

Since bootstrap 4 will be out soon I thought I would share a function that supports it (xl is now a thing) and performs minimal jQuery to get the job done. 由于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;
}

Bootstrap 4 引导程序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' : ''); }; 

or minified 或缩小

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

If you use Knockout , then you could use the following custom binding to bind the current viewport breakpoint (xs, sm, md or lg) to an observable in your model. 如果使用Knockout ,则可以使用以下自定义绑定将当前视口断点(xs,sm,md或lg)绑定到模型中的可观察对象。 The binding... 绑定...

  • wraps the 4 divs with visible-?? 将4个divs封装为visible-?? class in a div with id detect-viewport and adds it to the body if it doesn't exist already (so you could reuse this binding without duplicating these divs) 带有ID detect-viewport的div中的类,并将其添加到主体(如果尚不存在)(因此您可以重复使用此绑定而无需复制这些div)
  • sets the current viewport breakpoint to the bound observable by querying which of the divs is visible 通过查询哪个div可见将当前视口断点设置为可观察到的边界
  • updates the current viewport breakpoint when the window is resized 调整窗口大小时更新当前视口断点

 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> 

It's been a while since the OP, but here's my solution for this using Bootstrap 3. In my use case, I was only targeting rows, but the same could be applied to the container, etc. 自从OP以来已经有一段时间了,但是这是我使用Bootstrap 3的解决方案。在我的用例中,我仅针对行,但是同样可以应用于容器等。

Just change .row to whatever you want. 只需将.row更改为您想要的任何内容即可。

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

Here is my solution (Bootstrap 4): 这是我的解决方案(引导程序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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM