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的button默认enter事件(回车事件)。
May 18 Javascript
javascript内置对象arguments详解
Mar 16 Javascript
javascript与有限状态机详解
May 08 Javascript
jquery事件preventDefault()方法用法实例
Jan 16 Javascript
jQuery增加与删除table列的方法
Mar 01 Javascript
js实现可键盘控制的简单抽奖程序
Jul 13 Javascript
浅谈JavaScript 函数参数传递到底是值传递还是引用传递
Aug 23 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
Mar 14 Javascript
vue基于Element构建自定义树的示例代码
Sep 19 Javascript
vue实现引入本地json的方法分析
Jul 12 Javascript
在Vue中使用this.$store或者是$route一直报错的解决
Nov 08 Javascript
layui 弹出层值回传解决方式
Nov 14 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
做一个有下拉功能的留言版
2006/10/09 PHP
用 Composer构建自己的 PHP 框架之设计 MVC
2014/10/30 PHP
php封装的smarty类完整实例
2016/10/19 PHP
thinkPHP内置字符串截取函数用法详解
2016/11/15 PHP
PHP magento后台无法登录问题解决方法
2016/11/24 PHP
PHP简单实现二维数组赋值与遍历功能示例
2017/10/19 PHP
js jquery做的图片连续滚动代码
2008/01/06 Javascript
JavaScript 原型继承
2011/12/26 Javascript
javascript去除空格方法小结
2015/05/21 Javascript
jquery实现的缩略图预览滑块实例
2015/06/25 Javascript
jQuery实现Email邮箱地址自动补全功能代码
2015/11/03 Javascript
JS新包管理工具yarn和npm的对比与使用入门
2016/12/09 Javascript
webpack配置sass模块的加载的方法
2017/07/30 Javascript
Vue.js用法详解
2017/11/13 Javascript
详解webpack2异步加载套路
2018/09/14 Javascript
微信小程序实现点赞、取消点赞功能
2018/11/02 Javascript
详解基于React.js和Node.js的SSR实现方案
2019/03/21 Javascript
vue-router 前端路由之路由传值的方式详解
2019/04/30 Javascript
图解NodeJS实现登录注册功能
2019/09/16 NodeJs
微信小程序自定义顶部组件customHeader的示例代码
2020/06/03 Javascript
详解Python中的strftime()方法的使用
2015/05/22 Python
Python简单实现子网掩码转换的方法
2016/04/13 Python
Python+Opencv识别两张相似图片
2020/03/23 Python
快速了解Python开发中的cookie及简单代码示例
2018/01/17 Python
Python模拟浏览器上传文件脚本的方法(Multipart/form-data格式)
2018/10/22 Python
python读取大文件越来越慢的原因与解决
2019/08/08 Python
自定义Django Form中choicefield下拉菜单选取数据库内容实例
2020/03/13 Python
Django 解决由save方法引发的错误
2020/05/21 Python
Python StringIO及BytesIO包使用方法解析
2020/06/15 Python
CSS3 linear-gradient线性渐变生成加号和减号的方法
2017/11/21 HTML / CSS
联想德国官网:Lenovo Germany
2018/07/04 全球购物
施工协议书范本
2014/04/22 职场文书
政风行风整改报告
2014/11/06 职场文书
彻底理解golang中什么是nil
2021/04/29 Golang
MySQL 可扩展设计的基本原则
2021/05/14 MySQL
基于Go语言构建RESTful API服务
2021/07/25 Golang