javascript - 获取整数框宽度而不是小数值 : Math. ceil() 不向上舍入

标签 javascript jquery

我有一个 Bootstrap 导航栏。使用 Chrome DevTools 检查时,我注意到这个(我想还有其他浏览器)返回小数框宽度而不是整数(即 83.06 而不是 83)。

decimal width

为了与其他一些元素实现像素完美对齐,我需要将这个数字“转换为整数”,并且为了避免按钮在 2 个以上单词的项目中折叠,我需要对其进行“四舍五入”:简而言之,83.06 应变为 84(而不是 83)。

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

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

这里是代码片段(jsFiddle):

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

很直接,对吧?但它无法按预期工作:项目的原始宽度(根据 Chrome DevTools,86.05124.17107.7)并不总是向上舍入尽管有 Math.ceil() 函数,但我最终得到了 86124108 (只有后者是对的;前两项“折叠”是因为没有足够的空间)。 Math.ceil() 不应该总是向上舍入吗?很奇怪...

“好吧”,我想,“让我们找到一个解决方法”:所以我用 parseInt() 交换了 Math.ceil() 并至少添加了 +1 像素,就像这个其他代码片段 ( jsFiddle ):

$(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 个像素:这比以前更糟糕...

现在我陷入了困境,无法想象其他方法:有什么解决方案可以让整数四舍五入而不以所有这些疯狂的结果结束,拜托?谢谢

最佳答案

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

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

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

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

你可以保留它,但现在 width所有这些li总是会重置,无论是否已经重置。
为了防止这种情况,我使用了 if 子句来检查宽度是否尚未为整数,并且只有 获取实际调整大小的元素。

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

if (width%1 !== 0) {$(this).width(Math.ceil(width));}

但为了安全起见,我还会删除 .children('a') ,并测量li自己:

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

显然是a自动填充整个li ,但是li还会自动缩放到 a ,并且由于您正在执行 .width()li 进行操作,检查 width 似乎更安全、更合乎逻辑。相同元素。
或者,您可以设置 width() a的而不是 li .


请参阅演示的代码片段(将代码片段放入“完整页面”中进行测试):

$(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)[0].getBoundingClientRect().width; // for each valid 'li', take its 'a' descendant width
      if (width%1 !== 0) {$(this).width(Math.ceil(width));} // if width isn't already an integer, round up
      console.log(width, 'resize: '+(width%1 !== 0));
    });
  }
}).resize();
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<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>
jsfiddle:https://jsfiddle.net/c7927ud1/6/

关于javascript - 获取整数框宽度而不是小数值 : Math. ceil() 不向上舍入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44902202/

相关文章:

javascript - 单击时将文本元素转换为输入字段类型的文本,单击后又变回文本

javascript - 新的数组语法,多个参数

javascript - 使用 JavaScript 访问外部 json 文件

javascript - 使用 jQuery 更改 href 链接导致 CORS 策略阻塞

javascript/jquery - 倒计时器

javascript - 像在 Perl 中一样在 JavaScript 正则表达式中嵌入注释

javascript - 简单的 Javascript 问题

javascript - 使用jQuery比较服务器时间和当前时间

Javascript 选项卡使用数据属性而不是 ID 来链接按钮和选项卡

jquery - 将knockoutJS数据绑定(bind)模板插入容器后刷新砖石布局