Twitter Bootstrap-如何检测媒体查询何时开始

2021/01/28 11:31 · jquery ·  · 0评论

当bootstrap-sensitive.css媒体查询生效时,哪一种是最快,最简单的触发方式?

付诸行动=当您将窗口大小调整为移动设备宽度并且站点更改为响应移动设备时

希望问题清楚

使用jquery,您可以找到当前窗口的大小,然后相应地进行操作。

$(window).resize(function() {
  if ($(this).width() >= 1280) {
    //do something
  }
  else if ($(this).width() < 1280 && $(this).width()>= 980) {
    //do something
  }
  ...
});

CSS: Twitter的Bootsrap的布局

/* Large desktop */
@media (min-width: 1200px) { ... }

/* Portrait tablet to landscape and desktop */
@media (min-width: 768px) and (max-width: 979px) { ... }

/* Landscape phone to portrait tablet */
@media (max-width: 767px) { ... }

/* Landscape phones and down */
@media (max-width: 480px) { ... }

我想出了一种使用窗口调整大小事件的方法,但是依靠Twitter Bootstrap的媒体查询而不用硬编码它们的断点:

<span id="mq-detector">
    <span class="visible-xs"></span>
    <span class="visible-sm"></span>
    <span class="visible-md"></span>
    <span class="visible-lg"></span>
</span>

#mq-detector {
    visibility: hidden;
}

var currMqIdx = undefined;
var mqDetector = $("#mq-detector");
var mqSelectors = [
    mqDetector.find(".visible-xs"),
    mqDetector.find(".visible-sm"),
    mqDetector.find(".visible-md"),
    mqDetector.find(".visible-lg")
];

var checkForResize = function() {
    for (var i = 0; i <= mqSelectors.length; i++) {
        if (mqSelectors[i].is(":visible")) {
            if (currMqIdx != i) {
                currMqIdx = i;
                console.log(mqSelectors[i].attr("class"));
            }
            break;
        }
    }
};

$(window).on('resize', checkForResize);

checkForResize();

其他答案的一个问题是每次调整大小都会触发更改事件。如果您的JavaScript做的很重要,这可能会非常昂贵。

当超过阈值时,下面的代码仅一次调用您的更新函数。

要进行测试,请抓住您的窗口大小手柄,然后快速拖动以调整其大小以查看浏览器是否阻塞。

<script>
// Global state variable
var winSize = '';

window.onresize = function () {
    var newWinSize = 'xs'; // default value, check for actual size
    if ($(this).width() >= 1200) {
        newWinSize = 'lg';
    } else if ($(this).width() >= 992) {
        newWinSize = 'md';
    } else if ($(this).width() >= 768) {
        newWinSize = 'sm';
    }

    if( newWinSize != winSize ) {
        doSomethingOnSizeChange();
        winSize = newWinSize;
    }
};
</script>

与Bootstrap 3结合使用时,这对我有用:

<div id="media-width-detection-element"></div>
<style type="text/css">
    #media-width-detection-element {
        display: none;
        width: 0px;
    }
    @media (min-width: 768px) {
        #media-width-detection-element {
            width: 768px;
        }
    }
    @media (min-width: 992px) {
        #media-width-detection-element {
            width: 992px;
        }
    }
    @media (min-width: 1200px) {
        #media-width-detection-element {
            width: 1200px;
        }
    }
</style>
<script type="text/javascript">
    //<![CDATA[
    function xs() {
        return $("#media-width-detection-element").css("width") === "0px";
    }
    function sm() {
        return $("#media-width-detection-element").css("width") === "768px";
    }
    function md() {
        return $("#media-width-detection-element").css("width") === "992px";
    }
    function lg() {
        return $("#media-width-detection-element").css("width") === "1200px";
    }
    //]]>
</script>

隐藏的DIV更改宽度取决于实际使用的CSS最小宽度设置。然后,我的javascript简单地检查当前的DIV。

优秀提示,@ falsarella!

对于那些喜欢这种事情而不影响其实际标记的人,可以进行以下工作:

