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 相关文章推荐
解析arp病毒背后利用的Javascript技术附解密方法
Aug 06 Javascript
基于jquery实现的鼠标滑过按钮改变背景图片
Jul 15 Javascript
VBS通过WMI监视注册表变动的代码
Oct 27 Javascript
JavaScript中OnLoad几种使用方法
Dec 15 Javascript
JavaScript中实现依赖注入的思路分享
Jan 15 Javascript
javascript中使用new与不使用实例化对象的区别
Jun 22 Javascript
JQuery学习总结【二】
Dec 01 Javascript
vue.js移动端app之上拉加载以及下拉刷新实战
Sep 11 Javascript
Vue 2.0学习笔记之使用$refs访问Vue中的DOM
Dec 19 Javascript
angularjs 缓存的使用详解
Mar 19 Javascript
详解在HTTPS 项目中使用百度地图 API
Apr 26 Javascript
将Vue组件库更换为按需加载的方法步骤
May 06 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
收音机鉴频器对声音的影响和频偏分析
2021/03/02 无线电
php时间计算相关问题小结
2016/05/09 PHP
php的PDO事务处理机制实例分析
2017/02/16 PHP
php5.6.x到php7.0.x特性小结
2019/08/17 PHP
javascript EXCEL 操作类代码
2009/07/30 Javascript
JavaScript面向对象设计二 构造函数模式
2011/12/20 Javascript
js confirm()方法的使用方法实例
2013/07/13 Javascript
js数组操作常用方法
2014/05/08 Javascript
一些实用性较高的js方法
2016/04/19 Javascript
几句话带你理解JS中的this、闭包、原型链
2016/09/26 Javascript
禁用backspace网页回退功能的实现代码
2016/11/15 Javascript
bootstrap3 dialog 更强大、更灵活的模态框
2017/04/20 Javascript
JavaScript实现简单的星星评分效果
2017/05/18 Javascript
详解基于Angular4+ server render(服务端渲染)开发教程
2017/08/28 Javascript
react+ant design实现Table的增、删、改的示例代码
2018/12/27 Javascript
vuex刷新后数据丢失的解决方法
2020/10/18 Javascript
在Django中创建动态视图的教程
2015/07/15 Python
浅谈python可视化包Bokeh
2018/02/07 Python
如何使用python进行pdf文件分割
2019/11/11 Python
Python3并发写文件与Python对比
2019/11/20 Python
python中的itertools的使用详解
2020/01/13 Python
pytorch读取图像数据转成opencv格式实例
2020/06/02 Python
canvas小画板之平滑曲线的实现
2020/08/12 HTML / CSS
美国汽车轮胎和轮毂销售网站:Tire Rack
2018/01/11 全球购物
TUMI新加坡官网:国际领先的商旅箱包品牌
2019/01/12 全球购物
Boom手表官网:瑞典手表品牌,设计你的手表
2019/03/11 全球购物
Java平台和其他软件平台有什么不同
2015/06/05 面试题
中间件分为哪几类
2016/09/18 面试题
MIS软件工程师的面试题
2016/04/22 面试题
入党自我鉴定
2014/03/25 职场文书
党支部创先争优活动总结
2014/08/28 职场文书
2014年领导班子工作总结
2014/12/11 职场文书
行政复议答复书
2015/07/01 职场文书
酒店宣传语大全
2015/07/13 职场文书
Python访问Redis的详细操作
2021/06/26 Python
工厂无线对讲系统解决方案
2022/02/18 无线电