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 相关文章推荐
不错的JS中变量相关的细节分析
Aug 13 Javascript
jQuery中siblings()方法用法实例
Jan 08 Javascript
简介JavaScript中的getSeconds()方法的使用
Jun 10 Javascript
js实现的简洁网页滑动tab菜单效果代码
Aug 24 Javascript
jQuery实现自定义右键菜单的树状菜单效果
Sep 02 Javascript
AngularJS封装$http.post()实例详解
May 06 Javascript
浅析vue-router jquery和params传参(接收参数)$router $route的区别
Aug 03 jQuery
Vue 配合eiement动态路由,权限验证的方法
Sep 26 Javascript
vue进入页面时不在顶部,检测滚动返回顶部按钮问题及解决方法
Oct 30 Javascript
vue动态路由:路由参数改变,视图不更新问题的解决
Nov 05 Javascript
卸载vue2.0并升级vue_cli3.0的实例讲解
Feb 16 Javascript
Promise静态四兄弟实现示例详解
Jul 07 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
海贼王动画变成“真人”后,凯多神还原,雷利太帅了!
2020/04/09 日漫
php中文本数据翻页(留言本翻页)
2006/10/09 PHP
php zend解密软件绿色版测试可用
2008/04/14 PHP
实例讲解php数据访问
2016/05/09 PHP
php微信高级接口群发 多客服
2016/06/23 PHP
PHP房贷计算器实例代码,等额本息,等额本金
2017/04/01 PHP
PHP使用标准库spl实现的观察者模式示例
2018/08/04 PHP
PHP多进程简单实例小结
2019/11/09 PHP
JQuery对id中含有特殊字符的转义处理示例
2013/09/06 Javascript
jQuery 获取兄弟元素的几种不错方法
2014/05/23 Javascript
jQuery实现复选框成对选择及对应取消的方法
2015/03/03 Javascript
js实现滚动条滚动到页面底部继续加载
2015/12/19 Javascript
AngularJS中实现动画效果的方法
2016/07/28 Javascript
jQuery Validate验证框架详解(推荐)
2016/12/17 Javascript
JS作用域深度解析
2016/12/29 Javascript
Vue2.0 vue-source jsonp 跨域请求
2017/08/04 Javascript
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
Vue2.0 axios前后端登陆拦截器(实例讲解)
2017/10/27 Javascript
Angular4学习教程之DOM属性绑定详解
2018/01/04 Javascript
Node.Js中实现端口重用原理详解
2018/05/03 Javascript
13 个npm 快速开发技巧(推荐)
2019/07/04 Javascript
Python中for循环详解
2014/01/17 Python
浅析Python中元祖、列表和字典的区别
2016/08/17 Python
PyQt5每天必学之组合框
2018/04/20 Python
基于pycharm导入模块显示不存在的解决方法
2018/10/13 Python
scrapy-redis源码分析之发送POST请求详解
2019/05/15 Python
Python企业编码生成系统之系统主要函数设计详解
2019/07/26 Python
python+Selenium自动化测试——输入,点击操作
2020/03/06 Python
python使用matplotlib绘制折线图的示例代码
2020/09/22 Python
高中的自我鉴定
2013/12/16 职场文书
自动化职业生涯规划书范文
2014/01/03 职场文书
质量提升方案
2014/06/16 职场文书
交通事故委托书范本(2篇)
2014/09/21 职场文书
建国大业观后感600字
2015/06/01 职场文书
2016继续教育研修日志
2015/11/13 职场文书
教学工作总结范文5篇
2019/08/19 职场文书