$(function(){
...
var mqClasses = ["visible-xs", "visible-sm", "visible-md", "visible-lg"];
var mq = $("<span id='mqDetector' style='visibility:hidden'></span>").appendTo($("body"));
$.each(mqClasses, function(idx, val) {
    mq.append("<span class='" + val + "'></span>");
});
function checkMQ() {
    var visible = mq.find(":visible").get(0).className;
    return visible.slice(-2);
};

function checkResize(){
    switch(checkMQ){
      case 'xs' : ...; break;
      case 'sm' : ...; break;
     ...
    }
}
$(window).on('resize', checkResize);
checkResize(); //do it once when page loads.

此代码添加正文标签ldmdsdxd

     $(function(){

        var device_width_detect = '';

        function device_detec(){
            if ($(this).width() >= 1280) {
                device_width_detect = 'ld';
            }else if ($(this).width() < 1280 && $(this).width()>= 992) {
                device_width_detect = 'md';
            }else if ($(this).width() < 992 && $(this).width()>= 768) {
                device_width_detect = 'sd';
            }else if ($(this).width() < 768) {
                device_width_detect = 'xd';
            }
            $('body').removeClass( "ld md sd xd" ).addClass( device_width_detect );
        }
        device_detec();
        $(window).on('resize', device_detec);

    });

基于@falsarella的解决方案,js部分可以简化为:

var currMqIdx = undefined;
var checkForResize = function() {    
    currMqIdx = $('#mq-detector span').index($('#mq-detector span:visible'));
};

$(window).on('resize', checkForResize);
checkForResize();

currMqIdx将是一个int值,从0到3。值越大currMqIdx,媒体越宽。

更简单

$(window).on('resize', function () {
  if ($('<div class="visible-lg">').css('display')=='block') {
    // Do something for lg
  }
  // ...
});

我已经预装了一个超轻量级的库来处理在更改窗口宽度和Bootstrap断点时触发的事件-响应断点测试器

var viewport = new ResponsiveTester();

$('body').on('in.screen.xs', function(event, devices) {
    // Code executed when viewport is was changed to xs
});

$('body').on('out.screen.xs', function(event, devices) {
    // Code executed when viewport is no longer xs
});

还包括其他功能,例如当前断点检查:

if (viewport.is('xs')) {
    // Executed only on xs breakpoint
}

if (viewport.is('!=xs')) {
    // Executed on all breakpoints that are not equal xs (sm, md, lg)
}

if (viewport.is('<md')) {
    // Executed on breakpoints that are smaller than md (xs, sm)
}

if (viewport.is('<=md')) {
    // Executed on breakpoints that are smaller or equal to md (xs, sm, md)
}

if (viewport.is('>md')) {
    // Executed on breakpoints that are larger than md (lg)
}

支持Bootstrap 4和Foundation配置,有关更多信息,请访问GitHub Repository

这是我基于@falsarella想法的bootstrap 4解决方案

*注意:请使用下面的“整页”选项来测试此代码段,否则,根据代码段iframe的大小,它将返回错误的屏幕类型

/**
 * @returns STRING current screen type like: xs, sm, md, lg or xl
 */
function getScreenType() {

  !function initHelpers() {
    if ($('div.mq-detector').length !== 0) return;
    $('body').append(_mqDetector());
    // helpers
    function _mqDetector() {
      return `
      <div class="mq-detector invisible">
        <div
          class="d-block d-sm-none"
          data-type="xs"></div>
        <div
          class="d-none d-sm-block d-md-none"
          data-type="sm"></div>
        <div
          class="d-none d-md-block d-lg-none"
          data-type="md"></div>
        <div
          class="d-none d-lg-block d-xl-none"
          data-type="lg"></div>
        <div
          class="d-none d-xl-block"
          data-type="xl"></div>
      </div>
      `;
    }
  }();

  // @then

  return $('div.mq-detector').children().filter(':visible').data('type');

}

console.log(getScreenType())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

改进了出色的@falsarella答案,这是可与Bootstrap 4配合使用的较短版本:

CSS:

#mq-detector {
    visibility: hidden;
}

HTML:

<div id="mq-detector">
    <span data-mq="xs" class="d-block d-sm-none"></span>
    <span data-mq="sm" class="d-none d-sm-block d-md-none"></span>
    <span data-mq="md" class="d-none d-md-block d-lg-none"></span>
    <span data-mq="lg" class="d-none d-lg-block d-xl-none"></span>
    <span data-mq="xl" class="d-none d-xl-block"></span>
</div>

JAVASCRIPT:

//Define function that returns the currently used media query
function getBsMq(){
    var currMq;
    var mqDetector = $('#mq-detector [data-mq]');
    mqDetector.each(function(i){
        if ($(this).is(':visible')) {
            currMq = $(this).attr('data-mq');
        }
    });
    return currMq;
}


//Call the function and get the currently used media query
alert(getBsMq());

您可以使用matchMedia和包装器库enquire.js,该注册媒体查询并在匹配/不匹配时发出事件。

用法

让我们以这些Bootstrap CSS媒体查询为例,取自docs

/* Extra small devices (phones, less than 768px) */
/* No media query since this is the default in Bootstrap */

/* Small devices (tablets, 768px and up) */
@media (min-width: @screen-sm-min) { ... }

/* Medium devices (desktops, 992px and up) */
@media (min-width: @screen-md-min) { ... }

/* Large devices (large desktops, 1200px and up) */
@media (min-width: @screen-lg-min) { ... }

为了查看这些规则得到应用时,使用enquire.js注册媒体查询和供应适当matchunmatch功能,如下图所示:

let rules = [
    '(max-width: 768px)',  // extra small devices, default
    '(min-width: 768px)',  // small devices
    '(min-width: 992px)',  // medium devices
    '(min-width: 1200px)'  // large devices
];

for (let rule of rules) {
    enquire.register(rule, {
      match: function() {
        console.log(rule + ' matched');
      },      

      unmatch: function() {
        console.log(rule + ' unmatched');
      } 
    });
}

enquire.js使用matchMedia支持现代浏览器的浏览器,例如不支持IE9。因此,传统浏览器将需要polyfill来完成这项工作。

演示版

我只在大屏幕上的引导程序中将导航栏粘贴在https://ducttapedanyol.com上:

if ($(this).width() >= 979) { // Detect screen size
$(document).ready(function () {

    var menu = $('.menu');
    var origOffsetY = menu.offset().top;

    function scroll() {
       if ($(window).scrollTop() >= origOffsetY) {
          $('.menu').addClass('sticky');
          $('.fix').addClass('fix-tall');
       } else {
          $('.menu').removeClass('sticky');
          $('.fix').removeClass('fix-tall');
       }


    }

    document.onscroll = scroll;

});
}

我在链接中修改了Bootsrap 4的代码,而不是alpha或beta。代码如下;

    /* **********************************************************
        Detect bootrap 4 media query type
        https://getbootstrap.com/docs/4.0/utilities/display/
   ********************************************************** */


    $("body").append("<div style='visibilty:hidden' class='viewport-check'><span class='d-block d-sm-none'>xs</span><span class='d-none d-sm-block d-md-none'>sm</span><span class='d-none d-md-block d-lg-none'>md</span><span class='d-none d-lg-block d-xl-none'>lg</span><span class='d-none d-xl-block'>xl</span></div>");

    var Bootstrap4MediaQuery = "";

    //> Checks if the span is set to display block via CSS
    function FnDetectMediaQuery(_QsTarget) {
        var _QsTarget = $(_QsTarget).css('display') == 'block';
        return _QsTarget;
    }

    if(FnDetectMediaQuery('.viewport-check .d-block') == true)
    {
        Bootstrap4MediaQuery = "xs";
    }
    else if(FnDetectMediaQuery('.viewport-check .d-sm-block') == true)
    {
        Bootstrap4MediaQuery = "sm";
    }
    else if(FnDetectMediaQuery('.viewport-check .d-md-block') == true)
    {
        Bootstrap4MediaQuery = "md";
    }
    else if(FnDetectMediaQuery('.viewport-check .d-lg-block') == true)
    {
        Bootstrap4MediaQuery = "lg";
    }
    else if(FnDetectMediaQuery('.viewport-check .d-xl-block') == true)
    {
        Bootstrap4MediaQuery = "xl";
    }
    else
    {
        Bootstrap4MediaQuery = "";
    }

    console.log("Bootstrap4MediaQuery: " + Bootstrap4MediaQuery);

我会用window.matchMediawindow.addEventListener('resize')实施例下面,具体功能getActiveBreakpoint()会告诉你哪个断点是活动的,但也将告诉你哪些是lt-(小于),并gt-在辅助类即形式(大于)gt-xs gt-sm md lt-lg lt-xl,见https://jsfiddle.net/Lqtmc8yo/1/

/*
// from bootstrap/scss/_variables.scss
$grid-breakpoints: (
    xs: 0,
    sm: 576px,
    md: 768px,
    lg: 992px,
    xl: 1200px
  ) !default;
*/

const breakpoints = {
    xs: 0,
    sm: 576,
    md: 768,
    lg: 992,
    xl: 1200,
}
const orderedKeys = ['xs', 'sm', 'md', 'lg', 'xl']

const getActiveBreakpoint = () => {
    let breakpoint = ''
    let classList = []

    orderedKeys.some((k, i) => {
        const n = orderedKeys[i + 1]
        let query = ''
        query += `(min-width: ${breakpoints[k]}px)`
        if (n) {
            query += `and (max-width: ${breakpoints[n] - 1}px)`
        }
        if (window.matchMedia(query).matches) {
            breakpoint = k
            classList = [...orderedKeys.slice(0, i).map(b => `gt-${b}`), k, ...orderedKeys.slice(i + 1, orderedKeys.length).map(b => `lt-${b}`)]
            return true
        }
        return false
    })
    return { breakpoint, classList, className: classList.join(' ') }
}


const calculate = () => {
  const result = getActiveBreakpoint()
  document.getElementById('result').innerHTML = `
       breakpoint: ${result.breakpoint}
       <br>
       className: ${result.className}
     `
}

window.addEventListener('resize', calculate)
calculate()
<div id="result"></div>

已经回答了计算器Terryfrancis仍然是有用的在我的引导4的应用程序,当我想改变类非引导模块插入的.COL-MD在我的引导4的应用程序。

我同时使用了onloadwindow调整大小功能:

// on load
if ($(window).width() > 575 && $(window).width() < 992) {
   $('div').addClass('col-md-6').removeClass('col-md-4');
} else if ($(window).width() > 992) {
    $('div').addClass('col-md-4').removeClass('col-md-6');
}

// on user resizes browser window
 $( window ).resize(function() {
if ($(window).width() > 575 && $(window).width() < 992) {
   $('div').addClass('col-md-6').removeClass('col-md-4');
} else if (jQuery(window).width() > 992) {
    $('div').addClass('col-md-4').removeClass('col-md-6');
}
});
本文地址:http://jquery.askforanswer.com/twitter-bootstrap-ruhejiancemeitichaxunheshikaishi.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!