JavaScript中offsetWidth的bug及解决方法


Posted in Javascript onMay 17, 2017

offsetWidth表示对象的可见宽度。
比如:

#div1 {
 width: 100px;
 height: 200px;
 background: red;
}

结果:100

#div1 {
 width: 100px;
 height: 200px;
 background: red;
 border: 2px solid black;
}

结果:104 (100 + 2 + 2)

#div1 {
 width: 100px;
 height: 200px;
 background: red;
 border: 2px solid black;
 padding: 20px;
}

结果:144 (100 + 2 + 2 + 20 + 20)

#div1 {
 width: 100px;
 height: 200px;
 background: red;
 margin: 4px;
}

结果:100

**

所以,offsetWidth = width + padding + border, 和margin无关。

**
下面来看一个例子:

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>offsetWidth</title>
 <style type="text/css">
  #div1 {
   width: 500px;
   height: 200px;
   background: red;
  }
 </style>
</head>
<body>
 <div id="div1"></div>
 <script type="text/javascript">
  var oDiv = document.getElementById('div1');
  setInterval(function() {
   oDiv.style.width = oDiv.offsetWidth - 1 + 'px';
  }, 50);
 </script>
</body>
</html>

现象:红色div逐渐变窄,直到消失,没问题!

如果给div加一个border,呢?

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>offsetWidth</title>
 <style type="text/css">
  #div1 {
   width: 500px;
   height: 200px;
   background: red;
   border: 1px solid black;
  }
 </style>
</head>
<body>
 <div id="div1"></div>
 <script type="text/javascript">
  var oDiv = document.getElementById('div1');
  setInterval(function() {
   oDiv.style.width = oDiv.offsetWidth - 1 + 'px';
  }, 50);
 </script>
</body>
</html>

现象:红色div不仅没有变窄,反而越来越宽……

JavaScript中offsetWidth的bug及解决方法*

原因也很简单:就是border的直接原因,因为offsetWidth是把border算进去的,定时器轮询的时候,第一次,width : 102 - 1 == 101 ,那么offsetWidth立马就变为103;第二次,width: 103 - 1 == 102, 那么offsetWidth立马就变为104;紧接着第三次,width: 104 - 1 == 103, offsetWidth就为104了……

倘若把 oDiv.style.width = oDiv.offsetWidth - 1 + ‘px'; 换成 -2,那么红色div就不动了,不会变宽也不会变窄,因为offsetWidth为102,减去2就是100和原本的width相等,下一次循环,offsetWidth就等于100加上border的2,再减去2还是100,所以不动……*

解决方案也很简单,惹不起还躲不起?不用offsetWidth了!

我们都知道,获取元素的行间样式直接用element.style.width即可,但是这只针对元素的行间样式,如果写在css中,你就获取不到了.

但也是有办法的:

  • IE中用element.currentStyle.width / element.currentStyle.[‘width'];
  • 非IE中用getComputedStyle(element, false)[‘width']
<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>offsetWidth</title>
 <style type="text/css">
  #div1 {
   width: 500px;
   height: 200px;
   background: red;
   border: 1px solid black;
  }
 </style>
</head>
<body>
 <div id="div1"></div>
 <script type="text/javascript">

  var oDiv = document.getElementById('div1');
  function getStyle(obj, attr) {
   if (obj.currentStyle) {//IE
    return obj.currentStyle[attr];
   } else {
    return getComputedStyle(obj, false)[attr];
   }
  }
  alert(getStyle(oDiv, 'width'));//直接弹出 “500px”
 </script>
</body>
</html>

有了上面的这个封装,我们就可以解决offsetWidth带来的困扰了

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>offsetWidth</title>
 <style type="text/css">
  #div1 {
   width: 500px;
   height: 200px;
   background: red;
   border: 1px solid black;
  }
 </style>
</head>
<body>
 <div id="div1"></div>
 <script type="text/javascript">
  var oDiv = document.getElementById('div1');
  function getStyle(obj, attr) {
   if (obj.currentStyle) {//IE
    return obj.currentStyle[attr];
   } else {
    return getComputedStyle(obj, false)[attr];
   }
  }
  setInterval(function() {
   //parseInt是因为getStyle()返回的是‘px'带单位,要整数化
   oDiv.style.width = parseInt(getStyle(oDiv, 'width')) - 1 + 'px';
  }, 30);
 </script>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 应用类库代码
