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入门·动态的时钟,显示完整的一些方法,新年倒计时
Oct 01 Javascript
in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案
Jul 26 Javascript
JS动态添加与删除select中的Option对象(示例代码)
Dec 20 Javascript
浅谈jquery设置和获得checkbox选中的问题
Aug 19 Javascript
Bootstrap CDN和本地化环境搭建
Oct 26 Javascript
jQuery插件FusionCharts绘制的3D饼状图效果实例【附demo源码下载】
Mar 03 Javascript
Angular X中使用ngrx的方法详解(附源码)
Jul 10 Javascript
vue2.0 elementUI制作面包屑导航栏
Feb 22 Javascript
JS实现点星星消除小游戏
Mar 24 Javascript
vue中用 async/await 来处理异步操作
Jul 18 Javascript
基于Vue中的父子传值问题解决
Jul 27 Javascript
Vue深入理解插槽slot的使用
Aug 05 Vue.js
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实现paypal 授权登录
2015/05/28 PHP
PHP实现的分页类定义与用法示例
2017/07/05 PHP
jQuery cdn使用介绍
2013/05/08 Javascript
javascript full screen 全屏显示页面元素的方法
2013/09/27 Javascript
Jquery 复选框取值兼容FF和IE8(测试有效)
2013/10/29 Javascript
jQuery遍历对象、数组、集合实例
2014/11/08 Javascript
JQuery插入DOM节点的方法
2015/06/11 Javascript
AngularJS整合Springmvc、Spring、Mybatis搭建开发环境
2016/02/25 Javascript
详解JS几种变量交换方式以及性能分析对比
2016/11/25 Javascript
从零学习node.js之搭建http服务器(二)
2017/02/21 Javascript
利用JS如何计算字符串所占字节数示例代码
2017/09/13 Javascript
js定时器实现倒计时效果
2017/11/05 Javascript
JS实现的合并多个数组去重算法示例
2018/04/11 Javascript
详解AngularJS 过滤器的使用
2018/06/02 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
2020/05/11 Javascript
解决vue侦听器watch,调用this时出现undefined的问题
2020/10/30 Javascript
零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers
2014/11/05 Python
python机器学习之神经网络(三)
2017/12/20 Python
python3+selenium实现qq邮箱登陆并发送邮件功能
2019/01/23 Python
python使用adbapi实现MySQL数据库的异步存储
2019/03/19 Python
Python3使用TCP编写一个简易的文件下载器功能
2019/05/08 Python
Jupyter Notebook打开任意文件夹操作
2020/04/14 Python
python opencv实现图像配准与比较
2021/02/09 Python
canvas使用注意点总结
2013/07/19 HTML / CSS
精致的手工皮鞋:Shoe Embassy
2019/11/08 全球购物
利用异或运算实现两个无符号数的加法运算
2013/12/20 面试题
夜大自我鉴定
2013/10/31 职场文书
数学教学随笔感言
2014/02/17 职场文书
我有一个梦想演讲稿
2014/05/05 职场文书
水利水电建筑施工应届生求职信
2014/07/04 职场文书
小学三好学生事迹材料
2014/08/15 职场文书
高中生国庆节演讲稿范文2014
2014/09/21 职场文书
工作态度检讨书范文
2015/05/06 职场文书
证婚人致辞精选
2015/07/28 职场文书
mongoDB数据库索引快速入门指南
2022/03/23 MongoDB
Tomcat 与 maven 的安装与使用教程
2022/06/16 Servers