【问题标题】:How to detect responsive breakpoints of Twitter Bootstrap 3 using JavaScript?如何使用 JavaScript 检测 Twitter Bootstrap 3 的响应断点?
【发布时间】:2013-09-05 16:51:16
【问题描述】:

Currently,Twitter Bootstrap 3 有以下响应断点:768px、992px 和 1200px,分别代表小型、中型和大型设备。

如何使用 JavaScript 检测这些断点?

我想用 JavaScript 监听屏幕变化时触发的所有相关事件。并且能够检测屏幕是用于小型、中型还是大型设备。

有什么事情已经完成了吗?你有什么建议?

【问题讨论】:

  • 您可以使用IntersectionObserver 来检测<div class="d-none d-?-block"></div> 何时更改可见性(插入所需的断点)。这些 CSS 类适用于 Bootstrap 4...使用 Bootstrap 3 中的任何功能。比监听窗口调整大小事件性能要好得多。

标签: javascript twitter-bootstrap-3 dom-events


【解决方案1】:

编辑:这个库现在可以通过 Bower 和 NPM 获得。有关详细信息,请参阅 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 版开始,您不再需要下面提到的四个 &lt;div&gt; 元素。


原始答案:

我认为您不需要任何庞大的脚本或库。这是一个相当简单的任务。

&lt;/body&gt;之前插入以下元素:

<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 允许您检查当前活动的断点。为了方便 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())
});

【讨论】:

  • 对我不起作用。 viewport.current() 总是产生“无法识别”。我做错了吗?
  • 你有小提琴吗?编辑:可能是您在头部包含您的脚本,包括 RBT,而不是正文?这会阻止可见性 div 添加到正文中,从而破坏功能。
  • @MaciejGurban 我也无法让它工作。我正在使用 Rails 4.2。我在脑海中包含了引导程序,但在正文中包含了您的脚本,但它一直说无法识别。好的,我的问题我已经在正文中添加了所有内容。但这真的需要吗?
  • 再一次,如果没有小提琴或示例代码,很难说出问题所在。您可以在 SO 上提出有关它的问题并在此处引用它,或者在 github 上打开一个问题。您是否按照CodePen 上包含所有部分的顺序进行操作?只有那个功能不起作用吗?问题会不会像this one
  • 这如何与 bootstrap 4 一起使用?
【解决方案2】:

如果您没有特定需求,您可以这样做:

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 库,而你可以使用已经包含在你的 Bootstrap 项目中的 jQuery 来做到这一点。

【讨论】:

  • 谢谢,能否为所有在屏幕尺寸变化时触发的事件提供监听器?
  • 我认为屏幕尺寸变化没有事件。与屏幕尺寸(媒体查询)相关的所有内容都在样式表中。
  • 我知道,我只是在 JS 中寻找类似的行为。实际监听屏幕尺寸变化:$(window).bind('resize')... 但还有其他与移动屏幕方向相关的事件会影响屏幕尺寸。
  • 设备方向仍然是一个实验性功能:developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent我建议你使用.on('resize')
  • 我听说过这种检测状态的方式会导致问题的案例。恕我直言,最好使用一些检查可见辅助元素的东西 - 只是为了避免任何极端情况。
【解决方案3】:

使用 JavaScript 检测 Twitter Bootstrap 4.1.x 的响应断点

Bootstrap v.4.0.0(以及最新版本Bootstrap 4.1.x)引入了更新的grid options,所以旧的检测概念可能不直接被应用(见the migration instructions):

  • 768px 下方添加了一个新的sm 网格层,以实现更精细的控制。我们现在有xssmmdlgxl
  • 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;
};

使用 JavaScript 检测 Bootstrap v4-beta 的响应断点

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

我认为它会很有用,因为它很容易集成到任何项目中。它使用 Bootstrap 本身的原生 responsive display classes