Jun 02 Javascript
层序遍历在ExtJs的TreePanel中的应用
Oct 16 Javascript
jquery中获取select选中值的代码
Jun 27 Javascript
javascript实现uploadify上传格式以及个数限制
Nov 23 Javascript
基于jQuery实现的双11天猫拆红包抽奖效果
Dec 01 Javascript
JS判断图片是否加载完成方法汇总(最新版)
May 13 Javascript
jquery实现文字单行横移或翻转(上下、左右跳转)
Jan 08 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
Aug 25 Javascript
vue搜索和vue模糊搜索代码实例
May 07 Javascript
JavaScript计算出两个数的差值
Mar 19 Javascript
vue项目实现减少app.js和vender.js的体积操作
Nov 12 Javascript
原生JS实现音乐播放器的示例代码
Feb 25 Javascript
Bootstrap 表单验证formValidation 实现远程验证功能
May 17 #Javascript
基于vue+ bootstrap实现图片上传图片展示功能
May 17 #Javascript
JavaScript运动框架 多物体任意值运动(三)
May 17 #Javascript
BootStrap表单验证 FormValidation 调整反馈图标位置的实例代码
May 17 #Javascript
JavaScript运动框架 解决防抖动问题、悬浮对联(二)
May 17 #Javascript
vue之nextTick全面解析
May 17 #Javascript
Vue.js学习教程之列表渲染详解
May 17 #Javascript
You might like
php+mysql事务rollback&amp;commit示例
2010/02/08 PHP
php实现单链表的实例代码
2013/03/22 PHP
PHP中HTML标签过滤技巧
2014/01/07 PHP
php自动给网址加上链接的方法
2015/06/02 PHP
PHP多态代码实例
2015/06/26 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
2015/08/16 PHP
深入理解PHP内核(二)之SAPI探究
2015/11/10 PHP
Thinkphp和Bootstrap结合打造个性的分页样式(推荐)
2016/08/01 PHP
超强多功能php绿色集成环境详解
2017/01/25 PHP
JavaScript 监听textarea中按键事件
2009/10/08 Javascript
跟我一起学写jQuery插件开发方法(附完整实例及下载)
2010/04/01 Javascript
IE8下关于querySelectorAll()的问题
2010/05/13 Javascript
图片上传插件jquery.uploadify详解
2013/11/15 Javascript
常用的JavaScript模板引擎介绍
2015/02/28 Javascript
详解AngularJS中自定义过滤器
2015/12/28 Javascript
javascript中arguments,callee,caller详解
2016/03/16 Javascript
javascript执行环境及作用域详解
2016/05/05 Javascript
微信小程序实战之运维小项目
2017/01/17 Javascript
微信小程序实现多选功能
2018/11/04 Javascript
vue中进行微博分享的实例讲解
2019/10/14 Javascript
JavaScript变量Dom对象的所有属性
2020/04/30 Javascript
js实现点击按钮随机生成背景颜色
2020/09/05 Javascript
解决iview table组件里的 固定列 表格不自适应的问题
2020/11/13 Javascript
Python列表常见操作详解(获取,增加,删除,修改,排序等)
2019/02/18 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
2020/03/20 Python
python 实现客户端与服务端的通信
2020/12/23 Python
css3 pointer-events 介绍详解
2017/09/18 HTML / CSS
从一次项目重构说起CSS3自定义变量在项目的使用方法
2021/03/01 HTML / CSS
HTML5是什么 HTML5是什么意思 HTML5简介
2012/10/26 HTML / CSS
C,C++的几个面试题小集
2013/07/13 面试题
九州传奇上机题
2014/07/10 面试题
公司活动邀请函
2014/01/24 职场文书
中专毕业生自我鉴定
2014/02/02 职场文书
公司庆典主持词
2015/07/04 职场文书
【海涛DOTA】D-cup邀请赛NV.cn vs DT.Love
2022/04/01 DOTA
JavaScript parseInt0.0000005打印5原理解析
2022/07/23 Javascript