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 相关文章推荐
jQuery 获取和设置select下拉框的值实现代码
Nov 08 Javascript
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)
Dec 16 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
Mar 28 Javascript
jQuery实现表单提交时判断的方法
Dec 13 Javascript
jQuery中animate()方法用法实例
Dec 24 Javascript
Css3制作变形与动画效果
Jul 24 Javascript
js密码强度检测
Jan 07 Javascript
JS修改地址栏参数实例代码
Jun 14 Javascript
jQuery查看选中对象HTML代码的方法
Jun 17 Javascript
详解Js里的for…in和for…of的用法
Mar 28 Javascript
vue 数据操作相关总结
Dec 17 Vue.js
mustache.js实现首页元件动态渲染的示例代码
Dec 28 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 缓冲的免费实现方法
2006/10/09 PHP
for循环连续求和、九九乘法表代码
2012/02/20 PHP
php实现简单文件下载的方法
2015/01/30 PHP
php发送http请求的常用方法分析
2016/11/08 PHP
JavaScript flash复制库类 Zero Clipboard
2011/01/17 Javascript
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
2011/07/04 Javascript
js 本地预览的简单实现方法
2014/02/18 Javascript
Javascript玩转继承(二)
2014/05/08 Javascript
JavaScript拆分字符串时产生空字符的解决方案
2014/09/26 Javascript
jQuery使用removeClass方法删除元素指定Class的方法
2015/03/26 Javascript
javascript如何定义对象数组
2016/06/07 Javascript
jQuery深拷贝Json对象简单示例
2016/07/06 Javascript
vue实现可增删查改的成绩单
2016/10/27 Javascript
Javascript this 函数深入详解
2016/12/13 Javascript
Bootstrap table学习笔记(2) 前后端分页模糊查询
2017/05/18 Javascript
javaScript canvas实现(画笔大小 颜色 橡皮的实例)
2017/11/28 Javascript
基于vue 实现token验证的实例代码
2017/12/14 Javascript
webpack 插件html-webpack-plugin的具体使用
2018/04/09 Javascript
JS动画实现回调地狱promise的实例代码详解
2018/11/08 Javascript
微信小程序new Date()方法失效问题解决方法
2019/07/29 Javascript
javascript实现简易的计算器
2020/01/17 Javascript
JavaScript运行机制实例分析
2020/04/11 Javascript
举例讲解Python中装饰器的用法
2015/04/27 Python
python正则分析nginx的访问日志
2017/01/17 Python
python图的深度优先和广度优先算法实例分析
2019/10/26 Python
python中如何打包用户自定义模块
2020/09/23 Python
Python尾递归优化实现代码及原理详解
2020/10/09 Python
python实现图像高斯金字塔的示例代码
2020/12/11 Python
10张动图学会python循环与递归问题
2021/02/06 Python
九一八事变纪念日演讲稿
2014/09/14 职场文书
机械制造专业大学生自我鉴定
2014/09/19 职场文书
中学生综合素质自我评价
2015/03/06 职场文书
2015个人半年总结范文
2015/03/09 职场文书
党支部考察意见范文
2015/06/02 职场文书
2019年教师节:送给所有老师的祝福语
2019/09/05 职场文书
python中的None与NULL用法说明
2021/05/25 Python