js获取隐藏元素宽高的方法

简介:

网上有一些js获取隐藏元素宽高的方法,但是可能会存在某些情况获取不了。

例如:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
    <title>test</title>
</head>
<body>
<div id="test" style="display:none">
     我有一壶酒,足以慰风尘。尽倾江海里,赠饮天下人。
</div>
<div id="test2" style="display:none">
     <div style="display:none">
          <div id="test2_child">
               我有一壶酒,足以慰风尘。尽倾江海里,赠饮天下人。
          </div>
     </div>
</div>
<div id="test3">
     <div>
          <div id="test3_child">
               我有一壶酒,足以慰风尘。尽倾江海里,赠饮天下人。
          </div>
     </div>
</div>
</div>
</body>
</html>
复制代码

test获取得了,但是test2_child是获取不到的。鉴于这种情况,于是自己写了一个方法解决。

解决思路:

1. 获取元素(拿宽高那个)所有隐藏的祖先元素直到body元素,包括自己。

2. 获取所有隐藏元素的style的display、visibility 属性,保存下来。

3. 设置所有隐藏元素为 visibility:hidden;display:block !important;(之所以要important是避免优先级不够)。

4. 获取元素(拿宽高那个)的宽高。

5. 恢复所有隐藏元素的style的display、visibility 属性。

6. 返回元素宽高值。

代码实现:

复制代码
function getSize(id){
     var width,
          height,
          elem = document.getElementById(id),
          noneNodes = [],
          nodeStyle = [];
     getNoneNode(elem); //获取多层display:none;的元素
     setNodeStyle();
     width = elem.clientWidth;
     height = elem.clientHeight;
     resumeNodeStyle();
    
     return {
          width : width,
          height : height
     }

     function getNoneNode(node){
          var display = getStyles(node).getPropertyValue('display'),
               tagName = node.nodeName.toLowerCase();
          if(display != 'none'
               && tagName != 'body'){
               getNoneNode(node.parentNode);
          } else {
               noneNodes.push(node);
               if(tagName != 'body')
                    getNoneNode(node.parentNode);
          }
     }
    
     //这方法才能获取最终是否有display属性设置,不能style.display。
     function getStyles(elem) {

          // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
          // IE throws on elements created in popups
          // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
          var view = elem.ownerDocument.defaultView;

          if (!view || !view.opener) {
               view = window;
          }
          return view.getComputedStyle(elem);
     };
    
    
     function setNodeStyle(){
          var i = 0;
          for(; i < noneNodes.length; i++){
               var visibility = noneNodes[i].style.visibility,
               display = noneNodes[i].style.display,
               style = noneNodes[i].getAttribute("style");
               //覆盖其他display样式
               noneNodes[i].setAttribute("style", "visibility:hidden;display:block !important;" + style);
               nodeStyle[i] = {
                    visibility :visibility,
                    display : display
               }
          }              
     }
    
     function resumeNodeStyle(){
          var i = 0;
          for(; i < noneNodes.length; i++){
               noneNodes[i].style.visibility = nodeStyle[i].visibility;
               noneNodes[i].style.display = nodeStyle[i].display;
          }    

     }
} 
复制代码

例子演示:

复制代码
var testSize = getSize('test');
console.log("test-> width:" + testSize.width + " height:" + testSize.height);

var test2ChildSize2 = getSize('test2_child');
console.log("test2Child2-> width:" + test2ChildSize2.width + " height:" + test2ChildSize2.height);

var test3ChildSize = getSize('test3_child');
console.log("test3_child-> width:" + test3ChildSize.width + " height:" + test3ChildSize.height);     
 
//打印值如下
test-> width:417 height:18
test2Child2-> width:417 height:18
test3_child-> width:417 height:18
复制代码

注意事项:

1. 打开显示所有隐藏祖先元素,然后获取元素的宽高值,可能在某些情况下获取值是不正确的。

PS:不过这个不用担心,真正出错时再hack方法就行。

2. 之所以要保存隐藏祖先元素display、visibility 属性,是为了后面可以设置回来,不影响其本身。

3. 另外getStyles方法是从jquery源码中摘取出来,这方法才能获取最终是否有display属性设置。

