视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JavaScript中关于offsetWidth的bug问题以及解决方法
2020-11-27 20:22:38 责编:小OO
文档
这篇文章主要为大家详细介绍了JavaScript中offsetWidth的bug及解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

#p1 {
 width: 100px;
 height: 200px;
 background: red;
}

结果:100

#p1 {
 width: 100px;
 height: 200px;
 background: red;
 border: 2px solid black;
}

结果:104 (100 + 2 + 2)

#p1 {
 width: 100px;
 height: 200px;
 background: red;
 border: 2px solid black;
 padding: 20px;
}

结果:144 (100 + 2 + 2 + 20 + 20)

#p1 {
 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">
 #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,呢?

<!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>

    下载本文
    显示全文
    专题