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 贪吃蛇实现代码
Nov 22 Javascript
JavaScript代码复用模式实例分析
Dec 02 Javascript
jquery 隐藏与显示tr标签示例代码
Jun 06 Javascript
Node.js中使用socket创建私聊和公聊聊天室
Nov 19 Javascript
js实现搜索框关键字智能匹配代码
Mar 26 Javascript
Android中Okhttp3实现上传多张图片同时传递参数
Feb 18 Javascript
axios学习教程全攻略
Mar 26 Javascript
JS排序之选择排序详解
Apr 08 Javascript
vue addRoutes实现动态权限路由菜单的示例
May 15 Javascript
Vue隐藏显示、只读实例代码
Jul 18 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
Aug 27 Javascript
小程序跳转到的H5页面再跳转回跳小程序的方法
Mar 06 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
javascript的函数
2007/01/31 Javascript
JavaScript更改class和id的方法
2008/10/10 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
Javascript实现仿WebQQ界面的“浮云”兼容 IE7以上版本及FF
2011/04/27 Javascript
Jquery.Form 异步提交表单的简单实例
2014/03/03 Javascript
jquery操作checked属性以及disabled属性的多种方法
2014/06/20 Javascript
jQuery实现的fixedMenu下拉菜单效果代码
2015/08/24 Javascript
详解JavaScript的另类写法
2016/04/11 Javascript
Vue结合原生js实现自定义组件自动生成示例
2017/01/21 Javascript
使用Math.max,Math.min获取数组中的最值实例
2017/04/25 Javascript
微信小程序实现自定义modal弹窗封装的方法
2018/06/15 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
jQuery属性选择器用法实例分析
2019/06/28 jQuery
Vue中util的工具函数实例详解
2019/07/08 Javascript
vue实现侧边栏导航效果
2019/10/21 Javascript
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
python通过cookie模拟已登录状态的初步研究
2016/11/09 Python
python内置函数:lambda、map、filter简单介绍
2017/11/16 Python
python OpenCV学习笔记之绘制直方图的方法
2018/02/08 Python
opencv实现图片模糊和锐化操作
2018/11/19 Python
Python内置random模块生成随机数的方法
2019/05/31 Python
wxPython电子表格功能wx.grid实例教程
2019/11/19 Python
python标准库OS模块详解
2020/03/10 Python
python实现简单贪吃蛇游戏
2020/09/29 Python
python 高阶函数简单介绍
2021/02/19 Python
adidas旗下高尔夫装备供应商:TaylorMade Golf(泰勒梅高尔夫)
2016/08/28 全球购物
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
TIME时代杂志台湾总代理:台时亚洲
2018/10/22 全球购物
中国专业的音频分享平台:喜马拉雅
2019/05/24 全球购物
JAVA和C++区别都有哪些
2015/03/30 面试题
机电专业毕业生求职信
2013/10/27 职场文书
教师求职自荐信
2014/03/09 职场文书
小学假期安全广播稿
2014/09/28 职场文书
技术员个人工作总结
2015/03/03 职场文书
初中班级口号霸气押韵
2015/12/24 职场文书
Mybatis是这样防止sql注入的
2021/12/06 Java/Android