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的load函数动态加载其它页面的内容的实现代码
Dec 14 Javascript
JS操作Cookie写入和读取实例代码
Oct 20 Javascript
纯css+js写的一个简单的tab标签页带样式
Jan 28 Javascript
javascript算法题:求任意一个1-9位不重复的N位数在该组合中的大小排列序号
Apr 01 Javascript
jquery插件NProgress.js制作网页加载进度条
Jun 05 Javascript
jquery自定义插件——window的实现【示例代码】
May 06 Javascript
VueJS全面解析
Nov 10 Javascript
微信小程序 特效菜单抽屉效果实例代码
Jan 11 Javascript
Angular中使用$watch监听object属性值的变化(详解)
Apr 24 Javascript
vue实现Excel文件的上传与下载功能的两种方式
Jun 28 Javascript
原生JS实现留言板功能
Feb 08 Javascript
canvas绘制折线路径动画实现
May 12 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/11/23 PHP
PHP 将逗号、空格、回车分隔的字符串转换为数组的函数
2012/06/07 PHP
thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法分析
2019/08/05 PHP
将jQuery应用于login页面的问题及解决
2009/10/17 Javascript
javaScript同意等待代码实现心得
2011/01/01 Javascript
修改好的jquery滚动字幕效果实现代码
2011/06/22 Javascript
jQuery学习笔记之 Ajax操作篇(三) - 过程处理
2014/06/23 Javascript
ff chrome和ie下全局动态定位的异同及全局高度的取法
2014/06/30 Javascript
json字符串之间的相互转换示例代码
2014/08/21 Javascript
Javascript中Array.prototype.map()详解
2014/10/22 Javascript
使用JavaScript刷新网页的方法
2015/06/04 Javascript
IE6-IE9使用JSON、table.innerHTML所引发的问题
2015/12/22 Javascript
浅谈JavaScript对象与继承
2016/07/10 Javascript
jQuery的 $.ajax防止重复提交的两种方法(推荐)
2016/10/14 Javascript
js移动端事件基础及常用事件库详解
2017/08/15 Javascript
React Native自定义控件底部抽屉菜单的示例
2018/02/08 Javascript
JS实现中英文混合文字溢出友好截取功能
2018/08/06 Javascript
JavaScript数值类型知识汇总
2019/11/17 Javascript
JavaScript修改注册表实例代码
2020/01/05 Javascript
详解React 条件渲染
2020/07/08 Javascript
linux服务器快速卸载安装node环境(简单上手)
2021/02/22 Javascript
Python遍历zip文件输出名称时出现乱码问题的解决方法
2015/04/08 Python
Python中subprocess模块用法实例详解
2015/05/20 Python
Python执行时间的计算方法小结
2017/03/17 Python
查看django版本的方法分享
2018/05/14 Python
pytorch 在网络中添加可训练参数,修改预训练权重文件的方法
2019/08/17 Python
什么是Smart Navigation?
2016/07/03 面试题
三个Unix的命令面试题
2015/04/12 面试题
教师一岗双责责任书
2014/04/16 职场文书
大学生实习鉴定评语
2014/04/25 职场文书
仲裁协议书
2014/09/26 职场文书
会计工作检讨书
2015/02/19 职场文书
2016教师校本研修心得体会
2016/01/08 职场文书
毕业生就业推荐表自我鉴定
2019/06/20 职场文书
JDBC连接的六步实例代码(与mysql连接)
2021/05/12 MySQL
python多次执行绘制条形图
2022/04/20 Python