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检测对象中是否存在某个属性判断方法小结
May 19 Javascript
JQuery实现动态表格点击按钮表格增加一行
Aug 24 Javascript
javascript几个易错点记录
Nov 26 Javascript
jquery马赛克拼接翻转效果代码分享
Aug 24 Javascript
Vue.js快速入门实例教程
Oct 15 Javascript
jQuery插件之validation插件
Mar 29 jQuery
JavaScript简单计算人的年龄示例
Apr 15 Javascript
jQuery实现锚点向下平滑滚动特效示例
Aug 29 jQuery
如何在Vue.js中实现标签页组件详解
Jan 02 Javascript
vue实现父子组件之间的通信以及兄弟组件的通信功能示例
Jan 29 Javascript
jquery获取input输入框中的值
Nov 13 jQuery
微信小程序接入腾讯云验证码的方法步骤
Jan 07 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 JSON格式数据交互实例代码详解
2011/01/13 PHP
选择PHP作为网站开发语言的原因分享
2012/01/03 PHP
php中unlink()、mkdir()、rmdir()等方法的使用介绍
2012/12/21 PHP
php生成N个不重复的随机数实例
2013/11/12 PHP
帝国cms常用标签汇总
2015/07/06 PHP
一个简单至极的PHP缓存类代码
2015/10/23 PHP
jQuery 操作option的实现代码
2011/03/03 Javascript
非常漂亮的JS+CSS图片幻灯切换特效
2013/11/20 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
2014/07/04 Javascript
JavaScript中的splice()方法使用详解
2015/06/09 Javascript
js中用cssText设置css样式的简单方法
2016/09/19 Javascript
JavaScript实现通过select标签跳转网页的方法
2016/09/29 Javascript
Vue.js实现表格动态增加删除的方法(附源码下载)
2017/01/20 Javascript
JavaScript中最常见的三个面试题解析
2017/03/04 Javascript
温故知新——JavaScript中的字符串连接问题最全总结(推荐)
2017/08/21 Javascript
JavaScript插件Tab选项卡效果
2017/11/14 Javascript
jQuery中ajax获取数据赋值给页面的实例
2017/12/31 jQuery
json对象及数组键值的深度大小写转换问题详解
2018/03/30 Javascript
Vue2.X 通过AJAX动态更新数据
2018/07/17 Javascript
详解Vue改变数组中对象的属性不重新渲染View的解决方案
2018/09/21 Javascript
jQuery实现tab栏切换效果
2020/12/22 jQuery
Python爬虫实现爬取京东手机页面的图片(实例代码)
2017/11/30 Python
解决PyCharm控制台输出乱码的问题
2019/01/16 Python
Python2.7版os.path.isdir中文路径返回false的解决方法
2019/06/21 Python
Python面向对象之继承原理与用法案例分析
2019/12/31 Python
Python3安装模块报错Microsoft Visual C++ 14.0 is required的解决方法
2020/07/28 Python
CSS3使用transition属性实现过渡效果
2018/04/18 HTML / CSS
香港零食网购:上仓胃子
2020/06/08 全球购物
英国时尚和家居用品零售商:Matalan
2021/02/28 全球购物
预备党员思想汇报范文
2013/12/29 职场文书
给水工程专业毕业生自荐信
2014/01/28 职场文书
房地产财务部员工岗位职责
2014/03/12 职场文书
奶茶店创业计划书
2014/08/14 职场文书
施工现场安全管理制度
2015/08/05 职场文书
2019新员工试用期转正申请书3篇
2019/08/13 职场文书
利用javaScript处理常用事件详解
2021/04/14 Javascript