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


Posted in Javascript onMay 19, 2016

网上有一些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获取。

以上这篇js获取隐藏元素宽高的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
半角全角相互转换的js函数
Oct 16 Javascript
如何设置iframe高度自适应在跨域情况下的可用方法
Sep 06 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
Mar 28 Javascript
jquery选择器需要注意的问题
Nov 26 Javascript
javascript中利用柯里化函数实现bind方法
Apr 29 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
Jul 22 Javascript
jQuery实现带延时功能的水平多级菜单效果【附demo源码下载】
Sep 21 Javascript
JS添加或修改控件的样式(Class)实现方法
Oct 15 Javascript
vue实现登录后页面跳转到之前页面
Jan 07 Javascript
详细分析Node.js 模块系统
Jun 28 Javascript
vue中实现点击空白区域关闭弹窗的两种方法
Dec 30 Vue.js
nestjs中异常过滤器Exceptionfilter的具体使用
Feb 07 Javascript
jquery实现无刷新验证码的简单实例
May 19 #Javascript
AngularJs解决跨域问题案例详解(简单方法)
May 19 #Javascript
JavaScript:Array类型全面解析
May 19 #Javascript
JavaScript:Date类型全面解析
May 19 #Javascript
javascript中对Date类型的常用操作小结
May 19 #Javascript
JS Attribute属性操作详解
May 19 #Javascript
jQuery点击输入框显示验证码图片
May 19 #Javascript
You might like
PHP常用的文件操作函数经典收藏
2013/04/02 PHP
CentOS下PHP安装Oracle扩展
2015/02/15 PHP
php简单定时执行任务的实现方法
2015/02/23 PHP
总结PHP代码规范、流程规范、git规范
2018/06/18 PHP
Javascript之旅 对象的原型链之由来
2010/08/25 Javascript
javascript 延迟加载技术(lazyload)简单实现
2011/01/17 Javascript
js判断字符是否是汉字的两种方法小结
2014/01/03 Javascript
javascript中setTimeout使用指南
2015/07/26 Javascript
学习JavaScript设计模式之责任链模式
2016/01/18 Javascript
js 文字超出长度用省略号代替,鼠标悬停并以悬浮框显示实例
2016/12/06 Javascript
layer实现弹窗提交信息
2016/12/12 Javascript
JSONP基础知识详解
2017/03/19 Javascript
老生常谈jacascript DOM节点获取
2017/04/17 Javascript
JS鼠标滚动分页效果示例
2017/07/05 Javascript
JS自定义滚动条效果简单实现代码
2020/10/27 Javascript
ReactNative短信验证码倒计时控件的实现代码
2017/07/20 Javascript
pygame学习笔记(6):完成一个简单的游戏
2015/04/15 Python
浅析python递归函数和河内塔问题
2017/04/18 Python
numpy.ndarray 交换多维数组(矩阵)的行/列方法
2018/08/02 Python
[原创]Python入门教程4. 元组基本操作
2018/10/31 Python
关于Pytorch MaxUnpool2d中size操作方式
2020/01/03 Python
解决pycharm中的run和debug失效无法点击运行
2020/06/09 Python
用Python爬取LOL所有的英雄信息以及英雄皮肤的示例代码
2020/07/13 Python
使用Python操作MySQL的小技巧
2020/09/10 Python
Deichmann英国:德国鞋类零售商
2021/01/30 全球购物
财务会计专业毕业生自荐信
2013/10/02 职场文书
留学推荐信写作指南
2014/01/25 职场文书
优秀教师获奖感言
2014/01/31 职场文书
安全生产计划书
2014/05/04 职场文书
大学英语专业求职信
2014/06/21 职场文书
2015廉洁自律个人总结
2015/02/14 职场文书
安全学习心得体会范文
2016/01/18 职场文书
高中语文教材(文学文化常识大全一)
2019/08/13 职场文书
python使用PySimpleGUI设置进度条及控件使用
2021/06/10 Python
详解NodeJS模块化
2021/06/15 NodeJs
Python实现双向链表基本操作
2022/05/25 Python