您现在的位置: 365建站网 > 365学习 > JS/javascript中offsetWidth的用法和bug及处理方法

JS/javascript中offsetWidth的用法和bug及处理方法

文章来源:365jz.com     点击数:430    更新时间:2018-01-07 10:15   参与评论
offsetWidth是什么?

答:它可以获取物体宽度的数值

HTML部分


<div id="div1"></div>

<style>
#div1 { width:200px; height:200px; border:1px solid red; padding:2px; margin:2px; background:green;}
</style>


请看上面的html,你知道div1的offsetWidth是多少吗?

是不是200啊

哈哈,错了

div1的offsetWidth是206

为什么?

答:offsetWidth实际获取的是盒模型(width+border + padding)

200+2+4=206



扩展:那么offsetLeft和offsetTop呢

答: offsetLeft = left + marginLeft

     offsetTop = top +marginTop


示例:让div变窄

现象:onmouSEOver时,div变窄


原理:

oDiv.style.width = oDiv.offsetWidth - 1 + "px";  

offsetWidth表示对象的可见宽度。
比如:



1
2
3
4
5
#p1 {
width: 100px;
height: 200px;
background: red;
}
结果:100



1
2
3
4
5
6
#p1 {
width: 100px;
height: 200px;
background: red;
border: 2px solid black;
}
结果:104 (100 + 2 + 2)



1
2
3
4
5
6
7
#p1 {
width: 100px;
height: 200px;
background: red;
border: 2px solid black;
padding: 20px;
}
结果:144 (100 + 2 + 2 + 20 + 20)



1
2
3
4
5
6
#p1 {
width: 100px;
height: 200px;
background: red;
margin: 4px;
}
结果:100

**

所以,offsetWidth = width + padding + border, 和margin无关。

**
下面来看一个例子:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>offsetWidth</title>
<style type="text/CSS">
  #p1 {
   width: 500px;
   height: 200px;
   background: red;
  }
</style>
</head>
<body>
<p id="p1"></p>
<script type="text/JavaScript">
  var op = document.getElementById('p1');
  setInterval(function() {
   op.style.width = op.offsetWidth - 1 + 'px';
  }, 50);
</script>
</body>
</html>
现象:红色p逐渐变窄,直到消失,没问题!

如果给p加一个border,呢?



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>offsetWidth</title>
<style type="text/css">
  #p1 {
   width: 500px;
   height: 200px;
   background: red;
   border: 1px solid black;
  }
</style>
</head>
<body>
<p id="p1"></p>
<script type="text/javascript">
  var op = document.getElementById('p1');
  setInterval(function() {
   op.style.width = op.offsetWidth - 1 + 'px';
  }, 50);
</script>
</body>
</html>
现象:红色p不仅没有变窄,反而越来越宽…… 

*

原因也很简单:就是border的直接原因,因为offsetWidth是把border算进去的,定时器轮询的时候,第一次,width : 102 - 1 == 101 ,那么offsetWidth立马就变为103;第二次,width: 103 - 1 == 102, 那么offsetWidth立马就变为104;紧接着第三次,width: 104 - 1 == 103, offsetWidth就为104了……

倘若把 op.style.width = op.offsetWidth - 1 + ‘px'; 换成 -2,那么红色p就不动了,不会变宽也不会变窄,因为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">
  #p1 {
   width: 500px;
   height: 200px;
   background: red;
   border: 1px solid black;
  }
</style>
</head>
<body>
<p id="p1"></p>
<script type="text/javascript">

  var op = document.getElementById('p1');
  function getStyle(obj, attr) {
   if (obj.currentStyle) {//IE
    return obj.currentStyle[attr];
   } else {
    return getComputedStyle(obj, false)[attr];
   }
  }
  alert(getStyle(op, 'width'));//直接弹出 “500px”
</script>
</body>
</html>

有了上面的这个封装,我们就可以解决offsetWidth带来的困扰了

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>offsetWidth</title>
<style type="text/css">
  #p1 {
   width: 500px;
   height: 200px;
   background: red;
   border: 1px solid black;
  }
</style>
</head>
<body>
<p id="p1"></p>
<script type="text/javascript">
  var op = document.getElementById('p1');
  function getStyle(obj, attr) {
   if (obj.currentStyle) {//IE
    return obj.currentStyle[attr];
   } else {
    return getComputedStyle(obj, false)[attr];
   }
  }
  setInterval(function() {
   //parseInt是因为getStyle()返回的是‘px'带单位,要整数化
   op.style.width = parseInt(getStyle(op, 'width')) - 1 + 'px';
  }, 30);
</script>
</body>
</html>

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (430人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------