获取整数框宽度而不是十进制值:Math.ceil()不会向上舍入

时间:2017-07-04 09:32:35

标签: javascript jquery

我有一个Bootstrap导航栏。使用Chrome DevTools进行检查我注意到这个(以及其他浏览器,我认为)返回十进制框宽度而不是整数(即83.06而​​不是83)。

decimal width

对于与其他一些元素完美对齐,我需要'转换为整数'这个数字,并且为了避免2个字以内的项目中的按钮崩溃,我需要“整理”它:简而言之,{{1}应该成为83.06(而不是84)。

我知道的唯一方法是使用JavaScript,所以我做了这个脚本:

83

以下是代码段(jsFiddle):

$(window).on('resize', function(){ // recalculate when resizing window
  if (window.innerWidth > 768) { // only in 'desktop' version(s), smaller devices don't need recalculation
    $('.navbar-nav').find('> li:not(.hidden-sm)').each(function(){
      var width = $(this).children('a').outerWidth(); // for each valid 'li', take its 'a' descendant width
      console.log(width); // watch what happens
      $(this).width(Math.ceil(width)); // change item width with a 'rounded up' value
    })
  }
}).resize();
$(window).on('resize', function(){ // recalculate when resizing window
  if (window.innerWidth > 768) { // only in 'desktop' version(s)
    $('.navbar-nav').find('> li:not(.hidden-sm)').each(function(){
      var width = $(this).children('a').outerWidth(); // for each valid 'li', take its 'a' descendant width
      console.log(width); // watch what happens
      $(this).width(Math.ceil(width)); // change item width with a 'rounded up' value
    })
  }
}).resize();

挺直的吧?但它没有按预期工作:尽管<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link One<span class="sr-only">(current)</span></a></li> <li><a href="#">Link Two, Long</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> </ul> </li> <li class="hidden-sm"><a href="#">Link Three: too long to fit, hide on small devices</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav>函数和86.05函数并不总是向上舍入项目的原始宽度(124.17107.7Math.ceil(),根据Chrome DevTools)我最终得到86124108(只有后者是正确的;前两个项目'崩溃',因为没有足够的空间)。 Math.ceil()总是不应该围绕?非常奇怪......

“好的”,我想,“让我们找一个解决方法”:所以我将Math.ceil()parseInt()交换,并添加至少+1像素,就像这个其他代码段一样({{3 }}):

$(window).on('resize', function(){ // recalculate when resizing window
  if (window.innerWidth > 768) { // only in 'desktop' version(s)
    $('.navbar-nav').find('> li:not(.hidden-sm)').each(function(){
      var width = $(this).children('a').outerWidth(); // for each valid 'li', take its 'a' descendant width
      console.log(width); // watch what happens
      $(this).width(parseInt(width)+1); // change item width with a 'rounded up' value
    })
  }
}).resize();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<nav class="navbar navbar-default">
  <div class="container-fluid">
    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link One<span class="sr-only">(current)</span></a></li>
        <li><a href="#">Link Two, Long</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
          </ul>
        </li>
        <li class="hidden-sm"><a href="#">Link Three: too long to fit, hide on small devices</a></li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

好,按钮不会崩溃但是...尝试调整窗口大小:按钮会永远增长,可能是因为我在每次迭代中添加1个像素:这比以前更糟糕...

现在我陷入困境,无法想象其他方法:任何获得整数的解决方案都会结束而不会结束所有这些疯狂的结果,拜托?谢谢

1 个答案:

答案 0 :(得分:1)

你的问题是jQuery的.width()已经在内部将宽度值舍入到最接近的整数(所以:86.05 => 86124.17 => 124107.7 => 108)。

因此,使用.width()检索并执行舍入计算的值已经是整数,因此它们没有任何效果:)

这可以通过使用JavaScript的原生.getBoundingClientRect()来解决:
这将返回实际的浮点宽度(从this answer获得)。

var width = $(this).children('a')[0].getBoundingClientRect().width;

你可以保留它,但现在所有width的{​​{1}}总是被重置,无论它们是否已经存在。
为了防止这种情况,我使用if子句来检查宽度 是否 是一个整数, 只是 获取实际调整大小的元素。

这就是你所需要的(我从this answer得到的):

li

但为了安全起见,我还会移除if (width%1 !== 0) {$(this).width(Math.ceil(width));} ,并自行衡量.children('a')

li

显然,var width = $(this)[0].getBoundingClientRect().width; 会自动填充整个a,但li也会自动缩放到li,因为您正在执行a.width()进行{1}}操作,检查同一元素的li似乎更安全,也更符合逻辑。
或者,您可以设置width的{​​{1}}而不是width()


有关演示的详细信息,请参阅代码段(在“完整页面”中将代码段放入测试中):

a
li
jsfiddle:https://jsfiddle.net/c7927ud1/6/