【讨论】:

    【解决方案4】:

    您看过 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。
    【解决方案5】:

    您可以使用窗口大小并对断点进行硬编码。使用角度:

    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)。
    【解决方案6】:

    这是我自己的简单解决方案:

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

    【讨论】:

      【解决方案7】:

      将此方法与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');
      });
      

      【讨论】:

        【解决方案8】:

        像@oozic提到的那种手动实现应该没有问题。

        这里有几个你可以看看的库:

        • Response.js - jQuery 插件 - 利用 html 数据属性,也有一个 js api。
        • enquire.js - enquire.js 是一个轻量级的纯 JavaScript 库,用于响应 CSS 媒体查询
        • SimpleStateManager - 响应式网站的 javascript 状态管理器。它是轻量级的,没有依赖关系。

        请注意,这些库旨在独立于引导程序、基础等工作。您可以配置自己的断点并享受乐趣。

        【讨论】:

        • Enquire.js 看起来很有希望。
        【解决方案9】:

        您可能希望将其添加到您的引导项目中以直观地检查活动断点

            <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

        【讨论】:

          【解决方案10】:

          以 Maciej Gurban 的回答为基础(这太棒了……如果您喜欢这个,请为他的回答投票)。如果您正在构建要查询的服务,您可以使用以下设置返回当前活动的服务。这可以完全取代其他断点检测库(如果您放入一些事件,例如 enquire.js)。 请注意,我已经为 DOM 元素添加了一个带有 ID 的容器,以加快 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;
              }
            };
          });
          

          【讨论】:

            【解决方案11】:

            您应该设置一个 CSS 规则来提供此信息,而不是使用 $(document).width()。

            我刚刚写了一篇文章来准确获取它。在这里看到它:http://www.xurei-design.be/2013/10/how-to-accurately-detect-responsive-breakpoints/

            【讨论】:

            【解决方案12】:

            为什么不直接使用 jQuery 来检测引导容器类的当前 css 宽度?

            即..

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

            如果有人调整浏览器窗口的大小,您还可以使用 $(window).resize() 来防止您的布局“弄脏床”。

            【讨论】:

              【解决方案13】:

              而不是在每个页面中多次插入以下内容...

              <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 将其动态插入到每个页面中(请注意,我已将其更新为使用 .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");
              }
              

              【讨论】:

                【解决方案14】:

                我没有足够的声誉点来评论,但是对于那些在尝试使用 Maciej Gurban 的 ResponsiveToolKit 时遇到“无法识别”问题的人,我也遇到了这个错误,直到我注意到 Maciej 实际上引用了来自在他的 CodePen 页面底部

                我尝试这样做,突然它奏效了!因此,请使用 ResponsiveToolkit,但将链接放在页面底部:

                我不知道为什么它会有所作为,但确实如此。

                【讨论】:

                  【解决方案15】:

                  这是检测当前视口的另一种方法无需将视口大小数字放入您的 javascript。

                  在此处查看 css 和 javascript sn-ps:https://gist.github.com/steveh80/288a9a8bd4c3de16d799

                  将 sn-ps 添加到您的 css 和 javascript 文件后,您可以像这样检测当前视口:

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

                  如果您想检测视口范围,请像这样使用它

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

                  【讨论】:

                    【解决方案16】:

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

                    所以这意味着我们可以安全地依赖 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') ); 上解析 Int,其次,使用范围 if ( cssWidth &lt; 768) { return 'xs'; } else if (cssWidth &gt;= 768 &amp;&amp; cssWidth &lt;= 992) { return 'sm'; } else if (cssWidth &gt; 992 &amp;&amp; cssWidth &lt;= 1200) { return 'md'; } else { return 'lg'; }
                    【解决方案17】:

                    使用 CSS :beforecontent 属性在 &lt;span id="breakpoint-js"&gt; 中打印断点状态,因此 JavaScript 只需读取此数据即可将其作为变量在您的函数中使用。

                    (运行sn-p查看示例)

                    注意:我添加了几行 CSS 以使用 &lt;span&gt; 作为浏览器上角的红旗。只需确保在将您的内容公开之前将其切换回 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>

                    【讨论】:

                      【解决方案18】:

                      这是我的解决方案(引导程序 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>
                      

                      【讨论】:

                        【解决方案19】:

                        我为 Twitter Bootstrap 屏幕大小检测制作了一个原生 jQuery 方法。这里是:

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

                        【讨论】:

                          【解决方案20】:

                          对于任何对此感兴趣的人,我使用 TypeScript 和 Observables 编写了基于 CSS 断点的断点检测。如果您删除类型,则从中制作 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';
                            }
                          }
                          

                          打字稿:

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

                          我希望这对某人有所帮助。

                          【讨论】:

                            【解决方案21】:

                            带有 jQ​​uery 的 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>
                            

                            【讨论】:

                              【解决方案22】:

                              我对给出的答案并不满意,对我来说使用起来似乎过于复杂,所以我编写了自己的解决方案。但是,目前这依赖于下划线/lodash 来工作。

                              https://github.com/LeShrimp/GridSizeEvents

                              你可以这样使用它:

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

                              这适用于 Bootstrap 3,因为断点被硬编码为 768px、992px 和 1200px。对于其他版本,您可以轻松调整代码。

                              这在内部使用matchMedia(),因此应该保证产生与 Bootstrap 同步的结果。

                              【讨论】:

                                【解决方案23】:

                                也许它会对你们中的一些人有所帮助,但有一个插件可以帮助您检测您在哪个当前 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)
                                  })
                                })
                                

                                【讨论】:

                                  【解决方案24】:

                                  对于使用 knockout.js 的任何人,我想要一些 knockout.js observable properties 来告诉我何时遇到断点。我选择使用Modernizr's support for css-style media queries,所以这些数字与引导定义相匹配,并获得了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();
                                  };
                                  

                                  【讨论】:

                                    【解决方案25】:

                                    这是检测它的好方法(可能很有趣,但很有效),您可以使用必要的元素,以便代码清晰:

                                    示例: css:

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

                                    通过 jQuery 在文档中:

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

                                    当然 css 属性是任意的。

                                    【讨论】:

                                      【解决方案26】:

                                      由于 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;
                                      }
                                      

                                      【讨论】:

                                        【解决方案27】:

                                        引导程序 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&lt;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();

                                        【讨论】:

                                          【解决方案28】:

                                          如果您使用 Knockout,则可以使用以下自定义绑定将当前视口断点(xs、sm、md 或 lg)绑定到模型中的 observable。绑定...

                                          • 将 4 divsvisible-?? 类包装在 id 为 detect-viewport 的 div 中,如果它尚不存在,则将其添加到主体中(因此您可以重用此绑定而无需复制这些 div)
                                          • 通过查询哪些 div 可见,将当前视口断点设置为绑定的 observable
                                          • 调整窗口大小时更新当前视口断点

                                          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>

                                          【讨论】:

                                            【解决方案29】:

                                            自 OP 以来已经有一段时间了,但这是我使用 Bootstrap 3 的解决方案。在我的用例中,我只针对行,但同样可以应用于容器等。

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

                                            【讨论】:

                                              【解决方案30】:

                                              这是一个如何使用 CSS 变量的想法。 对于使用 CSS 的 Bootstrap 3(或 Bootstrap 4):

                                              :root {
                                                  --current-breakpoint: xs;
                                              }
                                              @media (min-width: 576px){
                                                :root {
                                                  --current-breakpoint: sm;
                                                }
                                              }
                                              @media (min-width: 768px){
                                                :root {
                                                  --current-breakpoint: md;
                                                }
                                              }
                                              @media (min-width: 992px){
                                                :root {
                                                  --current-breakpoint: lg;
                                                }
                                              }
                                              @media (min-width: 1200px){
                                                :root {
                                                  --current-breakpoint: xl;
                                                }
                                              }
                                              

                                              Bootstrap 4 和 SCSS 可能如下所示:

                                              :root{
                                                @include media-breakpoint-up(xs) {
                                                  --current-breakpoint:xs;
                                                }
                                                @include media-breakpoint-up(sm) {
                                                  --current-breakpoint:sm;
                                                }
                                                @include media-breakpoint-up(md) {
                                                  --current-breakpoint:md;
                                                }
                                                @include media-breakpoint-up(lg)  {
                                                  --current-breakpoint:lg;
                                                }
                                                @include media-breakpoint-up(xl)  {
                                                  --current-breakpoint:xl;
                                                }
                                              }
                                              

                                              JS代码可能是:

                                              window.onresize=()=>{
                                                   console.log(getComputedStyle(document.documentElement).getPropertyValue('--current-breakpoint'));
                                              }
                                              

                                              【讨论】:

                                                猜你喜欢
                                                • 1970-01-01
                                                • 2013-07-28
                                                • 1970-01-01
                                                • 1970-01-01
                                                • 1970-01-01
                                                • 1970-01-01
                                                • 2013-07-29
                                                • 1970-01-01
                                                • 2014-10-02
                                                相关资源
                                                最近更新 更多