PS:不能从style.display获取。

 

本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。

本文地址 :http://www.cnblogs.com/lovesong/p/5506430.html




本文转自 海角在眼前 博客园博客,原文链接: http://www.cnblogs.com/lovesong/p/5506430.html  ,如需转载请自行联系原作者

相关文章
|
11天前
|
JavaScript 前端开发
JavaScript遍历数组和对象常用方法总结
以上代码展示了数组和对象的多种遍历方法。对于数组,使用了传统的 `for` 循环、`for...in` 和 ES6 的 `for...of` 进行遍历;对于对象,则通过 `for...in`、`Object.keys()`、`Object.values()` 和 `Object.entries()` 来获取键值对。`for...of` 循环适用于遍历具有迭代协议的数据结构,如数组、字符串等,而对象遍历则更多地依赖于 `Object` 方法来获取其属性集合。
JavaScript遍历数组和对象常用方法总结
|
6天前
|
JavaScript 前端开发
JavaScript基础知识-方法
文章通过示例代码讲解了JavaScript中如何给对象添加方法以及如何调用这些方法。
13 2
JavaScript基础知识-方法
|
6天前
|
JavaScript 前端开发
JavaScript基础知识-数组的常用方法
关于JavaScript基础知识-数组的常用方法。
9 1
JavaScript基础知识-数组的常用方法
|
11天前
|
JavaScript 算法 前端开发
JS算法必备之String常用操作方法
这篇文章详细介绍了JavaScript中字符串的基本操作,包括创建字符串、访问特定字符、字符串的拼接、位置查找、大小写转换、模式匹配、以及字符串的迭代和格式化等方法。
JS算法必备之String常用操作方法
|
11天前
|
JavaScript 算法 前端开发
JS算法必备之Array常用操作方法
这篇文章详细介绍了JavaScript中数组的创建、检测、转换、排序、操作方法以及迭代方法等,提供了数组操作的全面指南。
JS算法必备之Array常用操作方法
|
4天前
|
前端开发 JavaScript
前端ES5 | js —添加元素方法
前端ES5 | js —添加元素方法
|
11天前
|
JavaScript 前端开发 索引
JS中常用的数组迭代方法(filter,forEach,map,every,some,find,findIndex)
这段代码和说明介绍了JavaScript中数组的一些常用方法。函数接收三个参数:`item`(数组项的值)、`index`(项的位置,可选)和`array`(数组本身,可选)。示例展示了如何使用`filter()`过滤非空项、`forEach()`遍历数组、`map()`处理并返回新数组、`every()`检查所有元素是否满足条件、`some()`检查是否存在满足条件的元素、`find()`获取首个符合条件的元素值以及`findIndex()`获取其索引位置。这些方法都不会修改原数组。
JS中常用的数组迭代方法(filter,forEach,map,every,some,find,findIndex)
|
17天前
|
JavaScript
分别用jquery和js修改页面元素
分别用jquery和js修改页面元素
26 2
|
17天前
|
JavaScript 前端开发 开发者
JS 继承之谜:究竟有哪些神秘方法?Web 前端开发者必知的关键技巧待你揭开谜底!
【8月更文挑战第23天】JavaScript (JS) 是 Web 前端开发的关键语言,其中继承是面向对象编程的重要概念。本文探讨了 JS 中几种继承机制:原型链继承、构造函数继承及组合继承。原型链继承利用原型对象实现属性和方法的共享;构造函数继承通过在子类构造器内调用父类构造器实现私有属性的复制;组合继承结合两者优点,既支持属性共享又避免了属性被意外覆盖的风险。理解这些模式有助于开发者更高效地组织代码结构,提升程序质量。
27 1
|
21天前
|
JavaScript Linux
2022年超详细在CentOS 7上安装Node.js方法(源码安装)
这篇文章介绍了在CentOS 7系统上通过源码安装Node.js的详细步骤,包括从官网下载Node.js源码包、将安装包上传至虚拟机、解压安装包、删除压缩文件、编译安装Node.js、检查Node.js和npm版本,以及切换npm源到淘宝镜像以加速下载。此外,还提供了一个获取Linux下Node.js离线安装包的微信公众号搜索方式。