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和DOM Interfaces来处理HTML
Oct 09 Javascript
为你的网站增加亮点的9款jQuery插件推荐
May 03 Javascript
单元选择合并变色示例代码
May 26 Javascript
js操作模态窗口及父子窗口间相互传值示例
Jun 09 Javascript
JavaScript实现DIV层拖动及动态增加新层的方法
May 12 Javascript
javascript检查浏览器是否已经启用XX功能
Jul 10 Javascript
JS基于面向对象实现的拖拽库实例
Sep 24 Javascript
jQuery+css实现炫目的动态块漂移效果
Jan 28 Javascript
js实现分割上传大文件
Mar 09 Javascript
深入理解jquery中的each用法
Dec 14 Javascript
微信小程序 slider的简单实例
Apr 19 Javascript
微信小程序对图片进行canvas压缩的方法示例详解
Nov 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
CI(CodeIgniter)框架配置
2014/06/10 PHP
ThinkPHP实现跨模块调用操作方法概述
2014/06/20 PHP
php实现多维数组排序的方法示例
2017/03/23 PHP
thinkphp5.0自定义验证规则使用方法
2017/11/16 PHP
PHP isset()及empty()用法区别详解
2020/08/29 PHP
JS类库Bindows1.3中的内存释放方式分析
2007/03/08 Javascript
jquery validation插件表单验证的一个例子
2010/03/03 Javascript
js调用webservice中的方法实现思路及代码
2013/02/25 Javascript
js实现的GridView即表头固定表体有滚动条且可滚动
2014/02/19 Javascript
Javascript单元测试框架QUnitjs详细介绍
2014/05/08 Javascript
ie 7/8不支持trim的属性的解决方案
2014/05/23 Javascript
node.js中的fs.symlink方法使用说明
2014/12/15 Javascript
jQuery的animate函数实现图文切换动画效果
2015/05/03 Javascript
js实现仿百度汽车频道选择汽车图片展示实例
2015/05/06 Javascript
jQuery bt气泡实现悬停显示及移开隐藏功能的方法
2016/07/12 Javascript
Easyui ueditor 整合解决不能编辑的问题(推荐)
2017/06/25 Javascript
Angularjs的键盘事件的绑定
2017/07/27 Javascript
使用selenium抓取淘宝的商品信息实例
2018/02/06 Javascript
20个必会的JavaScript面试题(小结)
2019/07/02 Javascript
python异常和文件处理机制详解
2016/07/19 Python
Python脚本实现自动将数据库备份到 Dropbox
2017/02/06 Python
python numpy实现文件存取的示例代码
2019/05/26 Python
利用python开发app实战的方法
2019/07/09 Python
Python使用正则实现计算字符串算式
2019/12/29 Python
Python datetime模块使用方法小结
2020/06/18 Python
详解用Python调用百度地图正/逆地理编码API
2020/07/02 Python
Python3合并两个有序数组代码实例
2020/08/11 Python
python openCV自制绘画板
2020/10/27 Python
CSS3等相关属性制作分页导航实现代码
2012/12/24 HTML / CSS
英国索普公园票务和酒店套餐:Thorpe Breaks
2019/09/14 全球购物
秘书专业自荐信范文
2013/12/26 职场文书
高中化学教学反思
2014/01/13 职场文书
网吧消防安全制度
2014/01/28 职场文书
五星级酒店餐饮部总监的标准岗位职责
2014/02/17 职场文书
党的群众路线教育实践活动先进个人材料
2014/12/24 职场文书
2019最新校园运动会广播稿!
2019/06/28 职场文书