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 相关文章推荐
根据选择不同的下拉值出现相对应的文本输入框
Aug 01 Javascript
javascript实现json页面分页实例代码
Feb 20 Javascript
node.js中的fs.statSync方法使用说明
Dec 16 Javascript
JavaScript使用指针操作实现约瑟夫问题实例
Apr 07 Javascript
常用的Javascript设计模式小结
Dec 09 Javascript
Node.js中防止错误导致的进程阻塞的方法
Aug 11 Javascript
jQuery EasyUI Draggable拖动组件
Mar 01 Javascript
Javascript中的async awai的用法
May 17 Javascript
浅谈webpack编译vue项目生成的代码探索
Dec 11 Javascript
分析javascript原型及原型链
Mar 18 Javascript
JavaScript捕捉事件和阻止冒泡事件实例分析
Aug 03 Javascript
Node4-5静态资源服务器实战以及优化压缩文件实例内容
Aug 29 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
PHP4实际应用经验篇(2)
2006/10/09 PHP
如何写php程序?
2006/12/08 PHP
Windows7下PHP开发环境安装配置图文方法
2010/05/20 PHP
解析PHP中的unset究竟会不会释放内存
2013/07/18 PHP
生成随机字符串和验证码的类的PHP实例
2013/12/24 PHP
ThinkPHP 3.2.2实现事务操作的方法
2017/05/05 PHP
php判断文件上传图片格式的实例详解
2017/09/30 PHP
用Laravel Sms实现laravel短信验证码的发送的实现
2018/11/29 PHP
js的闭包的一个示例说明
2008/11/18 Javascript
autoIMG 基于jquery的图片自适应插件代码
2011/03/12 Javascript
js怎么判断flash swf文件是否加载完毕
2014/08/14 Javascript
javascript实现连续赋值
2015/08/10 Javascript
jquery+CSS实现的多级竖向展开树形TRee菜单效果
2015/08/24 Javascript
Bootstrap中的fileinput 多图片上传及编辑功能
2016/09/05 Javascript
JS设计模式之访问者模式定义与用法分析
2018/02/05 Javascript
一次微信小程序内地图的使用实战记录
2019/09/09 Javascript
JavaScript 正则应用详解【模式、欲查、反向引用等】
2020/05/13 Javascript
封装Vue Element的table表格组件的示例详解
2020/08/19 Javascript
如何检测JavaScript中的死循环示例详解
2020/08/30 Javascript
Python将多个excel表格合并为一个表格
2021/02/22 Python
Python打包方法Pyinstaller的使用
2018/10/09 Python
对python以16进制打印字节数组的方法详解
2019/01/24 Python
美国潜水装备、水肺潜水和浮潜设备商店:Leisure Pro
2018/08/08 全球购物
解决方案设计综合面试题
2015/08/31 面试题
最热门的自我评价
2013/12/30 职场文书
护士检查书
2014/01/17 职场文书
运动会广播稿100字
2014/09/14 职场文书
工艺技术员岗位职责
2015/02/04 职场文书
2015年社区矫正工作总结
2015/04/21 职场文书
因家庭原因离职的辞职信范文
2015/05/12 职场文书
电影小兵张嘎观后感
2015/06/03 职场文书
新闻简讯格式及范文
2015/07/22 职场文书
民间借贷纠纷起诉书
2015/08/03 职场文书
新农村建设指导员工作总结
2015/08/13 职场文书
节水宣传标语口号
2015/12/26 职场文书
《雪地里的小画家》教学反思
2016/02/16 职场文书