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 相关文章推荐
在textarea中显示html页面的javascript代码
Apr 20 Javascript
jquery控制listbox中项的移动并排序
Nov 12 Javascript
jquery操作复选框(checkbox)的12个小技巧总结
Feb 04 Javascript
jquery实现鼠标滑过小图时显示大图的方法
Jan 14 Javascript
jQuery操作表单常用控件方法小结
Mar 23 Javascript
Vue实现数字输入框中分割手机号码的示例
Oct 10 Javascript
实现高性能javascript的注意事项
May 27 Javascript
vue实现将数据存入vuex中以及从vuex中取出数据
Nov 08 Javascript
实现vuex与组件data之间的数据同步更新方式
Nov 12 Javascript
vue实现分页加载效果
Dec 24 Javascript
JS常见错误(Error)及处理方案详解
Jul 02 Javascript
js实现双色球效果
Aug 02 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 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)
2012/06/07 PHP
PHP字符串word末字符实现大小写互换的方法
2014/11/10 PHP
php单链表实现代码分享
2016/07/04 PHP
PHP实现将多个文件中的内容合并为新文件的方法示例
2017/06/10 PHP
Thinkphp 框架配置操作之配置加载与读取配置实例分析
2020/05/15 PHP
另类调用flash无须激活的方法
2006/12/27 Javascript
HTML中Select不用Disabled实现ReadOnly的效果
2008/04/07 Javascript
JQuery的ajax获取数据后的处理总结(html,xml,json)
2010/07/14 Javascript
javascript中日期转换成时间戳的小例子
2013/03/21 Javascript
javascript从右边截取指定字符串的三种实现方法
2013/11/29 Javascript
JavaScript实现的一个计算数字步数的算法分享
2014/12/06 Javascript
原生js实现数字字母混合验证码的简单实例
2015/12/10 Javascript
JS获取子、父、兄节点方法小结
2017/08/14 Javascript
JavaScript变量声明var,let.const及区别浅析
2018/04/23 Javascript
Vue在页面数据渲染完成之后的调用方法
2018/09/11 Javascript
JavaScript交换变量的常用方法小结【4种方法】
2020/05/07 Javascript
[01:06:39]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第三局
2016/03/02 DOTA
Python Socket编程入门教程
2014/07/11 Python
探究数组排序提升Python程序的循环的运行效率的原因
2015/04/01 Python
python合并已经存在的sheet数据到新sheet的方法
2018/12/11 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
python关闭占用端口方式
2019/12/17 Python
pytorch 实现模型不同层设置不同的学习率方式
2020/01/06 Python
python3+openCV 获取图片中文本区域的最小外接矩形实例
2020/06/02 Python
Python3 搭建Qt5 环境的方法示例
2020/07/16 Python
自荐信范文
2013/12/10 职场文书
医校毕业生自我鉴定
2014/01/25 职场文书
师说教学反思
2014/02/07 职场文书
学生周末长期请假条
2014/02/15 职场文书
红色旅游心得体会
2014/09/03 职场文书
四风对照检查材料思想汇报
2014/09/20 职场文书
先进班组材料范文
2014/12/25 职场文书
小学家长通知书评语
2014/12/31 职场文书
财务负责人岗位职责
2015/02/03 职场文书
黄石寨导游词
2015/02/05 职场文书
读后感怎么写?书写读后感的基本技巧!
2019/12/10 职场文书